fix: view group followup (#9162)
This PR fixes all followup that @Bonapara add on Discord. - [x] When no group by is set, clicking on group by should open the "field selection" menu - [x] When closed, chevron should be "chevron-right" instead of "chevron-up" - [x] Sort : Add ability to switch from alphabetical to manual when moving a option in sort alphabetical - [x] Add subtext for group by and sort - [x] Group by menu display bug - [x] Changing the sort should not close the menu - [x] Group by Activation -> shows empty state + is slow - [x] Switching from Kanban view Settings to Table Options menu displays an empty menu - [x] Unnecessary spacing under groups - [x] When no "select" are set on an object, redirect the user directly to the new Select field page - [x] Sort : Default should be manual - [x] Hidding "no value" displays all options and remove the "hide empty group" toggle - [x] Hide Empty group option disappeared - [x] Group by should not be persisted on "Locked/Main view" (**For now we just disable the group by on main view**) - [x] Hide Empty group should not be activated by default on Opportunities Kanban view - [ ] Animate the group opening/closing (**We'll be done later**) Performance improvement: https://github.com/user-attachments/assets/fd2acf66-0e56-45d0-8b2f-99c62e57d6f7 https://github.com/user-attachments/assets/80f1a2e1-9f77-4923-b85d-acb9cad96886 Also fix #9036 --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -71,6 +71,7 @@ export const DropdownMenuItemsContainer = ({
|
||||
<ScrollWrapper
|
||||
contextProviderName="dropdownMenuItemsContainer"
|
||||
componentInstanceId={`scroll-wrapper-dropdown-menu-${id}`}
|
||||
heightMode="fit-content"
|
||||
>
|
||||
<StyledDropdownMenuItemsExternalContainer
|
||||
hasMaxHeight={hasMaxHeight}
|
||||
|
||||
@ -6,7 +6,7 @@ import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previo
|
||||
export const useSetActiveDropdownFocusIdAndMemorizePrevious = () => {
|
||||
const setActiveDropdownFocusIdAndMemorizePrevious = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(dropdownId: string) => {
|
||||
(dropdownId: string | null) => {
|
||||
const focusedDropdownId = snapshot
|
||||
.getLoadable(activeDropdownFocusIdState)
|
||||
.getValue();
|
||||
|
||||
@ -142,7 +142,9 @@ export const ConfirmationModal = ({
|
||||
</Section>
|
||||
)}
|
||||
<StyledCenteredButton
|
||||
onClick={() => setIsOpen(false)}
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
}}
|
||||
variant="secondary"
|
||||
title="Cancel"
|
||||
fullWidth
|
||||
|
||||
@ -15,9 +15,21 @@ import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/stat
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import 'overlayscrollbars/overlayscrollbars.css';
|
||||
|
||||
const StyledScrollWrapper = styled.div<{ scrollHide?: boolean }>`
|
||||
type HeightMode = 'full' | 'fit-content';
|
||||
|
||||
const StyledScrollWrapper = styled.div<{
|
||||
scrollHide?: boolean;
|
||||
heightMode: HeightMode;
|
||||
}>`
|
||||
display: flex;
|
||||
height: 100%;
|
||||
height: ${({ heightMode }) => {
|
||||
switch (heightMode) {
|
||||
case 'full':
|
||||
return '100%';
|
||||
case 'fit-content':
|
||||
return 'fit-content';
|
||||
}
|
||||
}};
|
||||
width: 100%;
|
||||
|
||||
.os-scrollbar-handle {
|
||||
@ -33,6 +45,7 @@ const StyledInnerContainer = styled.div`
|
||||
export type ScrollWrapperProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
heightMode?: HeightMode;
|
||||
defaultEnableXScroll?: boolean;
|
||||
defaultEnableYScroll?: boolean;
|
||||
contextProviderName: ContextProviderName;
|
||||
@ -44,6 +57,7 @@ export const ScrollWrapper = ({
|
||||
componentInstanceId,
|
||||
children,
|
||||
className,
|
||||
heightMode = 'full',
|
||||
defaultEnableXScroll = true,
|
||||
defaultEnableYScroll = true,
|
||||
contextProviderName,
|
||||
@ -164,6 +178,7 @@ export const ScrollWrapper = ({
|
||||
ref={scrollableRef}
|
||||
className={className}
|
||||
scrollHide={scrollHide}
|
||||
heightMode={heightMode}
|
||||
>
|
||||
<StyledInnerContainer>{children}</StyledInnerContainer>
|
||||
</StyledScrollWrapper>
|
||||
|
||||
@ -2,7 +2,14 @@ import { ComponentFamilyStateKeyV2 } from '@/ui/utilities/state/component-state/
|
||||
import { ComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateV2';
|
||||
import { ComponentInstanceStateContext } from '@/ui/utilities/state/component-state/types/ComponentInstanceStateContext';
|
||||
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||
import { AtomEffect, atomFamily, SerializableParam } from 'recoil';
|
||||
import {
|
||||
AtomEffect,
|
||||
atomFamily,
|
||||
Loadable,
|
||||
RecoilValue,
|
||||
SerializableParam,
|
||||
WrappedValue,
|
||||
} from 'recoil';
|
||||
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
@ -11,7 +18,16 @@ type CreateComponentFamilyStateArgs<
|
||||
FamilyKey extends SerializableParam,
|
||||
> = {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
defaultValue:
|
||||
| ValueType
|
||||
| ((
|
||||
param: ComponentFamilyStateKeyV2<FamilyKey>,
|
||||
) =>
|
||||
| ValueType
|
||||
| RecoilValue<ValueType>
|
||||
| Promise<ValueType>
|
||||
| Loadable<ValueType>
|
||||
| WrappedValue<ValueType>);
|
||||
componentInstanceContext: ComponentInstanceStateContext<any> | null;
|
||||
effects?:
|
||||
| AtomEffect<ValueType>[]
|
||||
|
||||
Reference in New Issue
Block a user