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:
Jérémy M
2025-01-02 16:40:28 +01:00
committed by GitHub
parent 866c29e9ee
commit 0f1458cbe9
49 changed files with 676 additions and 320 deletions

View File

@ -71,6 +71,7 @@ export const DropdownMenuItemsContainer = ({
<ScrollWrapper
contextProviderName="dropdownMenuItemsContainer"
componentInstanceId={`scroll-wrapper-dropdown-menu-${id}`}
heightMode="fit-content"
>
<StyledDropdownMenuItemsExternalContainer
hasMaxHeight={hasMaxHeight}

View File

@ -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();

View File

@ -142,7 +142,9 @@ export const ConfirmationModal = ({
</Section>
)}
<StyledCenteredButton
onClick={() => setIsOpen(false)}
onClick={() => {
setIsOpen(false);
}}
variant="secondary"
title="Cancel"
fullWidth

View File

@ -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>

View File

@ -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>[]