From 10bc82bce810b37688641da55ebe5c0211553cd8 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:00:50 +0100 Subject: [PATCH 1/8] Simplify last visited object --- .../components/MainContextStoreProvider.tsx | 17 +---- .../MainContextStoreProviderEffect.tsx | 42 +++++------ .../hooks/useDefaultHomePagePath.ts | 7 +- .../hooks/useLastVisitedObjectMetadataItem.ts | 70 ------------------- .../navigation/hooks/useLastVisitedView.ts | 33 +-------- .../navigation/hooks/useOpenSettings.ts | 6 +- .../useSetLastVisitedObjectMetadataId.ts | 35 ++++++++++ ...tVisitedViewForObjectMetadataNamePlural.ts | 44 ++++++++++++ .../lastVisitedObjectMetadataItemIdState.ts | 7 +- ...stVisitedViewPerObjectMetadataItemState.ts | 16 +++-- ...isitedObjectMetadataItemIdStateSelector.ts | 24 ------- ...dViewPerObjectMetadataItemStateSelector.ts | 34 --------- ...igationDrawerItemForObjectMetadataItem.tsx | 27 ++++--- .../components/RecordIndexContainer.tsx | 2 + .../components/SettingsObjectSummaryCard.tsx | 4 -- .../components/tabs/ObjectSettings.tsx | 27 +------ 16 files changed, 139 insertions(+), 256 deletions(-) delete mode 100644 packages/twenty-front/src/modules/navigation/hooks/useLastVisitedObjectMetadataItem.ts create mode 100644 packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts create mode 100644 packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts delete mode 100644 packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedObjectMetadataItemIdStateSelector.ts delete mode 100644 packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedViewPerObjectMetadataItemStateSelector.ts diff --git a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx index ff78e61273fe..217715fac6d5 100644 --- a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx +++ b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx @@ -1,10 +1,7 @@ import { MainContextStoreProviderEffect } from '@/context-store/components/MainContextStoreProviderEffect'; import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; -import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { AppPath } from '@/types/AppPath'; -import { View } from '@/views/types/View'; import { isNonEmptyString } from '@sniptt/guards'; import { useParams, useSearchParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; @@ -14,7 +11,6 @@ import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation'; const getViewId = ( viewIdFromQueryParams: string | null, - indexView?: View, lastVisitedViewId?: string, ) => { if (isDefined(viewIdFromQueryParams)) { @@ -25,10 +21,6 @@ const getViewId = ( return lastVisitedViewId; } - if (isDefined(indexView)) { - return indexView.id; - } - return undefined; }; @@ -48,8 +40,6 @@ export const MainContextStoreProvider = () => { const [searchParams] = useSearchParams(); const viewIdQueryParam = searchParams.get('viewId'); - const { records: views } = usePrefetchedData(PrefetchKey.AllViews); - const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItem = objectMetadataItems.find( @@ -62,12 +52,7 @@ export const MainContextStoreProvider = () => { objectMetadataItem?.namePlural ?? '', ); - const viewsOnCurrentObject = views.filter( - (view) => view.objectMetadataId === objectMetadataItem?.id, - ); - const indexView = viewsOnCurrentObject.find((view) => view.key === 'INDEX'); - - const viewId = getViewId(viewIdQueryParam, indexView, lastVisitedViewId); + const viewId = getViewId(viewIdQueryParam, lastVisitedViewId); const mainContextStoreComponentInstanceId = `${pageName}-${objectMetadataItem?.namePlural}-${viewId}`; diff --git a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx index a8626f4b74ef..e8cd2a342f28 100644 --- a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx +++ b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx @@ -1,8 +1,8 @@ import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState'; import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { mainContextStoreComponentInstanceIdState } from '@/context-store/states/mainContextStoreComponentInstanceId'; -import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem'; -import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; +import { useSetLastVisitedObjectMetadataId } from '@/navigation/hooks/useSetLastVisitedObjectMetadataId'; +import { useSetLastVisitedViewForObjectMetadataNamePlural } from '@/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; import { useEffect } from 'react'; @@ -17,20 +17,20 @@ export const MainContextStoreProviderEffect = ({ viewId: string; objectMetadataItem: ObjectMetadataItem; }) => { + console.log( + 'mainContextStoreComponentInstanceIdToSet', + mainContextStoreComponentInstanceIdToSet, + ); const [ mainContextStoreComponentInstanceId, setMainContextStoreComponentInstanceId, ] = useRecoilState(mainContextStoreComponentInstanceIdState); - const { getLastVisitedViewIdFromObjectNamePlural, setLastVisitedView } = - useLastVisitedView(); + const { setLastVisitedViewForObjectMetadataNamePlural } = + useSetLastVisitedViewForObjectMetadataNamePlural(); - const { lastVisitedObjectMetadataItemId, setLastVisitedObjectMetadataItem } = - useLastVisitedObjectMetadataItem(); - - const lastVisitedViewId = getLastVisitedViewIdFromObjectNamePlural( - objectMetadataItem.namePlural, - ); + const { setLastVisitedObjectMetadataId } = + useSetLastVisitedObjectMetadataId(); const [contextStoreCurrentViewId, setContextStoreCurrentViewId] = useRecoilComponentStateV2( @@ -60,16 +60,14 @@ export const MainContextStoreProviderEffect = ({ ); } - if (viewId !== lastVisitedViewId) { - setLastVisitedView({ - objectNamePlural: objectMetadataItem.namePlural, - viewId: viewId, - }); - } + setLastVisitedViewForObjectMetadataNamePlural({ + objectNamePlural: objectMetadataItem.namePlural, + viewId: viewId, + }); - if (objectMetadataItem.id !== lastVisitedObjectMetadataItemId) { - setLastVisitedObjectMetadataItem(objectMetadataItem.namePlural); - } + setLastVisitedObjectMetadataId({ + objectMetadataItemId: objectMetadataItem.id, + }); if (contextStoreCurrentViewId !== viewId) { setContextStoreCurrentViewId(viewId); @@ -77,16 +75,14 @@ export const MainContextStoreProviderEffect = ({ }, [ contextStoreCurrentObjectMetadataId, contextStoreCurrentViewId, - lastVisitedObjectMetadataItemId, - lastVisitedViewId, mainContextStoreComponentInstanceId, mainContextStoreComponentInstanceIdToSet, objectMetadataItem, objectMetadataItem.namePlural, setContextStoreCurrentObjectMetadataId, setContextStoreCurrentViewId, - setLastVisitedObjectMetadataItem, - setLastVisitedView, + setLastVisitedObjectMetadataId, + setLastVisitedViewForObjectMetadataNamePlural, setMainContextStoreComponentInstanceId, viewId, ]); diff --git a/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts b/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts index b3fa4412d0f5..fe8d45a6c60c 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts @@ -1,5 +1,5 @@ import { currentUserState } from '@/auth/states/currentUserState'; -import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem'; +import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; import { ObjectPathInfo } from '@/navigation/types/ObjectPathInfo'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; @@ -16,8 +16,9 @@ export const useDefaultHomePagePath = () => { const { activeObjectMetadataItems, alphaSortedActiveObjectMetadataItems } = useFilteredObjectMetadataItems(); const { records: views } = usePrefetchedData(PrefetchKey.AllViews); - const { lastVisitedObjectMetadataItemId } = - useLastVisitedObjectMetadataItem(); + const lastVisitedObjectMetadataItemId = useRecoilValue( + lastVisitedObjectMetadataItemIdState, + ); const getActiveObjectMetadataItemMatchingId = useCallback( (objectMetadataId: string) => { diff --git a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedObjectMetadataItem.ts b/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedObjectMetadataItem.ts deleted file mode 100644 index e95fa257937e..000000000000 --- a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedObjectMetadataItem.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; -import { lastVisitedObjectMetadataItemIdStateSelector } from '@/navigation/states/selectors/lastVisitedObjectMetadataItemIdStateSelector'; -import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; -import { AppPath } from '@/types/AppPath'; -import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; -import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; -import { isDefined } from 'twenty-shared'; -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -import { getAppPath } from '~/utils/navigation/getAppPath'; - -export const useLastVisitedObjectMetadataItem = () => { - const currentWorkspace = useRecoilValue(currentWorkspaceState); - const scopeId = currentWorkspace?.id ?? ''; - - const lastVisitedObjectMetadataItemIdState = extractComponentState( - lastVisitedObjectMetadataItemIdStateSelector, - scopeId, - ); - - const [lastVisitedObjectMetadataItemId, setLastVisitedObjectMetadataItemId] = - useRecoilState(lastVisitedObjectMetadataItemIdState); - - const { - findActiveObjectMetadataItemByNamePlural, - alphaSortedActiveObjectMetadataItems, - } = useFilteredObjectMetadataItems(); - - const setNavigationMemorizedUrl = useSetRecoilState( - navigationMemorizedUrlState, - ); - - const setFallbackForLastVisitedObjectMetadataItem = ( - objectMetadataItemId: string, - ) => { - const isDeactivateDefault = isDeeplyEqual( - lastVisitedObjectMetadataItemId, - objectMetadataItemId, - ); - - const [newFallbackObjectMetadataItem] = - alphaSortedActiveObjectMetadataItems.filter( - (item) => item.id !== objectMetadataItemId, - ); - - if (isDeactivateDefault) { - setLastVisitedObjectMetadataItemId(newFallbackObjectMetadataItem.id); - setNavigationMemorizedUrl( - getAppPath(AppPath.RecordIndexPage, { - objectNamePlural: newFallbackObjectMetadataItem.namePlural, - }), - ); - } - }; - - const setLastVisitedObjectMetadataItem = (objectNamePlural: string) => { - const fallbackObjectMetadataItem = - findActiveObjectMetadataItemByNamePlural(objectNamePlural); - - if (isDefined(fallbackObjectMetadataItem)) { - setLastVisitedObjectMetadataItemId(fallbackObjectMetadataItem.id); - } - }; - - return { - lastVisitedObjectMetadataItemId, - setLastVisitedObjectMetadataItem, - setFallbackForLastVisitedObjectMetadataItem, - }; -}; diff --git a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts b/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts index ea6d84a312d5..14a8b5ab1b04 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts @@ -1,19 +1,8 @@ -import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; -import { lastVisitedViewPerObjectMetadataItemStateSelector } from '@/navigation/states/selectors/lastVisitedViewPerObjectMetadataItemStateSelector'; +import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; -import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; -import { useRecoilState, useRecoilValue } from 'recoil'; -import { isDefined } from 'twenty-shared'; +import { useRecoilState } from 'recoil'; export const useLastVisitedView = () => { - const currentWorkspace = useRecoilValue(currentWorkspaceState); - const scopeId = currentWorkspace?.id ?? ''; - - const lastVisitedViewPerObjectMetadataItemState = extractComponentState( - lastVisitedViewPerObjectMetadataItemStateSelector, - scopeId, - ); - const [ lastVisitedViewPerObjectMetadataItem, setLastVisitedViewPerObjectMetadataItem, @@ -32,23 +21,6 @@ export const useLastVisitedView = () => { }); }; - const setLastVisitedView = ({ - objectNamePlural, - viewId, - }: { - objectNamePlural: string; - viewId: string; - }) => { - const objectMetadataItem = - findActiveObjectMetadataItemByNamePlural(objectNamePlural); - - if (isDefined(objectMetadataItem)) { - setLastVisitedViewPerObjectMetadataItem({ - [objectMetadataItem.id]: viewId, - }); - } - }; - const getLastVisitedViewIdFromObjectNamePlural = ( objectNamePlural: string, ) => { @@ -65,7 +37,6 @@ export const useLastVisitedView = () => { return lastVisitedViewPerObjectMetadataItem?.[objectMetadataItemId]; }; return { - setLastVisitedView, getLastVisitedViewIdFromObjectNamePlural, getLastVisitedViewIdFromObjectMetadataItemId, setFallbackForLastVisitedView, diff --git a/packages/twenty-front/src/modules/navigation/hooks/useOpenSettings.ts b/packages/twenty-front/src/modules/navigation/hooks/useOpenSettings.ts index 0b06f262fe12..92f85c1e096e 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useOpenSettings.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useOpenSettings.ts @@ -1,12 +1,12 @@ import { currentMobileNavigationDrawerState } from '@/navigation/states/currentMobileNavigationDrawerState'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; -import { useRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; export const useOpenSettingsMenu = () => { - const [, setIsNavigationDrawerExpanded] = useRecoilState( + const setIsNavigationDrawerExpanded = useSetRecoilState( isNavigationDrawerExpandedState, ); - const [, setCurrentMobileNavigationDrawer] = useRecoilState( + const setCurrentMobileNavigationDrawer = useSetRecoilState( currentMobileNavigationDrawerState, ); diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts new file mode 100644 index 000000000000..6a97900013f1 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts @@ -0,0 +1,35 @@ +import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { useRecoilCallback } from 'recoil'; +import { isDefined } from 'twenty-shared'; + +export const useSetLastVisitedObjectMetadataId = () => { + const setLastVisitedObjectMetadataId = useRecoilCallback( + ({ set, snapshot }) => + ({ objectMetadataItemId }: { objectMetadataItemId: string }) => { + const objectMetadataItems = snapshot + .getLoadable(objectMetadataItemsState) + .getValue(); + + const objectMetadataItem = objectMetadataItems.find( + (item) => item.id === objectMetadataItemId, + ); + + const lastVisitedObjectMetadataItemId = snapshot + .getLoadable(lastVisitedObjectMetadataItemIdState) + .getValue(); + + if ( + isDefined(objectMetadataItem) && + lastVisitedObjectMetadataItemId !== objectMetadataItemId + ) { + set(lastVisitedObjectMetadataItemIdState, objectMetadataItemId); + } + }, + [], + ); + + return { + setLastVisitedObjectMetadataId, + }; +}; diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts new file mode 100644 index 000000000000..203a722815ea --- /dev/null +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -0,0 +1,44 @@ +import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; +import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { useRecoilCallback } from 'recoil'; +import { isDefined } from 'twenty-shared'; + +export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { + const setLastVisitedViewForObjectMetadataNamePlural = useRecoilCallback( + ({ set, snapshot }) => + ({ + objectNamePlural, + viewId, + }: { + objectNamePlural: string; + viewId: string; + }) => { + const objectMetadataItems = snapshot + .getLoadable(objectMetadataItemsState) + .getValue(); + + const objectMetadataItem = objectMetadataItems.find( + (item) => item.namePlural === objectNamePlural, + ); + + const lastVisitedViewPerObjectMetadataItem = snapshot + .getLoadable(lastVisitedObjectMetadataItemIdState) + .getValue(); + + const lastVisitedViewId = + lastVisitedViewPerObjectMetadataItem?.[objectMetadataItem?.id]; + + if (isDefined(objectMetadataItem) && lastVisitedViewId !== viewId) { + set(lastVisitedViewPerObjectMetadataItemState, { + [objectMetadataItem.id]: viewId, + }); + } + }, + [], + ); + + return { + setLastVisitedViewForObjectMetadataNamePlural, + }; +}; diff --git a/packages/twenty-front/src/modules/navigation/states/lastVisitedObjectMetadataItemIdState.ts b/packages/twenty-front/src/modules/navigation/states/lastVisitedObjectMetadataItemIdState.ts index a615fe1c75fd..b879581ae182 100644 --- a/packages/twenty-front/src/modules/navigation/states/lastVisitedObjectMetadataItemIdState.ts +++ b/packages/twenty-front/src/modules/navigation/states/lastVisitedObjectMetadataItemIdState.ts @@ -1,10 +1,7 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; +import { createState } from 'twenty-ui'; import { localStorageEffect } from '~/utils/recoil-effects'; -export const lastVisitedObjectMetadataItemIdState = createComponentState | null>({ +export const lastVisitedObjectMetadataItemIdState = createState({ key: 'lastVisitedObjectMetadataItemIdState', defaultValue: null, effects: [localStorageEffect()], diff --git a/packages/twenty-front/src/modules/navigation/states/lastVisitedViewPerObjectMetadataItemState.ts b/packages/twenty-front/src/modules/navigation/states/lastVisitedViewPerObjectMetadataItemState.ts index f8f2176b9d6f..a22a42b21eb5 100644 --- a/packages/twenty-front/src/modules/navigation/states/lastVisitedViewPerObjectMetadataItemState.ts +++ b/packages/twenty-front/src/modules/navigation/states/lastVisitedViewPerObjectMetadataItemState.ts @@ -1,9 +1,11 @@ -import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; +import { createState } from 'twenty-ui'; import { localStorageEffect } from '~/utils/recoil-effects'; -export const lastVisitedViewPerObjectMetadataItemState = - createComponentState | null>({ - key: 'lastVisitedViewPerObjectMetadataItemState', - defaultValue: null, - effects: [localStorageEffect()], - }); +export const lastVisitedViewPerObjectMetadataItemState = createState | null>({ + key: 'lastVisitedViewPerObjectMetadataItemState', + defaultValue: null, + effects: [localStorageEffect()], +}); diff --git a/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedObjectMetadataItemIdStateSelector.ts b/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedObjectMetadataItemIdStateSelector.ts deleted file mode 100644 index fde862f47b7f..000000000000 --- a/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedObjectMetadataItemIdStateSelector.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; -import { createComponentSelector } from '@/ui/utilities/state/component-state/utils/createComponentSelector'; - -export const lastVisitedObjectMetadataItemIdStateSelector = - createComponentSelector({ - key: 'lastVisitedObjectMetadataItemIdStateSelector', - get: - ({ scopeId }: { scopeId: string }) => - ({ get }) => { - const state = get(lastVisitedObjectMetadataItemIdState({ scopeId })); - return state?.['last_visited_object'] - ? state['last_visited_object'] - : null; - }, - set: - ({ scopeId }: { scopeId: string }) => - ({ set }, newValue) => { - set(lastVisitedObjectMetadataItemIdState({ scopeId }), { - ...(typeof newValue === 'string' && { - last_visited_object: newValue, - }), - }); - }, - }); diff --git a/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedViewPerObjectMetadataItemStateSelector.ts b/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedViewPerObjectMetadataItemStateSelector.ts deleted file mode 100644 index 425837536688..000000000000 --- a/packages/twenty-front/src/modules/navigation/states/selectors/lastVisitedViewPerObjectMetadataItemStateSelector.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; -import { createComponentSelector } from '@/ui/utilities/state/component-state/utils/createComponentSelector'; -import { isDefined } from 'twenty-shared'; - -export const lastVisitedViewPerObjectMetadataItemStateSelector = - createComponentSelector | null>({ - key: 'lastVisitedViewPerObjectMetadataItemStateSelector', - get: - ({ scopeId }: { scopeId: string }) => - ({ get }) => { - const state = get( - lastVisitedViewPerObjectMetadataItemState({ scopeId }), - ); - - if (isDefined(state?.['last_visited_object'])) { - const { last_visited_object: _last_visited_object, ...rest } = state; - return rest; - } - - return state; - }, - set: - ({ scopeId }: { scopeId: string }) => - ({ set, get }, newValue) => { - const currentLastVisitedViewPerObjectMetadataItems = get( - lastVisitedViewPerObjectMetadataItemStateSelector({ scopeId }), - ); - - set(lastVisitedViewPerObjectMetadataItemState({ scopeId }), { - ...currentLastVisitedViewPerObjectMetadataItems, - ...newValue, - }); - }, - }); 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 29692d18eff2..acb248f2dcc9 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx @@ -1,4 +1,5 @@ -import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; +import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; +import { mainContextStoreComponentInstanceIdState } from '@/context-store/states/mainContextStoreComponentInstanceId'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; @@ -7,9 +8,11 @@ import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/componen 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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { View } from '@/views/types/View'; import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews'; import { useLocation } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { AnimatedExpandableContainer, useIcons } from 'twenty-ui'; import { getAppPath } from '~/utils/navigation/getAppPath'; @@ -27,20 +30,24 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ views, ); - const { getIcon } = useIcons(); - const currentPath = useLocation().pathname; - const { getLastVisitedViewIdFromObjectMetadataItemId } = useLastVisitedView(); + const mainContextStoreComponentInstanceId = useRecoilValue( + mainContextStoreComponentInstanceIdState, + ); - const lastVisitedViewId = getLastVisitedViewIdFromObjectMetadataItemId( - objectMetadataItem.id, + const contextStoreCurrentViewId = useRecoilComponentValueV2( + contextStoreCurrentViewIdComponentState, + mainContextStoreComponentInstanceId, ); - const viewId = lastVisitedViewId ?? objectMetadataViews[0]?.id; + const { getIcon } = useIcons(); + const currentPath = useLocation().pathname; const navigationPath = getAppPath( AppPath.RecordIndexPage, { objectNamePlural: objectMetadataItem.namePlural }, - viewId ? { viewId } : undefined, + contextStoreCurrentViewId + ? { viewId: contextStoreCurrentViewId } + : undefined, ); const isActive = @@ -62,7 +69,7 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ ); const selectedSubItemIndex = sortedObjectMetadataViews.findIndex( - (view) => viewId === view.id, + (view) => contextStoreCurrentViewId === view.id, ); const subItemArrayLength = sortedObjectMetadataViews.length; @@ -93,7 +100,7 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ { objectNamePlural: objectMetadataItem.namePlural }, { viewId: view.id }, )} - active={viewId === view.id} + active={contextStoreCurrentViewId === view.id} subItemState={getNavigationSubItemLeftAdornment({ index, arrayLength: subItemArrayLength, diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 4ec42a25f56c..df2f8b2de7e0 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -187,6 +187,8 @@ export const RecordIndexContainer = () => { FeatureFlagKey.IsCommandMenuV2Enabled, ); + console.log(columnDefinitions); + return ( <> { onEdit(); @@ -57,7 +54,6 @@ export const SettingsObjectSummaryCard = ({ }; const handleDeactivate = () => { - setFallbackForLastVisitedObjectMetadataItem(objectMetadataItemId); setFallbackForLastVisitedView(objectMetadataItemId); onDeactivate(); closeDropdown(); diff --git a/packages/twenty-front/src/modules/settings/data-model/object-details/components/tabs/ObjectSettings.tsx b/packages/twenty-front/src/modules/settings/data-model/object-details/components/tabs/ObjectSettings.tsx index 17112003710f..0a78b2806c77 100644 --- a/packages/twenty-front/src/modules/settings/data-model/object-details/components/tabs/ObjectSettings.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/object-details/components/tabs/ObjectSettings.tsx @@ -3,10 +3,8 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { zodResolver } from '@hookform/resolvers/zod'; import { FormProvider, useForm } from 'react-hook-form'; import { Button, H2Title, IconArchive, Section } from 'twenty-ui'; -import { z, ZodError } from 'zod'; +import { ZodError, z } from 'zod'; -import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem'; -import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem'; import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; import { @@ -17,11 +15,9 @@ import { import { settingsDataModelObjectIdentifiersFormSchema } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm'; import { SettingsDataModelObjectSettingsFormCard } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectSettingsFormCard'; import { settingsUpdateObjectInputSchema } from '@/settings/data-model/validation-schemas/settingsUpdateObjectInputSchema'; -import { AppPath } from '@/types/AppPath'; import { SettingsPath } from '@/types/SettingsPath'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import pick from 'lodash.pick'; @@ -29,7 +25,6 @@ import { useSetRecoilState } from 'recoil'; import { useNavigateSettings } from '~/hooks/useNavigateSettings'; import { updatedObjectNamePluralState } from '~/pages/settings/data-model/states/updatedObjectNamePluralState'; import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils'; -import { getAppPath } from '~/utils/navigation/getAppPath'; const objectEditFormSchema = z .object({}) @@ -63,9 +58,6 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => { ); const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem(); - const { lastVisitedObjectMetadataItemId } = - useLastVisitedObjectMetadataItem(); - const { getLastVisitedViewIdFromObjectMetadataItemId } = useLastVisitedView(); const formConfig = useForm({ mode: 'onTouched', @@ -73,10 +65,6 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => { }); const { isDirty } = formConfig.formState; - const setNavigationMemorizedUrl = useSetRecoilState( - navigationMemorizedUrlState, - ); - const getUpdatePayload = ( formValues: SettingsDataModelObjectEditFormValues, ) => { @@ -143,19 +131,6 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => { formConfig.reset(undefined, { keepValues: true }); - if (lastVisitedObjectMetadataItemId === objectMetadataItem.id) { - const lastVisitedView = getLastVisitedViewIdFromObjectMetadataItemId( - objectMetadataItem.id, - ); - setNavigationMemorizedUrl( - getAppPath( - AppPath.RecordIndexPage, - { objectNamePlural: objectNamePluralForRedirection }, - { viewId: lastVisitedView }, - ), - ); - } - navigate(SettingsPath.ObjectDetail, { objectNamePlural: objectNamePluralForRedirection, }); From 386eeffdac4612990886638e65e6d66e65bc0cf4 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:02:59 +0100 Subject: [PATCH 2/8] Fix --- .../navigation/hooks/useLastVisitedView.ts | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts b/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts index 14a8b5ab1b04..b53bd5e14587 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useLastVisitedView.ts @@ -1,26 +1,15 @@ import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; -import { useRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; export const useLastVisitedView = () => { - const [ - lastVisitedViewPerObjectMetadataItem, - setLastVisitedViewPerObjectMetadataItem, - ] = useRecoilState(lastVisitedViewPerObjectMetadataItemState); + const lastVisitedViewPerObjectMetadataItem = useRecoilValue( + lastVisitedViewPerObjectMetadataItemState, + ); const { findActiveObjectMetadataItemByNamePlural } = useFilteredObjectMetadataItems(); - const setFallbackForLastVisitedView = (objectMetadataItemId: string) => { - /* ...{} allows us to pass value as undefined to remove that particular key - even though param type is of type Record */ - - setLastVisitedViewPerObjectMetadataItem({ - ...{}, - [objectMetadataItemId]: undefined, - }); - }; - const getLastVisitedViewIdFromObjectNamePlural = ( objectNamePlural: string, ) => { @@ -39,6 +28,5 @@ export const useLastVisitedView = () => { return { getLastVisitedViewIdFromObjectNamePlural, getLastVisitedViewIdFromObjectMetadataItemId, - setFallbackForLastVisitedView, }; }; From d6310fb7f55e54f4b2a093975b03bf22ce199a24 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:20:25 +0100 Subject: [PATCH 3/8] Fix --- .../MainContextStoreProviderEffect.tsx | 4 --- ...tVisitedViewForObjectMetadataNamePlural.ts | 11 ++++++- .../components/RecordIndexContainer.tsx | 2 -- .../prefetch/hooks/useLazyPrefetchData.ts | 30 +++++++++++++++++++ .../components/SettingsObjectSummaryCard.tsx | 4 --- 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 packages/twenty-front/src/modules/prefetch/hooks/useLazyPrefetchData.ts diff --git a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx index e8cd2a342f28..28a634a72137 100644 --- a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx +++ b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProviderEffect.tsx @@ -17,10 +17,6 @@ export const MainContextStoreProviderEffect = ({ viewId: string; objectMetadataItem: ObjectMetadataItem; }) => { - console.log( - 'mainContextStoreComponentInstanceIdToSet', - mainContextStoreComponentInstanceIdToSet, - ); const [ mainContextStoreComponentInstanceId, setMainContextStoreComponentInstanceId, diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index 203a722815ea..25aa5b75e76c 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -1,19 +1,28 @@ import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { useLazyPrefetchedData } from '@/prefetch/hooks/useLazyPrefetchData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared'; export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { + const { findManyRecords } = useLazyPrefetchedData(PrefetchKey.AllViews); + const setLastVisitedViewForObjectMetadataNamePlural = useRecoilCallback( ({ set, snapshot }) => - ({ + async ({ objectNamePlural, viewId, }: { objectNamePlural: string; viewId: string; }) => { + console.log('setLastVisitedViewForObjectMetadataNamePlural'); + const views = await findManyRecords(); + + console.log(views); + const objectMetadataItems = snapshot .getLoadable(objectMetadataItemsState) .getValue(); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index df2f8b2de7e0..4ec42a25f56c 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -187,8 +187,6 @@ export const RecordIndexContainer = () => { FeatureFlagKey.IsCommandMenuV2Enabled, ); - console.log(columnDefinitions); - return ( <> ( + prefetchKey: PrefetchKey, + filter?: RecordGqlOperationFilter, +) => { + const { operationSignatureFactory, objectNameSingular } = + PREFETCH_CONFIG[prefetchKey]; + + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular, + }); + + const recordGqlFields = + operationSignatureFactory({ objectMetadataItem }).fields ?? filter; + const { records, findManyRecords } = useLazyFindManyRecords({ + objectNameSingular: objectNameSingular, + recordGqlFields, + }); + + return { + findManyRecords, + records, + }; +}; diff --git a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectSummaryCard.tsx b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectSummaryCard.tsx index 87ab0a5416f7..2673c2e65bbd 100644 --- a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectSummaryCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectSummaryCard.tsx @@ -9,7 +9,6 @@ import { useIcons, } from 'twenty-ui'; -import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { SettingsSummaryCard } from '@/settings/components/SettingsSummaryCard'; import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag'; @@ -43,10 +42,8 @@ export const SettingsObjectSummaryCard = ({ const theme = useTheme(); const { getIcon } = useIcons(); const Icon = getIcon(iconKey); - const objectMetadataItemId = objectMetadataItem.id; const { closeDropdown } = useDropdown(dropdownId); - const { setFallbackForLastVisitedView } = useLastVisitedView(); const handleEdit = () => { onEdit(); @@ -54,7 +51,6 @@ export const SettingsObjectSummaryCard = ({ }; const handleDeactivate = () => { - setFallbackForLastVisitedView(objectMetadataItemId); onDeactivate(); closeDropdown(); }; From 2450f94f740b331f50040236e0bce5b7511d23ba Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:25:17 +0100 Subject: [PATCH 4/8] Fix --- ...stVisitedViewForObjectMetadataNamePlural.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index 25aa5b75e76c..4796b14ac901 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -3,11 +3,14 @@ import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/l import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { useLazyPrefetchedData } from '@/prefetch/hooks/useLazyPrefetchData'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; +import { View } from '@/views/types/View'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared'; export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { - const { findManyRecords } = useLazyPrefetchedData(PrefetchKey.AllViews); + const { records: views, findManyRecords } = useLazyPrefetchedData( + PrefetchKey.AllViews, + ); const setLastVisitedViewForObjectMetadataNamePlural = useRecoilCallback( ({ set, snapshot }) => @@ -18,10 +21,9 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { objectNamePlural: string; viewId: string; }) => { - console.log('setLastVisitedViewForObjectMetadataNamePlural'); - const views = await findManyRecords(); + await findManyRecords(); - console.log(views); + const view = views.find((view: View) => view.id === viewId); const objectMetadataItems = snapshot .getLoadable(objectMetadataItemsState) @@ -31,6 +33,14 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { (item) => item.namePlural === objectNamePlural, ); + if (!isDefined(objectMetadataItem)) { + return; + } + + if (view.objectMetadataId !== objectMetadataItem.id) { + return; + } + const lastVisitedViewPerObjectMetadataItem = snapshot .getLoadable(lastVisitedObjectMetadataItemIdState) .getValue(); From fdbc0630bcae2fa6f60ed6a2a9c1a4728128e29e Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:35:19 +0100 Subject: [PATCH 5/8] Fix --- .../components/MainContextStoreProvider.tsx | 18 +++++++++++++++++- ...stVisitedViewForObjectMetadataNamePlural.ts | 2 +- ...vigationDrawerItemForObjectMetadataItem.tsx | 12 +++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx index 217715fac6d5..5ca07b30b022 100644 --- a/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx +++ b/packages/twenty-front/src/modules/context-store/components/MainContextStoreProvider.tsx @@ -1,7 +1,10 @@ import { MainContextStoreProviderEffect } from '@/context-store/components/MainContextStoreProviderEffect'; import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; +import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { AppPath } from '@/types/AppPath'; +import { View } from '@/views/types/View'; import { isNonEmptyString } from '@sniptt/guards'; import { useParams, useSearchParams } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; @@ -11,6 +14,7 @@ import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation'; const getViewId = ( viewIdFromQueryParams: string | null, + indexView?: View, lastVisitedViewId?: string, ) => { if (isDefined(viewIdFromQueryParams)) { @@ -21,6 +25,10 @@ const getViewId = ( return lastVisitedViewId; } + if (isDefined(indexView)) { + return indexView.id; + } + return undefined; }; @@ -40,6 +48,9 @@ export const MainContextStoreProvider = () => { const [searchParams] = useSearchParams(); const viewIdQueryParam = searchParams.get('viewId'); + // Todo: this is triggering a lot of re-renders as we update the viewFields, we should introduce a state here + const { records: views } = usePrefetchedData(PrefetchKey.AllViews); + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItem = objectMetadataItems.find( @@ -52,7 +63,12 @@ export const MainContextStoreProvider = () => { objectMetadataItem?.namePlural ?? '', ); - const viewId = getViewId(viewIdQueryParam, lastVisitedViewId); + const viewsOnCurrentObject = views.filter( + (view) => view.objectMetadataId === objectMetadataItem?.id, + ); + const indexView = viewsOnCurrentObject.find((view) => view.key === 'INDEX'); + + const viewId = getViewId(viewIdQueryParam, indexView, lastVisitedViewId); const mainContextStoreComponentInstanceId = `${pageName}-${objectMetadataItem?.namePlural}-${viewId}`; diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index 4796b14ac901..d22785843469 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -33,7 +33,7 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { (item) => item.namePlural === objectNamePlural, ); - if (!isDefined(objectMetadataItem)) { + if (!isDefined(objectMetadataItem) || !isDefined(view)) { return; } 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 acb248f2dcc9..b93a9df2c734 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerItemForObjectMetadataItem.tsx @@ -1,5 +1,6 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { mainContextStoreComponentInstanceIdState } from '@/context-store/states/mainContextStoreComponentInstanceId'; +import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; @@ -39,15 +40,20 @@ export const NavigationDrawerItemForObjectMetadataItem = ({ mainContextStoreComponentInstanceId, ); + const lastVisitedViewPerObjectMetadataItem = useRecoilValue( + lastVisitedViewPerObjectMetadataItemState, + ); + + const lastVisitedViewId = + lastVisitedViewPerObjectMetadataItem?.[objectMetadataItem.id]; + const { getIcon } = useIcons(); const currentPath = useLocation().pathname; const navigationPath = getAppPath( AppPath.RecordIndexPage, { objectNamePlural: objectMetadataItem.namePlural }, - contextStoreCurrentViewId - ? { viewId: contextStoreCurrentViewId } - : undefined, + lastVisitedViewId ? { viewId: lastVisitedViewId } : undefined, ); const isActive = From bf0b7704d9e7b95b5993ddc8eebb3432ac955126 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:43:40 +0100 Subject: [PATCH 6/8] Fixe --- .../hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index d22785843469..d1a6333cd8d0 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -54,7 +54,7 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { }); } }, - [], + [findManyRecords, views], ); return { From 7c7abf0d40ac5a7e8dedca4c6fe370bf1810e668 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 15:46:47 +0100 Subject: [PATCH 7/8] Fix --- .../hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index d1a6333cd8d0..762c75b27052 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -1,4 +1,3 @@ -import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { useLazyPrefetchedData } from '@/prefetch/hooks/useLazyPrefetchData'; @@ -42,7 +41,7 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { } const lastVisitedViewPerObjectMetadataItem = snapshot - .getLoadable(lastVisitedObjectMetadataItemIdState) + .getLoadable(lastVisitedViewPerObjectMetadataItemState) .getValue(); const lastVisitedViewId = @@ -50,6 +49,7 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { if (isDefined(objectMetadataItem) && lastVisitedViewId !== viewId) { set(lastVisitedViewPerObjectMetadataItemState, { + ...lastVisitedViewPerObjectMetadataItem, [objectMetadataItem.id]: viewId, }); } From bb9dd4b45e3a1b2655c73216c75dc7bff4ab2c18 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 17 Feb 2025 17:09:47 +0100 Subject: [PATCH 8/8] Fix --- .../hooks/useFilterableFieldMetadataItems.ts | 14 ++++++++ ...eFieldMetadataItemsInRecordIndexContext.ts | 9 ++--- .../components/RecordIndexContainer.tsx | 7 ++-- .../components/ViewBarRecordFilterEffect.tsx | 34 +++++++++++++++---- ...eApplyViewFiltersToCurrentRecordFilters.ts | 10 ++++-- .../pages/object-record/RecordIndexPage.tsx | 3 +- 6 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItems.ts diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItems.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItems.ts new file mode 100644 index 000000000000..244762acc131 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItems.ts @@ -0,0 +1,14 @@ +import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector'; +import { useRecoilValue } from 'recoil'; + +export const useFilterableFieldMetadataItems = ( + objectMetadataItemId: string, +) => { + const filterableFieldMetadataItems = useRecoilValue( + availableFieldMetadataItemsForFilterFamilySelector({ + objectMetadataItemId, + }), + ); + + return { filterableFieldMetadataItems }; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext.ts index dc977b1b5279..7475f6197cf2 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext.ts @@ -1,14 +1,11 @@ -import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector'; +import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems'; import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; -import { useRecoilValue } from 'recoil'; export const useFilterableFieldMetadataItemsInRecordIndexContext = () => { const { objectMetadataItem } = useRecordIndexContextOrThrow(); - const filterableFieldMetadataItems = useRecoilValue( - availableFieldMetadataItemsForFilterFamilySelector({ - objectMetadataItemId: objectMetadataItem.id, - }), + const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems( + objectMetadataItem.id, ); return { filterableFieldMetadataItems }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 4ec42a25f56c..b2c24e4d7e0f 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -26,7 +26,7 @@ import { RecordIndexActionMenu } from '@/action-menu/components/RecordIndexActio import { ContextStoreCurrentViewTypeEffect } from '@/context-store/components/ContextStoreCurrentViewTypeEffect'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType'; -import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; +import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems'; import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup'; import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect'; import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect'; @@ -180,8 +180,9 @@ export const RecordIndexContainer = () => { contextStoreTargetedRecordsRuleComponentState, ); - const { filterableFieldMetadataItems } = - useFilterableFieldMetadataItemsInRecordIndexContext(); + const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems( + objectMetadataItem.id, + ); const isCommandMenuV2Enabled = useIsFeatureEnabled( FeatureFlagKey.IsCommandMenuV2Enabled, diff --git a/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx index 6eec5272bd9a..09c8ecd84491 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx @@ -1,15 +1,18 @@ -import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; +import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState'; +import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; -import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState'; import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState'; import { View } from '@/views/types/View'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { useEffect } from 'react'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; export const ViewBarRecordFilterEffect = () => { @@ -17,7 +20,20 @@ export const ViewBarRecordFilterEffect = () => { PrefetchKey.AllViews, ); - const currentViewId = useRecoilComponentValueV2(currentViewIdComponentState); + const currentViewId = useRecoilComponentValueV2( + contextStoreCurrentViewIdComponentState, + ); + + const contextStoreCurrentObjectMetadataId = useRecoilComponentValueV2( + contextStoreCurrentObjectMetadataIdComponentState, + ); + + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + + const objectMetadataItem = objectMetadataItems.find( + (objectMetadataItem) => + objectMetadataItem.id === contextStoreCurrentObjectMetadataId, + ); const [ hasInitializedCurrentRecordFilters, @@ -25,7 +41,7 @@ export const ViewBarRecordFilterEffect = () => { ] = useRecoilComponentFamilyStateV2( hasInitializedCurrentRecordFiltersComponentFamilyState, { - viewId: currentViewId, + viewId: currentViewId ?? undefined, }, ); @@ -37,13 +53,18 @@ export const ViewBarRecordFilterEffect = () => { currentRecordFiltersComponentState, ); - const { filterableFieldMetadataItems } = - useFilterableFieldMetadataItemsInRecordIndexContext(); + const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems( + objectMetadataItem?.id, + ); useEffect(() => { if (isDataPrefetched && !hasInitializedCurrentRecordFilters) { const currentView = views.find((view) => view.id === currentViewId); + if (currentView?.objectMetadataId !== objectMetadataItem?.id) { + return; + } + if (isDefined(currentView)) { setCurrentRecordFilters( mapViewFiltersToFilters( @@ -63,6 +84,7 @@ export const ViewBarRecordFilterEffect = () => { currentRecordFilters, hasInitializedCurrentRecordFilters, setHasInitializedCurrentRecordFilters, + objectMetadataItem?.id, ]); return null; diff --git a/packages/twenty-front/src/modules/views/hooks/useApplyViewFiltersToCurrentRecordFilters.ts b/packages/twenty-front/src/modules/views/hooks/useApplyViewFiltersToCurrentRecordFilters.ts index 00d45118ff18..0bec3cb5e6b3 100644 --- a/packages/twenty-front/src/modules/views/hooks/useApplyViewFiltersToCurrentRecordFilters.ts +++ b/packages/twenty-front/src/modules/views/hooks/useApplyViewFiltersToCurrentRecordFilters.ts @@ -1,5 +1,6 @@ -import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; +import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; +import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { ViewFilter } from '@/views/types/ViewFilter'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; @@ -9,8 +10,11 @@ export const useApplyViewFiltersToCurrentRecordFilters = () => { currentRecordFiltersComponentState, ); - const { filterableFieldMetadataItems } = - useFilterableFieldMetadataItemsInRecordIndexContext(); + const { objectMetadataItem } = useRecordIndexContextOrThrow(); + + const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems( + objectMetadataItem.id, + ); const applyViewFiltersToCurrentRecordFilters = ( viewFilters: ViewFilter[], diff --git a/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx b/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx index 36b7925ea2a6..f151507dc6f1 100644 --- a/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx @@ -43,7 +43,8 @@ export const RecordIndexPage = () => { mainContextStoreComponentInstanceId, ); - const recordIndexId = `${objectNamePlural}-${contextStoreCurrentViewId}`; + // Todo: if we want the recordIndexId to contain the viewId, we need to remove the Effects otherwise we will have race condition on view change + const recordIndexId = `${objectNamePlural}`; const { objectNameSingular } = useObjectNameSingularFromPlural({ objectNamePlural,