diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx index 3e6fe5c41..d19e77d12 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/DeleteRecordsActionEffect.tsx @@ -37,8 +37,8 @@ export const DeleteRecordsActionEffect = ({ objectNameSingular: objectMetadataItem.nameSingular, }); - const favorites = useFavorites(); - const deleteFavorite = useDeleteFavorite(); + const { sortedFavorites: favorites } = useFavorites(); + const { deleteFavorite } = useDeleteFavorite(); const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2( contextStoreNumberOfSelectedRecordsComponentState, diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx index c595e7d6f..714f06c86 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/components/ManageFavoritesActionEffect.tsx @@ -23,11 +23,11 @@ export const ManageFavoritesActionEffect = ({ contextStoreTargetedRecordsRuleComponentState, ); - const favorites = useFavorites(); + const { sortedFavorites: favorites } = useFavorites(); - const createFavorite = useCreateFavorite(); + const { createFavorite } = useCreateFavorite(); - const deleteFavorite = useDeleteFavorite(); + const { deleteFavorite } = useDeleteFavorite(); const selectedRecordId = contextStoreTargetedRecordsRule.mode === 'selection' diff --git a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx index d33dfdbd5..46c64acbd 100644 --- a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx +++ b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx @@ -61,9 +61,9 @@ export const CurrentWorkspaceMemberFavorites = ({ const selectedFavoriteIndex = folder.favorites.findIndex((favorite) => isLocationMatchingFavorite(currentPath, currentViewPath, favorite), ); - const handleReorderFavorite = useReorderFavorite(); + const { handleReorderFavorite } = useReorderFavorite(); - const deleteFavorite = useDeleteFavorite(); + const { deleteFavorite } = useDeleteFavorite(); const favoriteFolderContentLength = folder.favorites.length; @@ -154,6 +154,7 @@ export const CurrentWorkspaceMemberFavorites = ({ key={favorite.id} draggableId={favorite.id} index={index} + isInsideScrollableContainer itemComponent={ { const currentViewPath = useLocation().pathname + useLocation().search; const theme = useTheme(); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - const favorites = useFavorites(); - const deleteFavorite = useDeleteFavorite(); - const handleReorderFavorite = useReorderFavorite(); + const { sortedFavorites: favorites } = useFavorites(); + const { deleteFavorite } = useDeleteFavorite(); + const { handleReorderFavorite } = useReorderFavorite(); const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] = useRecoilState(isFavoriteFolderCreatingState); @@ -50,24 +50,25 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => { const toggleNewFolder = () => { setIsFavoriteFolderCreating((current) => !current); }; + const shouldDisplayFavoritesWithFeatureFlagEnabled = true; + + //todo: remove this logic once feature flag gating is removed + const shouldDisplayFavoritesWithoutFeatureFlagEnabled = + favorites.length > 0 || isFavoriteFolderCreating; + + const shouldDisplayFavorites = isFavoriteFolderEnabled + ? shouldDisplayFavoritesWithFeatureFlagEnabled + : shouldDisplayFavoritesWithoutFeatureFlagEnabled; if (loading && isDefined(currentWorkspaceMember)) { return ; } - const currentWorkspaceMemberFavorites = favorites.filter( - (favorite) => favorite.workspaceMemberId === currentWorkspaceMember?.id, - ); - - const orphanFavorites = currentWorkspaceMemberFavorites.filter( + const orphanFavorites = favorites.filter( (favorite) => !favorite.favoriteFolderId, ); - if ( - (!currentWorkspaceMemberFavorites || - currentWorkspaceMemberFavorites.length === 0) && - !isFavoriteFolderCreating - ) { + if (!shouldDisplayFavorites) { return null; } @@ -104,6 +105,7 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => { key={favorite.id} draggableId={favorite.id} index={index} + isInsideScrollableContainer={true} itemComponent={ diff --git a/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx b/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx index 48179ad22..6810eb491 100644 --- a/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx +++ b/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx @@ -18,8 +18,8 @@ export const FavoriteFolders = ({ }: FavoriteFoldersProps) => { const [newFolderName, setNewFolderName] = useState(''); - const favoritesByFolder = useFavoritesByFolder(); - const createFavoriteFolder = useCreateFavoriteFolder(); + const { favoritesByFolder } = useFavoritesByFolder(); + const { createNewFavoriteFolder } = useCreateFavoriteFolder(); const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] = useRecoilState(isFavoriteFolderCreatingState); @@ -33,12 +33,12 @@ export const FavoriteFolders = ({ setIsFavoriteFolderCreating(false); setNewFolderName(''); - await createFavoriteFolder(value); + await createNewFavoriteFolder(value); return true; }; const handleClickOutside = async ( - event: MouseEvent | TouchEvent, + _event: MouseEvent | TouchEvent, value: string, ) => { if (!value) { @@ -48,7 +48,7 @@ export const FavoriteFolders = ({ setIsFavoriteFolderCreating(false); setNewFolderName(''); - await createFavoriteFolder(value); + await createNewFavoriteFolder(value); }; const handleCancelFavoriteFolderCreation = () => { diff --git a/packages/twenty-front/src/modules/ui/layout/page/components/PageFavoriteButton.tsx b/packages/twenty-front/src/modules/favorites/components/PageFavoriteButton.tsx similarity index 100% rename from packages/twenty-front/src/modules/ui/layout/page/components/PageFavoriteButton.tsx rename to packages/twenty-front/src/modules/favorites/components/PageFavoriteButton.tsx diff --git a/packages/twenty-front/src/modules/ui/layout/page/components/PageFavoriteFolderDropdown.tsx b/packages/twenty-front/src/modules/favorites/components/PageFavoriteFolderDropdown.tsx similarity index 80% rename from packages/twenty-front/src/modules/ui/layout/page/components/PageFavoriteFolderDropdown.tsx rename to packages/twenty-front/src/modules/favorites/components/PageFavoriteFolderDropdown.tsx index ee0cfb356..ba7324c9c 100644 --- a/packages/twenty-front/src/modules/ui/layout/page/components/PageFavoriteFolderDropdown.tsx +++ b/packages/twenty-front/src/modules/favorites/components/PageFavoriteFolderDropdown.tsx @@ -1,11 +1,11 @@ +import { PageFavoriteButton } from '@/favorites/components/PageFavoriteButton'; import { FavoriteFolderPicker } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPicker'; import { FavoriteFolderPickerEffect } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect'; -import { FavoriteFolderPickerScope } from '@/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope'; +import { FavoriteFolderPickerComponentInstanceContext } from '@/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; -import { PageFavoriteButton } from '@/ui/layout/page/components/PageFavoriteButton'; type PageFavoriteFoldersDropdownProps = { dropdownId: string; @@ -23,7 +23,9 @@ export const PageFavoriteFoldersDropdown = ({ const { closeDropdown } = useDropdown(dropdownId); return ( - + - + ); }; diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderMenuItemMultiSelect.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderMenuItemMultiSelect.tsx deleted file mode 100644 index ae0ee7204..000000000 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderMenuItemMultiSelect.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import styled from '@emotion/styled'; -import { MenuItemMultiSelect } from '@ui/navigation/menu-item/components/MenuItemMultiSelect'; - -const StyledNoGapMenuItem = styled(MenuItemMultiSelect)` - & > div { - gap: 0; - } -`; - -export const FavoriteFolderMenuItemMultiSelect = StyledNoGapMenuItem; diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx index d4193b405..456d36d95 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx @@ -36,7 +36,7 @@ export const FavoriteFolderPicker = ({ FavoriteFolderPickerInstanceContext, ); - const { getFoldersByIds, toggleFolderSelection } = useFavoriteFolderPicker({ + const { favoriteFolders, toggleFolderSelection } = useFavoriteFolderPicker({ record, objectNameSingular, }); @@ -45,8 +45,7 @@ export const FavoriteFolderPicker = ({ favoriteFolderSearchFilterComponentState, ); - const folders = getFoldersByIds(); - const filteredFolders = folders.filter((folder) => + const filteredFolders = favoriteFolders.filter((folder) => folder.name .toLowerCase() .includes(favoriteFoldersSearchFilter.toLowerCase()), @@ -94,7 +93,7 @@ export const FavoriteFolderPicker = ({ diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx index 30f10c3f4..28263ed5f 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx @@ -30,7 +30,7 @@ export const FavoriteFolderPickerEffect = ({ const { favoriteFolders } = usePrefetchedFavoritesFoldersData(); - const favorites = useFavorites(); + const { sortedFavorites: favorites } = useFavorites(); const setCheckedState = useSetRecoilComponentStateV2( favoriteFolderPickerCheckedComponentState, ); diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx index 98d92f4b2..e97a8d9d5 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx @@ -14,10 +14,6 @@ const StyledFooter = styled.div` border-top: 1px solid ${({ theme }) => theme.border.color.light}; `; -const StyledIconPlus = styled(IconPlus)` - padding-left: ${({ theme }) => theme.spacing(1)}; -`; - export const FavoriteFolderPickerFooter = () => { const [, setIsFavoriteFolderCreating] = useRecoilState( isFavoriteFolderCreatingState, @@ -35,7 +31,7 @@ export const FavoriteFolderPickerFooter = () => { closeDropdown(); }} text="Add folder" - LeftIcon={() => } + LeftIcon={() => } /> diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerList.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerList.tsx index fc29741c6..ba3b59f8b 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerList.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerList.tsx @@ -4,8 +4,7 @@ import { FavoriteFolder } from '@/favorites/types/FavoriteFolder'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; import styled from '@emotion/styled'; -import { MenuItem } from 'twenty-ui'; -import { FavoriteFolderMenuItemMultiSelect } from './FavoriteFolderMenuItemMultiSelect'; +import { MenuItem, MenuItemMultiSelect } from 'twenty-ui'; const StyledItemsContainer = styled.div` width: 100%; @@ -30,6 +29,7 @@ export const FavoriteFolderPickerList = ({ const [favoriteFoldersSearchFilter] = useRecoilComponentStateV2( favoriteFolderSearchFilterComponentState, ); + const [favoriteFolderPickerChecked] = useRecoilComponentStateV2( favoriteFolderPickerCheckedComponentState, ); @@ -47,7 +47,7 @@ export const FavoriteFolderPickerList = ({ return ( {showNoFolderOption && ( - toggleFolderSelection(NO_FOLDER_ID)} selected={favoriteFolderPickerChecked.includes(NO_FOLDER_ID)} @@ -60,7 +60,7 @@ export const FavoriteFolderPickerList = ({ )} {filteredFolders.length > 0 ? filteredFolders.map((folder) => ( - toggleFolderSelection(folder.id)} selected={favoriteFolderPickerChecked.includes(folder.id)} diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts index 6f4d35c8b..107854221 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts @@ -1,6 +1,5 @@ -import { favoriteFolderIdsPickerComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderIdPickerComponentState'; import { favoriteFolderPickerCheckedComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerCheckedComponentState'; -import { favoriteFolderPickerComponentFamilyState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerComponentFamilyState'; +import { favoriteFoldersComponentSelector } from '@/favorites/favorite-folder-picker/states/selectors/favoriteFoldersComponentSelector'; import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite'; import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; @@ -8,7 +7,7 @@ import { useFavorites } from '@/favorites/hooks/useFavorites'; import { FavoriteFolder } from '@/favorites/types/FavoriteFolder'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; -import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; +import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-ui'; @@ -17,46 +16,26 @@ type useFavoriteFolderPickerProps = { objectNameSingular: string; }; -type FolderOperations = { - getFoldersByIds: () => FavoriteFolder[]; +type useFavoriteFolderPickerReturnType = { + favoriteFolders: FavoriteFolder[]; toggleFolderSelection: (folderId: string) => Promise; }; export const useFavoriteFolderPicker = ({ record, objectNameSingular, -}: useFavoriteFolderPickerProps): FolderOperations => { - const [favoriteFolderIdsPicker] = useRecoilComponentStateV2( - favoriteFolderIdsPickerComponentState, - ); - +}: useFavoriteFolderPickerProps): useFavoriteFolderPickerReturnType => { const favoriteFoldersMultiSelectCheckedState = useRecoilComponentCallbackStateV2( favoriteFolderPickerCheckedComponentState, ); - const favoriteFolderPickerFamilyState = useRecoilComponentCallbackStateV2( - favoriteFolderPickerComponentFamilyState, - ); + const { sortedFavorites: favorites } = useFavorites(); + const { createFavorite } = useCreateFavorite(); + const { deleteFavorite } = useDeleteFavorite(); - const favorites = useFavorites(); - const createFavorite = useCreateFavorite(); - const deleteFavorite = useDeleteFavorite(); - - const getFoldersByIds = useRecoilCallback( - ({ snapshot }) => - (): FavoriteFolder[] => { - return favoriteFolderIdsPicker - .map((folderId) => { - const folderValue = snapshot - .getLoadable(favoriteFolderPickerFamilyState(folderId)) - .getValue(); - - return folderValue; - }) - .filter((folder): folder is FavoriteFolder => isDefined(folder)); - }, - [favoriteFolderIdsPicker, favoriteFolderPickerFamilyState], + const favoriteFolders = useRecoilComponentValueV2( + favoriteFoldersComponentSelector, ); const toggleFolderSelection = useRecoilCallback( @@ -123,7 +102,7 @@ export const useFavoriteFolderPicker = ({ ); return { - getFoldersByIds, + favoriteFolders, toggleFolderSelection, }; }; diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope.tsx index dc72ae681..107c19bee 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope.tsx @@ -1,15 +1,15 @@ import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext'; import { ReactNode } from 'react'; -type FavoriteFolderPickerScopeProps = { +type FavoriteFolderPickerComponentInstanceContextProps = { children: ReactNode; favoriteFoldersScopeId: string; }; -export const FavoriteFolderPickerScope = ({ +export const FavoriteFolderPickerComponentInstanceContext = ({ children, favoriteFoldersScopeId, -}: FavoriteFolderPickerScopeProps) => { +}: FavoriteFolderPickerComponentInstanceContextProps) => { return ( ({ - key: 'favoriteFoldersLoadingComponentState', - defaultValue: false, - componentInstanceContext: FavoriteFolderPickerInstanceContext, - }); diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/states/selectors/favoriteFoldersComponentSelector.ts b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/states/selectors/favoriteFoldersComponentSelector.ts new file mode 100644 index 000000000..8158c742a --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/states/selectors/favoriteFoldersComponentSelector.ts @@ -0,0 +1,31 @@ +import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext'; +import { favoriteFolderIdsPickerComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderIdPickerComponentState'; +import { favoriteFolderPickerComponentFamilyState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerComponentFamilyState'; +import { FavoriteFolder } from '@/favorites/types/FavoriteFolder'; +import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2'; +import { isDefined } from 'twenty-ui'; + +export const favoriteFoldersComponentSelector = createComponentSelectorV2< + FavoriteFolder[] +>({ + key: 'favoriteFoldersComponentSelector', + componentInstanceContext: FavoriteFolderPickerInstanceContext, + get: + ({ instanceId }) => + ({ get }) => { + const folderIds = get( + favoriteFolderIdsPickerComponentState.atomFamily({ instanceId }), + ); + + return folderIds + .map((folderId: string) => + get( + favoriteFolderPickerComponentFamilyState.atomFamily({ + instanceId, + familyKey: folderId, + }), + ), + ) + .filter((folder): folder is FavoriteFolder => isDefined(folder)); + }, +}); diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useCreateFavorite.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useCreateFavorite.test.tsx index 88ca51386..f7c866d4e 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useCreateFavorite.test.tsx +++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useCreateFavorite.test.tsx @@ -44,7 +44,10 @@ describe('useCreateFavorite', () => { { wrapper: Wrapper }, ); - result.current(favoriteTargetObjectRecord, CoreObjectNameSingular.Person); + result.current.createFavorite( + favoriteTargetObjectRecord, + CoreObjectNameSingular.Person, + ); await waitFor(() => { expect(mocks[0].result).toHaveBeenCalled(); diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useDeleteFavorite.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useDeleteFavorite.test.tsx index 8c84243c7..bf4fece8c 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useDeleteFavorite.test.tsx +++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useDeleteFavorite.test.tsx @@ -38,7 +38,7 @@ describe('useDeleteFavorite', () => { { wrapper: Wrapper }, ); - result.current(favoriteId); + result.current.deleteFavorite(favoriteId); await waitFor(() => { expect(mocks[1].result).toHaveBeenCalled(); diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx index 8753fd887..aabe1711d 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx +++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx @@ -38,6 +38,6 @@ describe('useFavorites', () => { { wrapper: Wrapper }, ); - expect(result.current).toEqual(sortedFavorites); + expect(result.current.sortedFavorites).toEqual(sortedFavorites); }); }); diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useReorderFavorite.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useReorderFavorite.test.tsx index a5baceba7..c43c8e1ab 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useReorderFavorite.test.tsx +++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useReorderFavorite.test.tsx @@ -54,7 +54,10 @@ describe('useReorderFavorite', () => { announce: () => {}, }; - result.current(dragAndDropResult, responderProvided); + result.current.handleReorderFavorite( + dragAndDropResult, + responderProvided, + ); }); await waitFor(() => { diff --git a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts index 61bb0a7f7..e4906401d 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts @@ -34,5 +34,5 @@ export const useCreateFavorite = () => { }); }; - return createFavorite; + return { createFavorite }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts index 45498fc11..c8b121e69 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts @@ -28,5 +28,5 @@ export const useCreateFavoriteFolder = () => { }); }; - return createNewFavoriteFolder; + return { createNewFavoriteFolder }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavorite.ts b/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavorite.ts index 70e5e9c6e..e8f976c14 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavorite.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavorite.ts @@ -10,5 +10,5 @@ export const useDeleteFavorite = () => { deleteOneRecord(favoriteId); }; - return deleteFavorite; + return { deleteFavorite }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavoriteFolder.ts b/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavoriteFolder.ts index dabdb0e57..4c0925ca6 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavoriteFolder.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useDeleteFavoriteFolder.ts @@ -1,23 +1,46 @@ +import { Favorite } from '@/favorites/types/Favorite'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; -import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; +import { PREFETCH_CONFIG } from '@/prefetch/constants/PrefetchConfig'; +import { usePrefetchRunQuery } from '@/prefetch/hooks/internal/usePrefetchRunQuery'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; export const useDeleteFavoriteFolder = () => { const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular: CoreObjectNameSingular.FavoriteFolder, }); - const { upsertFavorites, favorites, workspaceFavorites } = - usePrefetchedFavoritesData(); + + const { upsertRecordsInCache } = usePrefetchRunQuery({ + prefetchKey: PrefetchKey.AllFavorites, + }); + + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular: + PREFETCH_CONFIG[PrefetchKey.AllFavorites].objectNameSingular, + }); + + const { readFindManyRecordsQueryInCache } = + useReadFindManyRecordsQueryInCache({ + objectMetadataItem, + }); const deleteFavoriteFolder = async (folderId: string): Promise => { await deleteOneRecord(folderId); - const updatedFavorites = [ - ...favorites.filter((favorite) => favorite.favoriteFolderId !== folderId), - ...workspaceFavorites, - ]; + const allFavorites = readFindManyRecordsQueryInCache({ + queryVariables: {}, + recordGqlFields: PREFETCH_CONFIG[ + PrefetchKey.AllFavorites + ].operationSignatureFactory({ objectMetadataItem }).fields, + }); - upsertFavorites(updatedFavorites); + const updatedFavorites = allFavorites.filter( + (favorite) => favorite.favoriteFolderId !== folderId, + ); + + upsertRecordsInCache(updatedFavorites); }; return { diff --git a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts index c97ab8008..8563ad2b9 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useFavorites.ts @@ -52,5 +52,5 @@ export const useFavorites = () => { ], ); - return sortedFavorites; + return { sortedFavorites }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useFavoritesByFolder.ts b/packages/twenty-front/src/modules/favorites/hooks/useFavoritesByFolder.ts index 73c1239a3..2747c1e1f 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useFavoritesByFolder.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useFavoritesByFolder.ts @@ -1,62 +1,30 @@ import { sortFavorites } from '@/favorites/utils/sortFavorites'; -import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; -import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; -import { View } from '@/views/types/View'; -import { useMemo } from 'react'; -import { useRecoilValue } from 'recoil'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { useFavoritesMetadata } from './useFavoritesMetadata'; import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; import { usePrefetchedFavoritesFoldersData } from './usePrefetchedFavoritesFoldersData'; export const useFavoritesByFolder = () => { const { favorites } = usePrefetchedFavoritesData(); const { favoriteFolders } = usePrefetchedFavoritesFoldersData(); - const { records: views } = usePrefetchedData(PrefetchKey.AllViews); - const objectMetadataItems = useRecoilValue(objectMetadataItemsState); - const getObjectRecordIdentifierByNameSingular = - useGetObjectRecordIdentifierByNameSingular(); - - const { objectMetadataItem: favoriteObjectMetadataItem } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Favorite, - }); - - const favoriteRelationFields = useMemo( - () => - favoriteObjectMetadataItem.fields.filter( - (fieldMetadataItem) => - fieldMetadataItem.type === FieldMetadataType.Relation && - fieldMetadataItem.name !== 'workspaceMember' && - fieldMetadataItem.name !== 'favoriteFolder', - ), - [favoriteObjectMetadataItem.fields], - ); - - const favoritesByFolder = useMemo(() => { - return favoriteFolders.map((folder) => ({ - folderId: folder.id, - folderName: folder.name, - favorites: sortFavorites( - favorites.filter((favorite) => favorite.favoriteFolderId === folder.id), - favoriteRelationFields, - getObjectRecordIdentifierByNameSingular, - true, - views, - objectMetadataItems, - ), - })); - }, [ - favoriteFolders, - favorites, - favoriteRelationFields, - getObjectRecordIdentifierByNameSingular, + const { views, objectMetadataItems, - ]); + getObjectRecordIdentifierByNameSingular, + favoriteRelationFields, + } = useFavoritesMetadata(); - return favoritesByFolder; + const favoritesByFolder = favoriteFolders.map((folder) => ({ + folderId: folder.id, + folderName: folder.name, + favorites: sortFavorites( + favorites.filter((favorite) => favorite.favoriteFolderId === folder.id), + favoriteRelationFields, + getObjectRecordIdentifierByNameSingular, + true, + views, + objectMetadataItems, + ), + })); + + return { favoritesByFolder }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useFavoritesMetadata.ts b/packages/twenty-front/src/modules/favorites/hooks/useFavoritesMetadata.ts new file mode 100644 index 000000000..d074640c4 --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/hooks/useFavoritesMetadata.ts @@ -0,0 +1,35 @@ +import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; +import { View } from '@/views/types/View'; +import { useRecoilValue } from 'recoil'; +import { FieldMetadataType } from '~/generated-metadata/graphql'; + +export const useFavoritesMetadata = () => { + const { records: views } = usePrefetchedData(PrefetchKey.AllViews); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + const getObjectRecordIdentifierByNameSingular = + useGetObjectRecordIdentifierByNameSingular(); + + const { objectMetadataItem: favoriteObjectMetadataItem } = + useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.Favorite, + }); + + const favoriteRelationFields = favoriteObjectMetadataItem.fields.filter( + (fieldMetadataItem) => + fieldMetadataItem.type === FieldMetadataType.Relation && + fieldMetadataItem.name !== 'workspaceMember' && + fieldMetadataItem.name !== 'favoriteFolder', + ); + + return { + views, + objectMetadataItems, + getObjectRecordIdentifierByNameSingular, + favoriteRelationFields, + }; +}; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useReorderFavorite.ts b/packages/twenty-front/src/modules/favorites/hooks/useReorderFavorite.ts index dfa1dcd5e..bbbbf1285 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useReorderFavorite.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useReorderFavorite.ts @@ -12,7 +12,7 @@ export const useReorderFavorite = () => { objectNameSingular: CoreObjectNameSingular.Favorite, }); - const reorderFavorite: OnDragEndResponder = (result) => { + const handleReorderFavorite: OnDragEndResponder = (result) => { if (!result.destination) return; const draggedFavoriteId = result.draggableId; @@ -37,5 +37,5 @@ export const useReorderFavorite = () => { }); }; - return reorderFavorite; + return { handleReorderFavorite }; }; diff --git a/packages/twenty-front/src/modules/favorites/hooks/useSortedFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/useSortedFavorites.ts index e9c03cc63..3ec57bf5d 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useSortedFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useSortedFavorites.ts @@ -1,50 +1,28 @@ import { sortFavorites } from '@/favorites/utils/sortFavorites'; -import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; -import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; -import { View } from '@/views/types/View'; import { useMemo } from 'react'; -import { useRecoilValue } from 'recoil'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { useFavoritesMetadata } from './useFavoritesMetadata'; import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; export const useSortedFavorites = () => { const { favorites, workspaceFavorites } = usePrefetchedFavoritesData(); - const { records: views } = usePrefetchedData(PrefetchKey.AllViews); - const objectMetadataItems = useRecoilValue(objectMetadataItemsState); - const { objectMetadataItem: favoriteObjectMetadataItem } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Favorite, - }); - - const getObjectRecordIdentifierByNameSingular = - useGetObjectRecordIdentifierByNameSingular(); - - const favoriteRelationFieldMetadataItems = useMemo( - () => - favoriteObjectMetadataItem.fields.filter( - (fieldMetadataItem) => - fieldMetadataItem.type === FieldMetadataType.Relation && - fieldMetadataItem.name !== 'workspaceMember' && - fieldMetadataItem.name !== 'favoriteFolder', - ), - [favoriteObjectMetadataItem.fields], - ); + const { + views, + objectMetadataItems, + getObjectRecordIdentifierByNameSingular, + favoriteRelationFields, + } = useFavoritesMetadata(); const favoritesSorted = useMemo(() => { return sortFavorites( favorites, - favoriteRelationFieldMetadataItems, + favoriteRelationFields, getObjectRecordIdentifierByNameSingular, true, views, objectMetadataItems, ); }, [ - favoriteRelationFieldMetadataItems, + favoriteRelationFields, favorites, getObjectRecordIdentifierByNameSingular, views, @@ -54,14 +32,14 @@ export const useSortedFavorites = () => { const workspaceFavoritesSorted = useMemo(() => { return sortFavorites( workspaceFavorites.filter((favorite) => favorite.viewId), - favoriteRelationFieldMetadataItems, + favoriteRelationFields, getObjectRecordIdentifierByNameSingular, false, views, objectMetadataItems, ); }, [ - favoriteRelationFieldMetadataItems, + favoriteRelationFields, getObjectRecordIdentifierByNameSingular, workspaceFavorites, views, diff --git a/packages/twenty-front/src/modules/favorites/hooks/useWorkspaceFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/useWorkspaceFavorites.ts index 4a1d1686a..c6de1d26f 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useWorkspaceFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useWorkspaceFavorites.ts @@ -52,5 +52,5 @@ export const useWorkspaceFavorites = () => { ], ); - return sortedWorkspaceFavorites; + return { sortedWorkspaceFavorites }; }; diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx index f603faced..0a86fe528 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx @@ -6,23 +6,20 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CurrentWorkspaceMemberFavoritesFolders } from '@/favorites/components/CurrentWorkspaceMemberFavoritesFolders'; import { WorkspaceFavorites } from '@/favorites/components/WorkspaceFavorites'; import { NavigationDrawerOpenedSection } from '@/object-metadata/components/NavigationDrawerOpenedSection'; -import { NavigationDrawerSectionForObjectMetadataItemsWrapper } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper'; +import { RemoteNavigationDrawerSection } from '@/object-metadata/components/RemoteNavigationDrawerSection'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import styled from '@emotion/styled'; const StyledMainSection = styled(NavigationDrawerSection)` min-height: fit-content; `; -const StyledContainer = styled.div` - overflow-x: hidden; - overflow-y: auto; -`; export const MainNavigationDrawerItems = () => { const isMobile = useIsMobile(); const { toggleCommandMenu } = useCommandMenu(); @@ -59,15 +56,16 @@ export const MainNavigationDrawerItems = () => { /> )} - + - - - - - + + ); }; diff --git a/packages/twenty-front/src/modules/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites.ts b/packages/twenty-front/src/modules/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites.ts index 7e6bca977..fa616a912 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites.ts @@ -7,7 +7,8 @@ import { View } from '@/views/types/View'; export const useFilteredObjectMetadataItemsForWorkspaceFavorites = () => { const { records: views } = usePrefetchedData(PrefetchKey.AllViews); - const workspaceFavorites = useWorkspaceFavorites(); + const { sortedWorkspaceFavorites: workspaceFavorites } = + useWorkspaceFavorites(); const workspaceFavoriteIds = new Set( workspaceFavorites.map((favorite) => favorite.recordId), diff --git a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems.tsx b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems.tsx index 97f2a7452..ecd8af8a3 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems.tsx @@ -4,7 +4,6 @@ import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigat import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection'; -import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; @@ -78,19 +77,15 @@ export const NavigationDrawerSectionForObjectMetadataItems = ({ onClick={() => toggleNavigationSection()} /> - - - {isNavigationSectionOpen && - objectMetadataItemsForNavigationItems.map( - (objectMetadataItem) => ( - - ), - )} - - + + {isNavigationSectionOpen && + objectMetadataItemsForNavigationItems.map((objectMetadataItem) => ( + + ))} + ) ); diff --git a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper.tsx b/packages/twenty-front/src/modules/object-metadata/components/RemoteNavigationDrawerSection.tsx similarity index 81% rename from packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper.tsx rename to packages/twenty-front/src/modules/object-metadata/components/RemoteNavigationDrawerSection.tsx index 91a22ca5a..1ad2595e8 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/RemoteNavigationDrawerSection.tsx @@ -7,16 +7,12 @@ import { NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader } from '@/o import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; -export const NavigationDrawerSectionForObjectMetadataItemsWrapper = ({ - isRemote, -}: { - isRemote: boolean; -}) => { +export const RemoteNavigationDrawerSection = () => { const currentUser = useRecoilValue(currentUserState); const { activeObjectMetadataItems } = useFilteredObjectMetadataItems(); const filteredActiveObjectMetadataItems = activeObjectMetadataItems.filter( - (item) => (isRemote ? item.isRemote : !item.isRemote), + (item) => item.isRemote, ); const loading = useIsPrefetchLoading(); @@ -26,9 +22,9 @@ export const NavigationDrawerSectionForObjectMetadataItemsWrapper = ({ return ( ); }; diff --git a/packages/twenty-front/src/modules/object-metadata/components/__stories__/NavigationDrawerSectionForObjectMetadataItemsWrapper.stories.tsx b/packages/twenty-front/src/modules/object-metadata/components/__stories__/NavigationDrawerSectionForObjectMetadataItemsWrapper.stories.tsx deleted file mode 100644 index fc21940e6..000000000 --- a/packages/twenty-front/src/modules/object-metadata/components/__stories__/NavigationDrawerSectionForObjectMetadataItemsWrapper.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; - -import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator'; -import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator'; -import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator'; -import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator'; -import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; - -import { NavigationDrawerSectionForObjectMetadataItemsWrapper } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper'; -import { within } from '@storybook/test'; -import { PrefetchLoadedDecorator } from '~/testing/decorators/PrefetchLoadedDecorator'; - -const meta: Meta = - { - title: - 'Modules/ObjectMetadata/NavigationDrawerSectionForObjectMetadataItemsWrapper', - component: NavigationDrawerSectionForObjectMetadataItemsWrapper, - decorators: [ - IconsProviderDecorator, - ObjectMetadataItemsDecorator, - ComponentWithRouterDecorator, - ComponentWithRecoilScopeDecorator, - SnackBarDecorator, - PrefetchLoadedDecorator, - ], - parameters: { - msw: graphqlMocks, - }, - }; - -export default meta; -type Story = StoryObj< - typeof NavigationDrawerSectionForObjectMetadataItemsWrapper ->; - -export const Default: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - await canvas.findByText('People', undefined, { timeout: 10000 }); - await canvas.findByText('Companies'); - await canvas.findByText('Opportunities'); - }, -}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx index 9d850160b..94c85d7b0 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx @@ -1,3 +1,4 @@ +import { PageFavoriteFoldersDropdown } from '@/favorites/components/PageFavoriteFolderDropdown'; import { FAVORITE_FOLDER_PICKER_DROPDOWN_ID } from '@/favorites/favorite-folder-picker/constants/FavoriteFolderPickerDropdownId'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; @@ -8,7 +9,6 @@ import { recordIndexViewTypeState } from '@/object-record/record-index/states/re import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { PageAddButton } from '@/ui/layout/page/components/PageAddButton'; -import { PageFavoriteFoldersDropdown } from '@/ui/layout/page/components/PageFavoriteFolderDropdown'; import { PageHeader } from '@/ui/layout/page/components/PageHeader'; import { PageHotkeysEffect } from '@/ui/layout/page/components/PageHotkeysEffect'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; @@ -39,7 +39,7 @@ export const RecordIndexPageHeader = () => { const view = views.find((view) => view.id === currentViewId); - const favorites = useFavorites(); + const { sortedFavorites: favorites } = useFavorites(); const isFavorite = favorites.some( (favorite) => diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts index 46df62135..f2e2cb17a 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts @@ -36,9 +36,9 @@ export const useRecordShowPage = ( const { objectMetadataItems } = useObjectMetadataItems(); const { labelIdentifierFieldMetadataItem } = useLabelIdentifierFieldMetadataItem({ objectNameSingular }); - const favorites = useFavorites(); - const createFavorite = useCreateFavorite(); - const deleteFavorite = useDeleteFavorite(); + const { sortedFavorites: favorites } = useFavorites(); + const { createFavorite } = useCreateFavorite(); + const { deleteFavorite } = useDeleteFavorite(); const setEntityFields = useSetRecoilState( recordStoreFamilyState(objectRecordId), ); diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchFavortiteFoldersRunQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchFavortiteFoldersRunQueriesEffect.tsx index 376c1e469..c8e93949d 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchFavortiteFoldersRunQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchFavortiteFoldersRunQueriesEffect.tsx @@ -9,6 +9,7 @@ import { useEffect } from 'react'; import { useRecoilValue } from 'recoil'; import { isDefined } from '~/utils/isDefined'; +// TODO: Remove this component once we merge it with PrefetchRunQueriesEffect (once we remove feature flag) export const PrefetchFavoriteFoldersRunQueriesEffect = () => { const currentUser = useRecoilValue(currentUserState); @@ -19,7 +20,6 @@ export const PrefetchFavoriteFoldersRunQueriesEffect = () => { const { objectMetadataItems } = useObjectMetadataItems(); - // Only include favorite folders operation const operationSignatures = Object.values(PREFETCH_CONFIG) .filter(({ objectNameSingular }) => objectNameSingular === 'favoriteFolder') .map(({ objectNameSingular, operationSignatureFactory }) => { diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx index bad5c0b5a..3541e90e8 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunQueriesEffect.tsx @@ -9,14 +9,10 @@ import { PREFETCH_CONFIG } from '@/prefetch/constants/PrefetchConfig'; import { usePrefetchRunQuery } from '@/prefetch/hooks/internal/usePrefetchRunQuery'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { View } from '@/views/types/View'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { isDefined } from '~/utils/isDefined'; export const PrefetchRunQueriesEffect = () => { const currentUser = useRecoilValue(currentUserState); - const isFavoriteFolderEnabled = useIsFeatureEnabled( - 'IS_FAVORITE_FOLDER_ENABLED', - ); const { upsertRecordsInCache: upsertViewsInCache } = usePrefetchRunQuery({ @@ -33,7 +29,7 @@ export const PrefetchRunQueriesEffect = () => { const operationSignatures = Object.values(PREFETCH_CONFIG) .filter( ({ objectNameSingular }) => - // Exclude favorite folders as they're handled separately + // TODO: Remove this filter once we merge PrefetchFavortiteFoldersRunQueriesEffect with this component objectNameSingular !== 'favoriteFolder', ) .map(({ objectNameSingular, operationSignatureFactory }) => { @@ -57,12 +53,7 @@ export const PrefetchRunQueriesEffect = () => { if (isDefined(result.favorites)) { upsertFavoritesInCache(result.favorites as Favorite[]); } - }, [ - result, - upsertViewsInCache, - upsertFavoritesInCache, - isFavoriteFolderEnabled, - ]); + }, [result, upsertViewsInCache, upsertFavoritesInCache]); return <>; }; diff --git a/packages/twenty-front/src/modules/prefetch/hooks/useIsFavoriteFoldersPrefetchLoading.ts b/packages/twenty-front/src/modules/prefetch/hooks/useIsFavoriteFoldersPrefetchLoading.ts deleted file mode 100644 index a3ffaa608..000000000 --- a/packages/twenty-front/src/modules/prefetch/hooks/useIsFavoriteFoldersPrefetchLoading.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedFamilyState'; -import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; -import { useRecoilValue } from 'recoil'; - -export const useIsFavoriteFoldersPrefetchLoading = () => { - const areFavoritesFolderPrefetched = useRecoilValue( - prefetchIsLoadedFamilyState(PrefetchKey.AllFavoritesFolders), - ); - - return !areFavoritesFolderPrefetched; -}; diff --git a/packages/twenty-front/src/modules/prefetch/hooks/useIsPrefetchLoading.ts b/packages/twenty-front/src/modules/prefetch/hooks/useIsPrefetchLoading.ts index ca3e275b5..9a291c811 100644 --- a/packages/twenty-front/src/modules/prefetch/hooks/useIsPrefetchLoading.ts +++ b/packages/twenty-front/src/modules/prefetch/hooks/useIsPrefetchLoading.ts @@ -2,13 +2,14 @@ import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedF import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useRecoilValue } from 'recoil'; -import { useIsFavoriteFoldersPrefetchLoading } from './useIsFavoriteFoldersPrefetchLoading'; export const useIsPrefetchLoading = () => { const isFavoriteFolderEnabled = useIsFeatureEnabled( 'IS_FAVORITE_FOLDER_ENABLED', ); - const isFavoriteFoldersLoading = useIsFavoriteFoldersPrefetchLoading(); + const isFavoriteFoldersPrefetched = useRecoilValue( + prefetchIsLoadedFamilyState(PrefetchKey.AllFavoritesFolders), + ); const areViewsPrefetched = useRecoilValue( prefetchIsLoadedFamilyState(PrefetchKey.AllViews), @@ -20,6 +21,6 @@ export const useIsPrefetchLoading = () => { return ( !areViewsPrefetched || !areFavoritesPrefetched || - (isFavoriteFolderEnabled && isFavoriteFoldersLoading) + (isFavoriteFolderEnabled && !isFavoriteFoldersPrefetched) ); }; diff --git a/packages/twenty-front/src/modules/ui/layout/draggable-list/components/DraggableList.tsx b/packages/twenty-front/src/modules/ui/layout/draggable-list/components/DraggableList.tsx index 000d1156b..d130cbde0 100644 --- a/packages/twenty-front/src/modules/ui/layout/draggable-list/components/DraggableList.tsx +++ b/packages/twenty-front/src/modules/ui/layout/draggable-list/components/DraggableList.tsx @@ -1,10 +1,10 @@ -import { useState } from 'react'; import styled from '@emotion/styled'; import { DragDropContext, Droppable, OnDragEndResponder, } from '@hello-pangea/dnd'; +import { useState } from 'react'; import { v4 } from 'uuid'; type DraggableListProps = { draggableItems: React.ReactNode; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx b/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx index 41dc48f13..969a24a6f 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx @@ -23,12 +23,17 @@ const StyledScrollWrapper = styled.div` } `; +const StyledInnerContainer = styled.div` + flex: 1; +`; + export type ScrollWrapperProps = { children: React.ReactNode; className?: string; enableXScroll?: boolean; enableYScroll?: boolean; contextProviderName: ContextProviderName; + scrollHide?: boolean; }; export const ScrollWrapper = ({ @@ -37,6 +42,7 @@ export const ScrollWrapper = ({ enableXScroll = true, enableYScroll = true, contextProviderName, + scrollHide = false, }: ScrollWrapperProps) => { const scrollableRef = useRef(null); const Context = getContextByProviderName(contextProviderName); @@ -55,7 +61,10 @@ export const ScrollWrapper = ({ const [initialize, instance] = useOverlayScrollbars({ options: { - scrollbars: { autoHide: 'scroll' }, + scrollbars: { + autoHide: scrollHide ? 'scroll' : 'never', + visibility: scrollHide ? 'hidden' : 'visible', + }, overflow: { x: enableXScroll ? undefined : 'hidden', y: enableYScroll ? undefined : 'hidden', @@ -84,7 +93,7 @@ export const ScrollWrapper = ({ }} > - {children} + {children} ); diff --git a/packages/twenty-front/src/pages/object-record/RecordShowPageBaseHeader.tsx b/packages/twenty-front/src/pages/object-record/RecordShowPageBaseHeader.tsx index 94737e826..40f442482 100644 --- a/packages/twenty-front/src/pages/object-record/RecordShowPageBaseHeader.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordShowPageBaseHeader.tsx @@ -1,8 +1,8 @@ +import { PageFavoriteButton } from '@/favorites/components/PageFavoriteButton'; +import { PageFavoriteFoldersDropdown } from '@/favorites/components/PageFavoriteFolderDropdown'; import { FAVORITE_FOLDER_PICKER_DROPDOWN_ID } from '@/favorites/favorite-folder-picker/constants/FavoriteFolderPickerDropdownId'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { PageFavoriteButton } from '@/ui/layout/page/components/PageFavoriteButton'; -import { PageFavoriteFoldersDropdown } from '@/ui/layout/page/components/PageFavoriteFolderDropdown'; import { ShowPageAddButton } from '@/ui/layout/show-page/components/ShowPageAddButton'; import { ShowPageMoreButton } from '@/ui/layout/show-page/components/ShowPageMoreButton'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';