From 4cb64c6aa5d354ef1769e13b8c32ce29f903920f Mon Sep 17 00:00:00 2001 From: Etienne <45695613+etiennejouan@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:35:17 +0100 Subject: [PATCH] Restore old favorite design (#18049) Issue : With IS_NAVIGATION_MENU_ITEM_ENABLED:true + IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED:false, nav menu design is changed after 1.18.0 release : views expansion removed, system object displayed, position re-ordered We prefer keeping the same "old" favorite behaviour and design state - After 1.18.0 all workspaces have up-to-date navigation menu items (migrated) - IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED becomes the FF for nav menu new design --------- Co-authored-by: Charles Bochet --- .../AddToFavoritesSingleRecordAction.tsx | 14 +-- .../components/DeleteSingleRecordAction.tsx | 20 ++--- .../RemoveFromFavoritesSingleRecordAction.tsx | 32 +++---- .../useShouldActionBeRegisteredParams.ts | 8 +- .../favorites/hooks/__mocks__/useFavorites.ts | 39 ++++++++- .../__tests__/useCreateFavorite.test.tsx | 17 ++++ .../favorites/hooks/useCreateFavorite.ts | 86 ++++++++++++++++++- .../hooks/useCreateFavoriteFolder.ts | 37 ++++++++ ...berNavigationMenuItemFoldersDispatcher.tsx | 6 +- ...igationMenuItemFolderContentDispatcher.tsx | 6 +- ...WorkspaceNavigationMenuItemsDispatcher.tsx | 6 +- .../components/MainNavigationDrawer.tsx | 10 +-- .../components/NavbarDragProvider.tsx | 6 +- .../components/PageDragDropProvider.tsx | 6 +- ...igationDrawerItemForObjectMetadataItem.tsx | 73 ++++++++++++++++ .../NavigationDrawerOpenedSection.tsx | 6 +- .../hooks/useDeleteManyRecords.ts | 12 +-- .../hooks/useDestroyManyRecords.ts | 13 +-- .../hooks/useIncrementalDeleteManyRecords.ts | 11 +-- .../PrefetchRunFavoriteQueriesEffect.tsx | 8 +- ...etchRunNavigationMenuItemQueriesEffect.tsx | 6 +- .../components/ViewPickerOptionDropdown.tsx | 16 ++-- .../object-metadata.service.ts | 31 +++---- .../constant/default-feature-flags.ts | 1 - 24 files changed, 326 insertions(+), 144 deletions(-) diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/AddToFavoritesSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/AddToFavoritesSingleRecordAction.tsx index 93a36a1528..cac5779fb9 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/AddToFavoritesSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/AddToFavoritesSingleRecordAction.tsx @@ -2,24 +2,16 @@ import { Action } from '@/action-menu/actions/components/Action'; import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow'; import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow'; import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite'; -import { useCreateNavigationMenuItem } from '@/navigation-menu-item/hooks/useCreateNavigationMenuItem'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; export const AddToFavoritesSingleRecordAction = () => { const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(); const recordId = useSelectedRecordIdOrThrow(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); - const { createFavorite } = useCreateFavorite(); - const { createNavigationMenuItem } = useCreateNavigationMenuItem(); const selectedRecord = useRecoilValue(recordStoreFamilyState(recordId)); @@ -28,11 +20,7 @@ export const AddToFavoritesSingleRecordAction = () => { return; } - if (isNavigationMenuItemEnabled) { - createNavigationMenuItem(selectedRecord, objectMetadataItem.nameSingular); - } else { - createFavorite(selectedRecord, objectMetadataItem.nameSingular); - } + createFavorite(selectedRecord, objectMetadataItem.nameSingular); }; return ; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/DeleteSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/DeleteSingleRecordAction.tsx index 32b8bb74bf..dc6e8b51b2 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/DeleteSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/DeleteSingleRecordAction.tsx @@ -8,9 +8,7 @@ import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { useRemoveSelectedRecordsFromRecordBoard } from '@/object-record/record-board/hooks/useRemoveSelectedRecordsFromRecordBoard'; import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { isDefined } from 'twenty-shared/utils'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; export const DeleteSingleRecordAction = () => { const { recordIndexId, objectMetadataItem } = @@ -29,9 +27,7 @@ export const DeleteSingleRecordAction = () => { const { sortedFavorites: favorites } = useFavorites(); const { deleteFavorite } = useDeleteFavorite(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); + const { navigationMenuItems, workspaceNavigationMenuItems } = usePrefetchedNavigationMenuItemsData(); const { removeNavigationMenuItemsByTargetRecordIds } = @@ -50,15 +46,13 @@ export const DeleteSingleRecordAction = () => { deleteFavorite(foundFavorite.id); } - if (isNavigationMenuItemEnabled) { - const foundNavigationMenuItem = [ - ...navigationMenuItems, - ...workspaceNavigationMenuItems, - ].find((item) => item.targetRecordId === recordId); + const foundNavigationMenuItem = [ + ...navigationMenuItems, + ...workspaceNavigationMenuItems, + ].find((item) => item.targetRecordId === recordId); - if (isDefined(foundNavigationMenuItem)) { - removeNavigationMenuItemsByTargetRecordIds([recordId]); - } + if (isDefined(foundNavigationMenuItem)) { + removeNavigationMenuItemsByTargetRecordIds([recordId]); } await deleteOneRecord(recordId); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/RemoveFromFavoritesSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/RemoveFromFavoritesSingleRecordAction.tsx index afe61abbe4..0510ab0139 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/RemoveFromFavoritesSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/RemoveFromFavoritesSingleRecordAction.tsx @@ -5,9 +5,7 @@ import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useDeleteNavigationMenuItem } from '@/navigation-menu-item/hooks/useDeleteNavigationMenuItem'; import { usePrefetchedNavigationMenuItemsData } from '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { isDefined } from 'twenty-shared/utils'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; export const RemoveFromFavoritesSingleRecordAction = () => { const recordId = useSelectedRecordIdOrThrow(); @@ -16,9 +14,6 @@ export const RemoveFromFavoritesSingleRecordAction = () => { const { sortedFavorites: favorites } = useFavorites(); const { navigationMenuItems, workspaceNavigationMenuItems } = usePrefetchedNavigationMenuItemsData(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); const { deleteFavorite } = useDeleteFavorite(); const { deleteNavigationMenuItem } = useDeleteNavigationMenuItem(); @@ -27,28 +22,21 @@ export const RemoveFromFavoritesSingleRecordAction = () => { (favorite) => favorite.recordId === recordId, ); - const foundNavigationMenuItem = isNavigationMenuItemEnabled - ? [...navigationMenuItems, ...workspaceNavigationMenuItems].find( - (item) => - item.targetRecordId === recordId && - item.targetObjectMetadataId === objectMetadataItem.id, - ) - : undefined; + const foundNavigationMenuItem = [ + ...navigationMenuItems, + ...workspaceNavigationMenuItems, + ].find( + (item) => + item.targetRecordId === recordId && + item.targetObjectMetadataId === objectMetadataItem.id, + ); const handleClick = () => { - if (isNavigationMenuItemEnabled) { - if (!isDefined(foundNavigationMenuItem)) { - return; - } - - deleteNavigationMenuItem(foundNavigationMenuItem.id); - return; - } - - if (!isDefined(foundFavorite)) { + if (!isDefined(foundNavigationMenuItem) || !isDefined(foundFavorite)) { return; } + deleteNavigationMenuItem(foundNavigationMenuItem.id); deleteFavorite(foundFavorite.id); }; diff --git a/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts b/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts index 2bc3746929..3b663d7ab1 100644 --- a/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts +++ b/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts @@ -29,8 +29,8 @@ export const useShouldActionBeRegisteredParams = ({ }): ShouldBeRegisteredFunctionParams => { const { sortedFavorites: favorites } = useFavorites(); const { navigationMenuItems } = usePrefetchedNavigationMenuItemsData(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const contextStoreTargetedRecordsRule = useRecoilComponentValue( @@ -47,7 +47,7 @@ export const useShouldActionBeRegisteredParams = ({ return false; } - if (isNavigationMenuItemEnabled && isDefined(objectMetadataItem)) { + if (isNavigationMenuItemEditingEnabled && isDefined(objectMetadataItem)) { const foundNavigationMenuItem = navigationMenuItems?.find( (item) => item.targetRecordId === recordId && @@ -62,7 +62,7 @@ export const useShouldActionBeRegisteredParams = ({ return !!foundFavorite; }, [ recordId, - isNavigationMenuItemEnabled, + isNavigationMenuItemEditingEnabled, objectMetadataItem, navigationMenuItems, favorites, diff --git a/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts index a181744f32..e6291c4e40 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts @@ -5,6 +5,7 @@ import { generateCreateOneRecordMutation } from '@/object-metadata/utils/generat import { generateUpdateOneRecordMutation } from '@/object-metadata/utils/generateUpdateOneRecordMutation'; import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; import { AvatarType } from 'twenty-ui/display'; +import { CreateNavigationMenuItemDocument } from '~/generated-metadata/graphql'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; import { getMockObjectMetadataItemOrThrow } from '~/testing/utils/getMockObjectMetadataItemOrThrow'; @@ -105,7 +106,8 @@ export const sortedFavorites = [ }, ]; -const favoriteObjectMetadataItem = getMockObjectMetadataItemOrThrow('favorite') +const favoriteObjectMetadataItem = getMockObjectMetadataItemOrThrow('favorite'); +const personObjectMetadataItem = getMockObjectMetadataItemOrThrow('person'); const UPDATE_ONE_FAVORITE_MUTATION = generateUpdateOneRecordMutation( { @@ -240,6 +242,41 @@ export const mocks = [ }, })), }, + + { + request: { + query: CreateNavigationMenuItemDocument, + variables: { + input: { + targetRecordId: favoriteTargetObjectId, + targetObjectMetadataId: personObjectMetadataItem.id, + userWorkspaceId: '1', + folderId: undefined, + position: 1, + }, + }, + }, + result: jest.fn(() => ({ + data: { + createNavigationMenuItem: { + __typename: 'NavigationMenuItem', + id: mockId, + userWorkspaceId: '1', + targetRecordId: favoriteTargetObjectId, + targetObjectMetadataId: personObjectMetadataItem.id, + viewId: null, + folderId: null, + name: null, + link: null, + icon: null, + position: 1, + applicationId: null, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + }, + })), + }, ]; export const mockWorkspaceMember = { 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 1b54bbd98b..6001c148aa 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 @@ -23,6 +23,23 @@ jest.mock('@/object-record/hooks/useFindManyRecords', () => ({ useFindManyRecords: () => ({ records: initialFavorites }), })); +jest.mock( + '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData', + () => ({ + usePrefetchedNavigationMenuItemsData: () => ({ + navigationMenuItems: [], + workspaceNavigationMenuItems: [], + currentWorkspaceMemberId: '1', + }), + }), +); + +jest.mock('@/favorites/hooks/usePrefetchedFavoritesFoldersData', () => ({ + usePrefetchedFavoritesFoldersData: () => ({ + favoriteFolders: [], + }), +})); + const Wrapper = getJestMetadataAndApolloMocksWrapper({ apolloMocks: mocks, }); diff --git a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts index b5a3183c4d..09538b5d12 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavorite.ts @@ -1,15 +1,31 @@ +import { usePrefetchedNavigationMenuItemsData } from '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData'; +import { isNavigationMenuItemFolder } from '@/navigation-menu-item/utils/isNavigationMenuItemFolder'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; +import { useRecoilValue } from 'recoil'; +import { isDefined } from 'twenty-shared/utils'; +import { useCreateNavigationMenuItemMutation } from '~/generated-metadata/graphql'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; +import { usePrefetchedFavoritesFoldersData } from './usePrefetchedFavoritesFoldersData'; export const useCreateFavorite = () => { const { favorites, currentWorkspaceMemberId } = usePrefetchedFavoritesData(); + const { favoriteFolders } = usePrefetchedFavoritesFoldersData(); + const { navigationMenuItems } = usePrefetchedNavigationMenuItemsData(); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + const { createOneRecord: createOneFavorite } = useCreateOneRecord({ objectNameSingular: CoreObjectNameSingular.Favorite, }); - const createFavorite = ( + const [createNavigationMenuItemMutation] = + useCreateNavigationMenuItemMutation({ + refetchQueries: ['FindManyNavigationMenuItems'], + }); + + const createFavorite = async ( targetRecord: ObjectRecord, targetObjectNameSingular: string, favoriteFolderId?: string, @@ -25,12 +41,78 @@ export const useCreateFavorite = () => { 0, ); - createOneFavorite({ + await createOneFavorite({ [`${targetObjectNameSingular}Id`]: targetRecord.id, position: maxPosition + 1, forWorkspaceMemberId: currentWorkspaceMemberId, favoriteFolderId, }); + + let navigationMenuItemFolderId: string | undefined; + + if (isDefined(favoriteFolderId)) { + const favoriteFolder = favoriteFolders.find( + (folder) => folder.id === favoriteFolderId, + ); + + if (isDefined(favoriteFolder)) { + const matchingNavigationMenuItemFolder = navigationMenuItems.find( + (item) => + isNavigationMenuItemFolder(item) && + item.name === favoriteFolder.name && + item.userWorkspaceId === currentWorkspaceMemberId, + ); + + navigationMenuItemFolderId = matchingNavigationMenuItemFolder?.id; + } + } + + const relevantNavigationMenuItems = navigationMenuItemFolderId + ? navigationMenuItems.filter( + (item) => item.folderId === navigationMenuItemFolderId, + ) + : navigationMenuItems.filter( + (item) => + !item.folderId && item.userWorkspaceId === currentWorkspaceMemberId, + ); + + const maxNavigationMenuItemPosition = Math.max( + ...relevantNavigationMenuItems.map((item) => item.position), + 0, + ); + + const isView = targetObjectNameSingular === 'view'; + + if (isView) { + await createNavigationMenuItemMutation({ + variables: { + input: { + viewId: targetRecord.id, + userWorkspaceId: currentWorkspaceMemberId, + folderId: navigationMenuItemFolderId, + position: maxNavigationMenuItemPosition + 1, + }, + }, + }); + } else { + const objectMetadataItem = objectMetadataItems.find( + (item) => item.nameSingular === targetObjectNameSingular, + ); + + if (isDefined(objectMetadataItem)) { + await createNavigationMenuItemMutation({ + variables: { + input: { + targetRecordId: targetRecord.id, + targetObjectMetadataId: objectMetadataItem.id, + userWorkspaceId: currentWorkspaceMemberId, + folderId: navigationMenuItemFolderId, + position: maxNavigationMenuItemPosition + 1, + }, + }, + }); + } + } }; 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 bee2fbea98..a5e0821494 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useCreateFavoriteFolder.ts @@ -1,5 +1,8 @@ +import { usePrefetchedNavigationMenuItemsData } from '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; +import { isDefined } from 'twenty-shared/utils'; +import { useCreateNavigationMenuItemMutation } from '~/generated-metadata/graphql'; import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; import { usePrefetchedFavoritesFoldersData } from './usePrefetchedFavoritesFoldersData'; @@ -10,6 +13,12 @@ export const useCreateFavoriteFolder = () => { const { currentWorkspaceMemberId } = usePrefetchedFavoritesData(); const { favoriteFolders } = usePrefetchedFavoritesFoldersData(); + const { navigationMenuItems } = usePrefetchedNavigationMenuItemsData(); + + const [createNavigationMenuItemMutation] = + useCreateNavigationMenuItemMutation({ + refetchQueries: ['FindManyNavigationMenuItems'], + }); const createNewFavoriteFolder = async (name: string): Promise => { if (!name || !currentWorkspaceMemberId) { @@ -25,6 +34,34 @@ export const useCreateFavoriteFolder = () => { name, position: maxPosition + 1, }); + + const folderNavigationMenuItems = navigationMenuItems.filter( + (item) => + isDefined(item.name) && + !item.folderId && + !item.targetRecordId && + !item.targetObjectMetadataId && + !item.viewId && + item.userWorkspaceId === currentWorkspaceMemberId, + ); + + const maxNavigationMenuItemPosition = Math.max( + ...folderNavigationMenuItems.map((item) => item.position), + 0, + ); + + await createNavigationMenuItemMutation({ + variables: { + input: { + name, + targetRecordId: null, + targetObjectMetadataId: null, + userWorkspaceId: currentWorkspaceMemberId, + folderId: null, + position: maxNavigationMenuItemPosition + 1, + }, + }, + }); }; return { createNewFavoriteFolder }; diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFoldersDispatcher.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFoldersDispatcher.tsx index 179372b5ee..b26a1f36a2 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFoldersDispatcher.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFoldersDispatcher.tsx @@ -5,11 +5,11 @@ import { CurrentWorkspaceMemberNavigationMenuItemFolders } from '@/navigation-me import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; export const CurrentWorkspaceMemberNavigationMenuItemFoldersDispatcher = () => { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); - if (isNavigationMenuItemEnabled) { + if (isNavigationMenuItemEditingEnabled) { return ; } diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolderContentDispatcher.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolderContentDispatcher.tsx index ca4bb7e7bc..b4fa539e62 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolderContentDispatcher.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolderContentDispatcher.tsx @@ -20,11 +20,11 @@ export const NavigationMenuItemFolderContentDispatcherEffect = ({ favorites, navigationMenuItems, }: NavigationMenuItemFolderContentDispatcherEffectProps) => { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); - if (isNavigationMenuItemEnabled && isDefined(navigationMenuItems)) { + if (isNavigationMenuItemEditingEnabled && isDefined(navigationMenuItems)) { return ( { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); - if (isNavigationMenuItemEnabled) { + if (isNavigationMenuItemEditingEnabled) { return ; } diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx index f83a44c6ee..8ebdd7b442 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx @@ -1,5 +1,5 @@ -import { useRecoilValue } from 'recoil'; import styled from '@emotion/styled'; +import { useRecoilValue } from 'recoil'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder'; @@ -31,8 +31,8 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => { ); const { favoritesByFolder } = useFavoritesByFolder(); const { navigationMenuItemsByFolder } = useNavigationMenuItemsByFolder(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const openedFavoriteFolder = favoritesByFolder.find( @@ -43,7 +43,7 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => { (f) => f.id === currentNavigationMenuItemFolderId, ); - const openedFolder = isNavigationMenuItemEnabled + const openedFolder = isNavigationMenuItemEditingEnabled ? openedNavigationMenuItemFolder : openedFavoriteFolder; @@ -59,7 +59,7 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => { - {isNavigationMenuItemEnabled ? ( + {isNavigationMenuItemEditingEnabled ? ( {openedFolder ? ( { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const [isDragging, setIsDragging] = useState(false); const [sourceDroppableId, setSourceDroppableId] = useState( @@ -42,7 +42,7 @@ export const NavbarDragProvider = ({ children }: NavbarDragProviderProps) => { setIsDragging(false); setSourceDroppableId(null); - if (isNavigationMenuItemEnabled) { + if (isNavigationMenuItemEditingEnabled) { const isWorkspaceDrop = (result.source?.droppableId?.startsWith('workspace-') ?? false) && (result.destination?.droppableId?.startsWith('workspace-') ?? false); diff --git a/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx b/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx index d8af3b7765..c1f3054147 100644 --- a/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx +++ b/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx @@ -35,8 +35,8 @@ type PageDragDropProviderProps = { export const PageDragDropProvider = ({ children, }: PageDragDropProviderProps) => { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const [isDragging, setIsDragging] = useState(false); const [sourceDroppableId, setSourceDroppableId] = useState( @@ -136,7 +136,7 @@ export const PageDragDropProvider = ({ return; } - if (isNavigationMenuItemEnabled) { + if (isNavigationMenuItemEditingEnabled) { const isWorkspaceDrop = isWorkspaceDroppableId(result.source?.droppableId) && isWorkspaceDroppableId(result.destination?.droppableId); diff --git a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx index aba99eb61b..473aca2c27 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx @@ -1,3 +1,5 @@ +import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; +import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { ObjectIconWithViewOverlay } from '@/navigation-menu-item/components/ObjectIconWithViewOverlay'; import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors'; @@ -6,6 +8,11 @@ import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/l import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { NavigationDrawerItemsCollapsableContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsableContainer'; +import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; +import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment'; +import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; +import { coreViewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreViewsFromObjectMetadataItemFamilySelector'; import { ViewKey } from '@/views/types/ViewKey'; import { useTheme } from '@emotion/react'; import { useLocation } from 'react-router-dom'; @@ -13,6 +20,7 @@ import { useRecoilValue } from 'recoil'; import { AppPath } from 'twenty-shared/types'; import { getAppPath, isDefined } from 'twenty-shared/utils'; import { Avatar, useIcons } from 'twenty-ui/display'; +import { AnimatedExpandableContainer } from 'twenty-ui/layout'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -45,6 +53,17 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ lastVisitedViewPerObjectMetadataItemState, ); + const views = useRecoilValue( + coreViewsFromObjectMetadataItemFamilySelector({ + objectMetadataItemId: objectMetadataItem.id, + }), + ); + + const contextStoreCurrentViewId = useRecoilComponentValue( + contextStoreCurrentViewIdComponentState, + MAIN_CONTEXT_STORE_INSTANCE_ID, + ); + const lastVisitedViewId = lastVisitedViewPerObjectMetadataItem?.[objectMetadataItem.id]; @@ -136,6 +155,60 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ ? objectMetadataItem.labelSingular : undefined; + const shouldSubItemsBeDisplayed = + !isNavigationMenuItemEditingEnabled && isActive && views.length > 1; + + const sortedObjectMetadataViews = [...views].sort( + (viewA, viewB) => viewA.position - viewB.position, + ); + + const selectedSubItemIndex = sortedObjectMetadataViews.findIndex( + (view) => contextStoreCurrentViewId === view.id, + ); + + const subItemArrayLength = sortedObjectMetadataViews.length; + + if (!isNavigationMenuItemEditingEnabled) { + return ( + + + + {sortedObjectMetadataViews.map((view, index) => ( + + ))} + + + ); + } + return ( { const { workspaceFavoritesObjectMetadataItems } = useWorkspaceFavorites(); const { workspaceNavigationMenuItemsObjectMetadataItems } = useWorkspaceNavigationMenuItems(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const { @@ -52,7 +52,7 @@ export const NavigationDrawerOpenedSection = () => { return; } - const workspaceItemsToExclude = isNavigationMenuItemEnabled + const workspaceItemsToExclude = isNavigationMenuItemEditingEnabled ? workspaceNavigationMenuItemsObjectMetadataItems : workspaceFavoritesObjectMetadataItems; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useDeleteManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useDeleteManyRecords.ts index 0a9fd77ae2..a838eb178e 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useDeleteManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useDeleteManyRecords.ts @@ -1,4 +1,5 @@ import { triggerUpdateRecordOptimisticEffectByBatch } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffectByBatch'; +import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; import { apiConfigState } from '@/client-config/states/apiConfigState'; import { useRemoveNavigationMenuItemByTargetRecordId } from '@/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; @@ -15,12 +16,9 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; import { getDeleteManyRecordsMutationResponseField } from '@/object-record/utils/getDeleteManyRecordsMutationResponseField'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { sleep } from '~/utils/sleep'; type useDeleteManyRecordProps = { @@ -60,9 +58,7 @@ export const useDeleteManyRecords = ({ const { objectMetadataItems } = useObjectMetadataItems(); const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); const { refetchAggregateQueries } = useRefetchAggregateQueries(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); + const { removeNavigationMenuItemsByTargetRecordIds } = useRemoveNavigationMenuItemByTargetRecordId(); @@ -231,9 +227,7 @@ export const useDeleteManyRecords = ({ objectMetadataNamePlural: objectMetadataItem.namePlural, }); - if (isNavigationMenuItemEnabled) { - removeNavigationMenuItemsByTargetRecordIds(recordIdsToDelete); - } + removeNavigationMenuItemsByTargetRecordIds(recordIdsToDelete); dispatchObjectRecordOperationBrowserEvent({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/hooks/useDestroyManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useDestroyManyRecords.ts index d434015628..086b1ebb4d 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useDestroyManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useDestroyManyRecords.ts @@ -1,6 +1,8 @@ import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect'; import { triggerDestroyRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect'; +import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; import { apiConfigState } from '@/client-config/states/apiConfigState'; +import { useRemoveNavigationMenuItemByTargetRecordId } from '@/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; @@ -11,12 +13,8 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; import { getDestroyManyRecordsMutationResponseField } from '@/object-record/utils/getDestroyManyRecordsMutationResponseField'; -import { useRemoveNavigationMenuItemByTargetRecordId } from '@/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useRecoilValue } from 'recoil'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { capitalize, isDefined } from 'twenty-shared/utils'; import { sleep } from '~/utils/sleep'; @@ -55,9 +53,6 @@ export const useDestroyManyRecords = ({ const { objectMetadataItems } = useObjectMetadataItems(); const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); const { refetchAggregateQueries } = useRefetchAggregateQueries(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); const { removeNavigationMenuItemsByTargetRecordIds } = useRemoveNavigationMenuItemByTargetRecordId(); @@ -152,9 +147,7 @@ export const useDestroyManyRecords = ({ objectMetadataNamePlural: objectMetadataItem.namePlural, }); - if (isNavigationMenuItemEnabled) { - removeNavigationMenuItemsByTargetRecordIds(recordIdsToDestroy); - } + removeNavigationMenuItemsByTargetRecordIds(recordIdsToDestroy); dispatchObjectRecordOperationBrowserEvent({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/hooks/useIncrementalDeleteManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useIncrementalDeleteManyRecords.ts index e8a823bb0b..607f0a99aa 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useIncrementalDeleteManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useIncrementalDeleteManyRecords.ts @@ -1,4 +1,5 @@ import { triggerUpdateRecordOptimisticEffectByBatch } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffectByBatch'; +import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; import { useRemoveNavigationMenuItemByTargetRecordId } from '@/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; @@ -16,11 +17,8 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { dispatchObjectRecordOperationBrowserEvent } from '@/browser-event/utils/dispatchObjectRecordOperationBrowserEvent'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; -import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { sleep } from '~/utils/sleep'; const DEFAULT_DELAY_BETWEEN_MUTATIONS_MS = 50; @@ -64,9 +62,6 @@ export const useIncrementalDeleteManyRecords = ({ const { objectMetadataItems } = useObjectMetadataItems(); const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); const { refetchAggregateQueries } = useRefetchAggregateQueries(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, - ); const { removeNavigationMenuItemsByTargetRecordIds } = useRemoveNavigationMenuItemByTargetRecordId(); @@ -244,9 +239,7 @@ export const useIncrementalDeleteManyRecords = ({ objectMetadataNamePlural: objectMetadataItem.namePlural, }); - if (isNavigationMenuItemEnabled) { - removeNavigationMenuItemsByTargetRecordIds(allDeletedRecordIds); - } + removeNavigationMenuItemsByTargetRecordIds(allDeletedRecordIds); dispatchObjectRecordOperationBrowserEvent({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx index 87d37fe72b..3c9ad90f7f 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx @@ -23,8 +23,8 @@ import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const PrefetchRunFavoriteQueriesEffect = () => { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const showAuthModal = useShowAuthModal(); const isSettingsPage = useIsSettingsPage(); @@ -64,7 +64,7 @@ export const PrefetchRunFavoriteQueriesEffect = () => { showAuthModal || isSettingsPage || !isWorkspaceActive || - isNavigationMenuItemEnabled, + isNavigationMenuItemEditingEnabled, }); const { records: favoriteFolders } = useFindManyRecords({ @@ -75,7 +75,7 @@ export const PrefetchRunFavoriteQueriesEffect = () => { showAuthModal || isSettingsPage || !isWorkspaceActive || - isNavigationMenuItemEnabled, + isNavigationMenuItemEditingEnabled, }); const setPrefetchFavoritesState = useRecoilCallback( diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx index ff142a427e..9eeaec0484 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx @@ -18,8 +18,8 @@ import { import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const PrefetchRunNavigationMenuItemQueriesEffect = () => { - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); const showAuthModal = useShowAuthModal(); @@ -37,7 +37,7 @@ export const PrefetchRunNavigationMenuItemQueriesEffect = () => { showAuthModal || isSettingsPage || !isWorkspaceActive || - !isNavigationMenuItemEnabled, + !isNavigationMenuItemEditingEnabled, fetchPolicy: 'cache-and-network', }); diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx index c0bae306f1..589b48f825 100644 --- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx +++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx @@ -1,6 +1,5 @@ import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite'; import { useFavorites } from '@/favorites/hooks/useFavorites'; -import { useCreateNavigationMenuItem } from '@/navigation-menu-item/hooks/useCreateNavigationMenuItem'; import { usePrefetchedNavigationMenuItemsData } from '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData'; import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; @@ -24,8 +23,8 @@ import { import { MenuItem } from 'twenty-ui/navigation'; import { FeatureFlagKey, - ViewVisibility, PermissionFlagType, + ViewVisibility, } from '~/generated-metadata/graphql'; type ViewPickerOptionDropdownProps = { @@ -63,10 +62,9 @@ export const ViewPickerOptionDropdown = ({ const { sortedFavorites: favorites } = useFavorites(); const { createFavorite } = useCreateFavorite(); - const isNavigationMenuItemEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_ENABLED, + const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); - const { createNavigationMenuItem } = useCreateNavigationMenuItem(); const { navigationMenuItems, currentWorkspaceMemberId } = usePrefetchedNavigationMenuItemsData(); @@ -75,7 +73,7 @@ export const ViewPickerOptionDropdown = ({ const canEditView = hasViewsPermission || view.visibility === ViewVisibility.UNLISTED; - const isFavorite = isNavigationMenuItemEnabled + const isFavorite = isNavigationMenuItemEditingEnabled ? navigationMenuItems.some( (item) => item.viewId === view.id && @@ -94,11 +92,7 @@ export const ViewPickerOptionDropdown = ({ const handleAddToFavorites = () => { if (!isFavorite) { - if (isNavigationMenuItemEnabled) { - createNavigationMenuItem(view, 'view'); - } else { - createFavorite(view, 'view'); - } + createFavorite(view, 'view'); } else { setViewPickerReferenceViewId(view.id); setViewPickerMode('favorite-folders-picker'); diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 3499d92051..a2e9cde2a7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -473,19 +473,14 @@ export class ObjectMetadataService extends TypeOrmQueryService