Migrate record table to scope map (#3363)

* Migrate record table to scope map

* Update record scope id to record id

* Remove todos and fix edit mode

* Fix perf

* Fix tests

* Fix tests

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Thomas Trompette
2024-01-11 17:44:40 +01:00
committed by GitHub
parent 5f0c9f67c9
commit 6bae6fcdce
84 changed files with 713 additions and 1121 deletions

View File

@ -5,24 +5,37 @@ import { renderHook } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope';
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
const recordTableScopeId = 'people';
const recordTableId = 'people';
const onColumnsChange = jest.fn();
const Wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>
<RecordTableScope
recordTableScopeId={recordTableScopeId}
onColumnsChange={onColumnsChange}
>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<MockedProvider addTypename={false}>{children}</MockedProvider>
</SnackBarProviderScope>
</RecordTableScope>
</RecoilRoot>
);
const ObjectNamePluralSetter = ({ children }: { children: ReactNode }) => {
const { setObjectNamePlural } = useRecordTable({ recordTableId });
setObjectNamePlural('people');
return <>{children}</>;
};
const Wrapper = ({ children }: { children: ReactNode }) => {
return (
<RecoilRoot>
<ObjectNamePluralSetter>
<RecordTableScope
recordTableScopeId={getScopeIdFromComponentId(recordTableId) ?? ''}
onColumnsChange={onColumnsChange}
>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<MockedProvider addTypename={false}>{children}</MockedProvider>
</SnackBarProviderScope>
</RecordTableScope>
</ObjectNamePluralSetter>
</RecoilRoot>
);
};
describe('useObjectRecordTable', () => {
it('should skip fetch if currentWorkspace is undefined', async () => {

View File

@ -5,16 +5,15 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
import { turnObjectDropdownFilterIntoQueryFilter } from '@/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { signInBackgroundMockCompanies } from '@/sign-in-background-mock/constants/signInBackgroundMockCompanies';
import { useFindManyRecords } from './useFindManyRecords';
export const useObjectRecordTable = () => {
const {
scopeId: objectNamePlural,
objectNamePlural,
setRecordTableData,
setIsRecordTableInitialLoading,
} = useRecordTable();
@ -30,29 +29,12 @@ export const useObjectRecordTable = () => {
},
);
const {
tableFiltersScopeInjector,
tableSortsScopeInjector,
tableLastRowVisibleScopeInjector,
} = getRecordTableScopeInjector();
const { tableFiltersState, tableSortsState, tableLastRowVisibleState } =
useRecordTableStates();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const tableFiltersState = injectStateWithRecordTableScopeId(
tableFiltersScopeInjector,
);
const tableSortsState = injectStateWithRecordTableScopeId(
tableSortsScopeInjector,
);
const tableLastRowVisibleState = injectStateWithRecordTableScopeId(
tableLastRowVisibleScopeInjector,
);
const tableFilters = useRecoilValue(tableFiltersState);
const tableSorts = useRecoilValue(tableSortsState);
const setLastRowVisible = useSetRecoilState(tableLastRowVisibleState);
const tableFilters = useRecoilValue(tableFiltersState());
const tableSorts = useRecoilValue(tableSortsState());
const setLastRowVisible = useSetRecoilState(tableLastRowVisibleState());
const requestFilters = turnObjectDropdownFilterIntoQueryFilter(
tableFilters,

View File

@ -8,10 +8,8 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { useExecuteQuickActionOnOneRecord } from '@/object-record/hooks/useExecuteQuickActionOnOneRecord';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import {
IconCheckbox,
IconClick,
@ -25,55 +23,37 @@ import {
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
import { ContextMenuEntry } from '@/ui/navigation/context-menu/types/ContextMenuEntry';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
type useRecordTableContextMenuEntriesProps = {
recordTableScopeId?: string;
objectNamePlural: string;
recordTableId: string;
};
// TODO: refactor this
export const useRecordTableContextMenuEntries = (
props?: useRecordTableContextMenuEntriesProps,
props: useRecordTableContextMenuEntriesProps,
) => {
const scopeId = useAvailableScopeIdOrThrow(
RecordTableScopeInternalContext,
props?.recordTableScopeId,
);
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
const { selectedRowIdsScopeInjector } = getRecordTableScopeInjector();
const {
injectSelectorWithRecordTableScopeId,
injectSelectorSnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates(scopeId);
const selectedRowIdsSelector = injectSelectorWithRecordTableScopeId(
selectedRowIdsScopeInjector,
);
const { selectedRowIdsSelector } = useRecordTableStates(props?.recordTableId);
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
const { resetTableRowSelection } = useRecordTable({
recordTableScopeId: scopeId,
recordTableId: props?.recordTableId,
});
const objectNamePlural = scopeId;
const { objectNameSingular } = useObjectNameSingularFromPlural({
objectNamePlural,
objectNamePlural: props.objectNamePlural,
});
const { createFavorite, favorites, deleteFavorite } = useFavorites();
const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => {
const selectedRowIds = injectSelectorSnapshotValueWithRecordTableScopeId(
snapshot,
selectedRowIdsScopeInjector,
);
const selectedRowIds = getSnapshotValue(snapshot, selectedRowIdsSelector);
const selectedRowId = selectedRowIds.length === 1 ? selectedRowIds[0] : '';
@ -107,31 +87,24 @@ export const useRecordTableContextMenuEntries = (
const handleDeleteClick = useRecoilCallback(
({ snapshot }) =>
async () => {
const rowIdsToDelete =
injectSelectorSnapshotValueWithRecordTableScopeId(
snapshot,
selectedRowIdsScopeInjector,
);
const rowIdsToDelete = getSnapshotValue(
snapshot,
selectedRowIdsSelector,
);
resetTableRowSelection();
await deleteManyRecords(rowIdsToDelete);
},
[
deleteManyRecords,
injectSelectorSnapshotValueWithRecordTableScopeId,
resetTableRowSelection,
selectedRowIdsScopeInjector,
],
[deleteManyRecords, resetTableRowSelection, selectedRowIdsSelector],
);
const handleExecuteQuickActionOnClick = useRecoilCallback(
({ snapshot }) =>
async () => {
const rowIdsToExecuteQuickActionOn =
injectSelectorSnapshotValueWithRecordTableScopeId(
snapshot,
selectedRowIdsScopeInjector,
);
const rowIdsToExecuteQuickActionOn = getSnapshotValue(
snapshot,
selectedRowIdsSelector,
);
resetTableRowSelection();
await Promise.all(
@ -142,9 +115,8 @@ export const useRecordTableContextMenuEntries = (
},
[
executeQuickActionOnOneRecord,
injectSelectorSnapshotValueWithRecordTableScopeId,
resetTableRowSelection,
selectedRowIdsScopeInjector,
selectedRowIdsSelector,
],
);
@ -152,8 +124,9 @@ export const useRecordTableContextMenuEntries = (
'IS_QUICK_ACTIONS_ENABLED',
);
const openCreateActivityDrawer =
useOpenCreateActivityDrawerForSelectedRowIds(scopeId);
const openCreateActivityDrawer = useOpenCreateActivityDrawerForSelectedRowIds(
props.recordTableId,
);
return {
setContextMenuEntries: useCallback(() => {