7336 create contextstore (#7374)
Closes #7336 Create 3 states: - `contextStoreCurrentObjectMetadataIdState`: is set when we change object metadata - `contextStoreCurrentViewIdState`: is set when we change view - `contextStoreTargetedRecordIdsState`: is set when we select records inside a table or a board or when a show page is opened. Is reset when we change view.
This commit is contained in:
@ -0,0 +1,8 @@
|
|||||||
|
import { createState } from 'twenty-ui';
|
||||||
|
|
||||||
|
export const contextStoreCurrentObjectMetadataIdState = createState<
|
||||||
|
string | null
|
||||||
|
>({
|
||||||
|
key: 'contextStoreCurrentObjectMetadataIdState',
|
||||||
|
defaultValue: null,
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from 'twenty-ui';
|
||||||
|
|
||||||
|
export const contextStoreCurrentViewIdState = createState<string | null>({
|
||||||
|
key: 'contextStoreCurrentViewIdState',
|
||||||
|
defaultValue: null,
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from 'twenty-ui';
|
||||||
|
|
||||||
|
export const contextStoreTargetedRecordIdsState = createState<string[]>({
|
||||||
|
key: 'contextStoreTargetedRecordIdsState',
|
||||||
|
defaultValue: [],
|
||||||
|
});
|
||||||
@ -2,6 +2,8 @@ import { useCallback, useEffect } from 'react';
|
|||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState';
|
||||||
|
import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
||||||
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
|
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
|
||||||
@ -129,10 +131,33 @@ export const RecordIndexBoardDataLoaderEffect = ({
|
|||||||
callback: resetRecordSelection,
|
callback: resetRecordSelection,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setContextStoreTargetedRecordIds = useSetRecoilState(
|
||||||
|
contextStoreTargetedRecordIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setContextStoreCurrentObjectMetadataItem = useSetRecoilState(
|
||||||
|
contextStoreCurrentObjectMetadataIdState,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActionBarEntries?.();
|
setActionBarEntries?.();
|
||||||
setContextMenuEntries?.();
|
setContextMenuEntries?.();
|
||||||
}, [setActionBarEntries, setContextMenuEntries]);
|
}, [setActionBarEntries, setContextMenuEntries]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setContextStoreTargetedRecordIds(selectedRecordIds);
|
||||||
|
setContextStoreCurrentObjectMetadataItem(objectMetadataItem?.id);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setContextStoreTargetedRecordIds([]);
|
||||||
|
setContextStoreCurrentObjectMetadataItem(null);
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
objectMetadataItem?.id,
|
||||||
|
selectedRecordIds,
|
||||||
|
setContextStoreCurrentObjectMetadataItem,
|
||||||
|
setContextStoreTargetedRecordIds,
|
||||||
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState';
|
||||||
|
import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState';
|
||||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
|
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
|
||||||
@ -34,6 +36,14 @@ export const RecordIndexTableContainerEffect = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setContextStoreTargetedRecordIds = useSetRecoilState(
|
||||||
|
contextStoreTargetedRecordIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setContextStoreCurrentObjectMetadataItem = useSetRecoilState(
|
||||||
|
contextStoreCurrentObjectMetadataIdState,
|
||||||
|
);
|
||||||
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
@ -111,5 +121,20 @@ export const RecordIndexTableContainerEffect = ({
|
|||||||
);
|
);
|
||||||
}, [setRecordCountInCurrentView, setOnEntityCountChange]);
|
}, [setRecordCountInCurrentView, setOnEntityCountChange]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setContextStoreTargetedRecordIds(selectedRowIds);
|
||||||
|
setContextStoreCurrentObjectMetadataItem(objectMetadataItem?.id);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setContextStoreTargetedRecordIds([]);
|
||||||
|
setContextStoreCurrentObjectMetadataItem(null);
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
objectMetadataItem?.id,
|
||||||
|
selectedRowIds,
|
||||||
|
setContextStoreCurrentObjectMetadataItem,
|
||||||
|
setContextStoreTargetedRecordIds,
|
||||||
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState';
|
||||||
import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem';
|
import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem';
|
||||||
import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView';
|
import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView';
|
||||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||||
@ -7,6 +8,7 @@ import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|||||||
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
||||||
import { isUndefined } from '@sniptt/guards';
|
import { isUndefined } from '@sniptt/guards';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
@ -37,6 +39,9 @@ export const QueryParamsViewIdEffect = () => {
|
|||||||
objectMetadataItemId?.id,
|
objectMetadataItemId?.id,
|
||||||
lastVisitedObjectMetadataItemId,
|
lastVisitedObjectMetadataItemId,
|
||||||
);
|
);
|
||||||
|
const setContextStoreCurrentViewId = useSetRecoilState(
|
||||||
|
contextStoreCurrentViewIdState,
|
||||||
|
);
|
||||||
|
|
||||||
// // TODO: scope view bar per view id if possible
|
// // TODO: scope view bar per view id if possible
|
||||||
// const { resetCurrentView } = useResetCurrentView();
|
// const { resetCurrentView } = useResetCurrentView();
|
||||||
@ -59,6 +64,7 @@ export const QueryParamsViewIdEffect = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setCurrentViewId(lastVisitedViewId);
|
setCurrentViewId(lastVisitedViewId);
|
||||||
|
setContextStoreCurrentViewId(lastVisitedViewId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +79,7 @@ export const QueryParamsViewIdEffect = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setCurrentViewId(viewIdQueryParam);
|
setCurrentViewId(viewIdQueryParam);
|
||||||
|
setContextStoreCurrentViewId(viewIdQueryParam);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +94,13 @@ export const QueryParamsViewIdEffect = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setCurrentViewId(indexView.id);
|
setCurrentViewId(indexView.id);
|
||||||
|
setContextStoreCurrentViewId(indexView.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setContextStoreCurrentViewId(null);
|
||||||
|
};
|
||||||
}, [
|
}, [
|
||||||
currentViewId,
|
currentViewId,
|
||||||
getFiltersFromQueryParams,
|
getFiltersFromQueryParams,
|
||||||
@ -96,6 +108,7 @@ export const QueryParamsViewIdEffect = () => {
|
|||||||
lastVisitedViewId,
|
lastVisitedViewId,
|
||||||
objectMetadataItemId?.id,
|
objectMetadataItemId?.id,
|
||||||
objectNamePlural,
|
objectNamePlural,
|
||||||
|
setContextStoreCurrentViewId,
|
||||||
setCurrentViewId,
|
setCurrentViewId,
|
||||||
setLastVisitedObjectMetadataItem,
|
setLastVisitedObjectMetadataItem,
|
||||||
setLastVisitedView,
|
setLastVisitedView,
|
||||||
|
|||||||
@ -1,19 +1,11 @@
|
|||||||
import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates';
|
import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSetViewInUrl } from '@/views/hooks/useSetViewInUrl';
|
||||||
|
|
||||||
export const useChangeView = (viewBarComponentId?: string) => {
|
export const useChangeView = (viewBarComponentId?: string) => {
|
||||||
const { resetUnsavedViewStates } =
|
const { resetUnsavedViewStates } =
|
||||||
useResetUnsavedViewStates(viewBarComponentId);
|
useResetUnsavedViewStates(viewBarComponentId);
|
||||||
|
|
||||||
const [, setSearchParams] = useSearchParams();
|
const { setViewInUrl } = useSetViewInUrl();
|
||||||
|
|
||||||
const setViewInUrl = (viewId: string) => {
|
|
||||||
setSearchParams(() => {
|
|
||||||
const searchParams = new URLSearchParams();
|
|
||||||
searchParams.set('view', viewId);
|
|
||||||
return searchParams;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeView = async (viewId: string) => {
|
const changeView = async (viewId: string) => {
|
||||||
setViewInUrl(viewId);
|
setViewInUrl(viewId);
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
export const useSetViewInUrl = () => {
|
||||||
|
const [, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
|
const setViewInUrl = (viewId: string) => {
|
||||||
|
setSearchParams(() => {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
searchParams.set('view', viewId);
|
||||||
|
return searchParams;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return { setViewInUrl };
|
||||||
|
};
|
||||||
@ -12,6 +12,7 @@ import { PageTitle } from '@/ui/utilities/page-title/PageTitle';
|
|||||||
import { RecordShowPageWorkflowHeader } from '@/workflow/components/RecordShowPageWorkflowHeader';
|
import { RecordShowPageWorkflowHeader } from '@/workflow/components/RecordShowPageWorkflowHeader';
|
||||||
import { RecordShowPageWorkflowVersionHeader } from '@/workflow/components/RecordShowPageWorkflowVersionHeader';
|
import { RecordShowPageWorkflowVersionHeader } from '@/workflow/components/RecordShowPageWorkflowVersionHeader';
|
||||||
import { RecordShowPageBaseHeader } from '~/pages/object-record/RecordShowPageBaseHeader';
|
import { RecordShowPageBaseHeader } from '~/pages/object-record/RecordShowPageBaseHeader';
|
||||||
|
import { RecordShowPageContextStoreEffect } from '~/pages/object-record/RecordShowPageContextStoreEffect';
|
||||||
import { RecordShowPageHeader } from '~/pages/object-record/RecordShowPageHeader';
|
import { RecordShowPageHeader } from '~/pages/object-record/RecordShowPageHeader';
|
||||||
|
|
||||||
export const RecordShowPage = () => {
|
export const RecordShowPage = () => {
|
||||||
@ -39,6 +40,7 @@ export const RecordShowPage = () => {
|
|||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
<RecordFieldValueSelectorContextProvider>
|
||||||
<RecordValueSetterEffect recordId={objectRecordId} />
|
<RecordValueSetterEffect recordId={objectRecordId} />
|
||||||
|
<RecordShowPageContextStoreEffect recordId={objectRecordId} />
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageTitle title={pageTitle} />
|
<PageTitle title={pageTitle} />
|
||||||
<RecordShowPageHeader
|
<RecordShowPageHeader
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState';
|
||||||
|
import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState';
|
||||||
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
export const RecordShowPageContextStoreEffect = ({
|
||||||
|
recordId,
|
||||||
|
}: {
|
||||||
|
recordId: string;
|
||||||
|
}) => {
|
||||||
|
const setContextStoreTargetedRecordIds = useSetRecoilState(
|
||||||
|
contextStoreTargetedRecordIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setContextStoreCurrentObjectMetadataId = useSetRecoilState(
|
||||||
|
contextStoreCurrentObjectMetadataIdState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { objectNameSingular } = useParams();
|
||||||
|
|
||||||
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
|
objectNameSingular: objectNameSingular ?? '',
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setContextStoreTargetedRecordIds([recordId]);
|
||||||
|
setContextStoreCurrentObjectMetadataId(objectMetadataItem?.id);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setContextStoreTargetedRecordIds([]);
|
||||||
|
setContextStoreCurrentObjectMetadataId(null);
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
recordId,
|
||||||
|
setContextStoreTargetedRecordIds,
|
||||||
|
setContextStoreCurrentObjectMetadataId,
|
||||||
|
objectMetadataItem?.id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user