Fix latest visited view (#10158)

Fixes https://github.com/twentyhq/twenty/issues/9772

In this PR:
- the root cause of the issue that the ContextStoreViewIdEffect was not
filtering the views on objectMetadata properly
- I'm also deleting some over complex in the latestVisited view logic
- Duplicated logic between ContextStoreViewIdEffect and
ViewBarViewIdEffect, see my comment
This commit is contained in:
Charles Bochet
2025-02-13 00:52:04 +01:00
committed by GitHub
parent 8f69352d17
commit 466f8c733f
9 changed files with 237 additions and 290 deletions

View File

@ -1,120 +1,35 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem';
import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView';
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { mainContextStoreComponentInstanceIdState } from '@/context-store/states/mainContextStoreComponentInstanceId';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
import { isUndefined } from '@sniptt/guards';
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
// TODO: This whole code should be removed. currentViewId should be used directly to set the mainContextStore
// and viewbar / view tooling should be updated to use that state contextStore state directly.
export const QueryParamsViewIdEffect = () => {
const { getFiltersFromQueryParams, viewIdQueryParam } =
useViewFromQueryParams();
// TODO: fix this implicit hack
const { instanceId: objectNamePlural } = useGetCurrentView();
const [currentViewId, setCurrentViewId] = useRecoilComponentStateV2(
currentViewIdComponentState,
);
const { viewsOnCurrentObject } = useGetCurrentView();
const { findObjectMetadataItemByNamePlural } =
useFilteredObjectMetadataItems();
const objectMetadataItemId =
findObjectMetadataItemByNamePlural(objectNamePlural);
const { getLastVisitedViewIdFromObjectNamePlural, setLastVisitedView } =
useLastVisitedView();
const { lastVisitedObjectMetadataItemId, setLastVisitedObjectMetadataItem } =
useLastVisitedObjectMetadataItem();
const lastVisitedViewId =
getLastVisitedViewIdFromObjectNamePlural(objectNamePlural);
const isLastVisitedObjectMetadataItemDifferent = !isDeeplyEqual(
objectMetadataItemId?.id,
lastVisitedObjectMetadataItemId,
const mainContextStoreComponentInstanceId = useRecoilValue(
mainContextStoreComponentInstanceIdState,
);
const setContextStoreCurrentViewId = useSetRecoilComponentStateV2(
const contextStoreCurrentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
mainContextStoreComponentInstanceId,
);
// // TODO: scope view bar per view id if possible
// const { resetCurrentView } = useResetCurrentView();
// useEffect(() => {
// if (isDefined(currentViewId)) {
// resetCurrentView();
// }
// }, [resetCurrentView, currentViewId]);
useEffect(() => {
const indexView = viewsOnCurrentObject.find((view) => view.key === 'INDEX');
if (isUndefined(viewIdQueryParam) && isDefined(lastVisitedViewId)) {
if (isLastVisitedObjectMetadataItemDifferent) {
setLastVisitedObjectMetadataItem(objectNamePlural);
setLastVisitedView({
objectNamePlural,
viewId: lastVisitedViewId,
});
if (isDefined(contextStoreCurrentViewId)) {
if (currentViewId !== contextStoreCurrentViewId) {
setCurrentViewId(contextStoreCurrentViewId);
}
setCurrentViewId(lastVisitedViewId);
setContextStoreCurrentViewId(lastVisitedViewId);
return;
}
if (isDefined(viewIdQueryParam)) {
if (isLastVisitedObjectMetadataItemDifferent) {
setLastVisitedObjectMetadataItem(objectNamePlural);
}
if (!isDeeplyEqual(viewIdQueryParam, lastVisitedViewId)) {
setLastVisitedView({
objectNamePlural,
viewId: viewIdQueryParam,
});
}
setCurrentViewId(viewIdQueryParam);
setContextStoreCurrentViewId(viewIdQueryParam);
return;
}
if (isDefined(indexView)) {
if (isLastVisitedObjectMetadataItemDifferent) {
setLastVisitedObjectMetadataItem(objectNamePlural);
}
if (!isDeeplyEqual(indexView.id, lastVisitedViewId)) {
setLastVisitedView({
objectNamePlural,
viewId: indexView.id,
});
}
setCurrentViewId(indexView.id);
setContextStoreCurrentViewId(indexView.id);
return;
}
return () => {
setContextStoreCurrentViewId(null);
};
}, [
currentViewId,
getFiltersFromQueryParams,
isLastVisitedObjectMetadataItemDifferent,
lastVisitedViewId,
objectMetadataItemId?.id,
objectNamePlural,
setContextStoreCurrentViewId,
setCurrentViewId,
setLastVisitedObjectMetadataItem,
setLastVisitedView,
viewIdQueryParam,
viewsOnCurrentObject,
]);
}, [contextStoreCurrentViewId, currentViewId, setCurrentViewId]);
return <></>;
};