2357 Refactor RecordTable to use the new scope architecture (#2407)

* create RecordTableScope

* use RecordTableScope

* working on useRecordTable hook

* add RecordTableScope to company-table

* add RecordTableScope to person-table

* add filter state and sort state

* add useSetRecordTableData to useRecordTable

* wip

* add setRecordTableData to useRecordTable

* update in RecordTableEffect

* fix bug

* getting rid of unnecessary context and hooks

* remove console.log

* wip

* fix bug by creating an init effect

* fix viewbar not in scope in company and people tables

* wip

* updating useRecordTable to use internal hooks

* updating useRecordTable to use internal hooks

* updating useRecordTable to use internal hooks

* updating useRecordTable to use internal hooks

* modified according to comments
This commit is contained in:
bosiraphael
2023-11-09 17:45:58 +01:00
committed by GitHub
parent 0d4949484c
commit 588091d3dd
93 changed files with 871 additions and 875 deletions

View File

@ -11,7 +11,7 @@ import {
} from '@/ui/display/icon'; } from '@/ui/display/icon';
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState'; import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
import { useResetTableRowSelection } from '@/ui/object/record-table/hooks/useResetTableRowSelection'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector'; import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState'; import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
import { import {
@ -30,7 +30,9 @@ export const useCompanyTableContextMenuEntries = () => {
const createActivityForCompany = useCreateActivityForCompany(); const createActivityForCompany = useCreateActivityForCompany();
const setTableRowIds = useSetRecoilState(tableRowIdsState); const setTableRowIds = useSetRecoilState(tableRowIdsState);
const resetRowSelection = useResetTableRowSelection(); const { resetTableRowSelection } = useRecordTable({
recordTableScopeId: 'companies',
});
const { data } = useGetFavoritesQuery(); const { data } = useGetFavoritesQuery();
const favorites = data?.findFavorites; const favorites = data?.findFavorites;
@ -50,7 +52,7 @@ export const useCompanyTableContextMenuEntries = () => {
(favorite) => favorite.company?.id === selectedCompanyId, (favorite) => favorite.company?.id === selectedCompanyId,
); );
resetRowSelection(); resetTableRowSelection();
if (isFavorite) deleteCompanyFavorite(selectedCompanyId); if (isFavorite) deleteCompanyFavorite(selectedCompanyId);
else insertCompanyFavorite(selectedCompanyId); else insertCompanyFavorite(selectedCompanyId);
}); });
@ -64,7 +66,7 @@ export const useCompanyTableContextMenuEntries = () => {
.getLoadable(selectedRowIdsSelector) .getLoadable(selectedRowIdsSelector)
.getValue(); .getValue();
resetRowSelection(); resetTableRowSelection();
await deleteManyCompany({ await deleteManyCompany({
variables: { variables: {

View File

@ -1,57 +0,0 @@
import { getOperationName } from '@apollo/client/utilities';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useOptimisticEvict } from '@/apollo/optimistic-effect/hooks/useOptimisticEvict';
import { GET_PIPELINES } from '@/pipeline/graphql/queries/getPipelines';
import { useResetTableRowSelection } from '@/ui/object/record-table/hooks/useResetTableRowSelection';
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
import { useDeleteManyCompaniesMutation } from '~/generated/graphql';
export const useDeleteSelectedComapnies = () => {
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
const resetRowSelection = useResetTableRowSelection();
const [deleteCompanies] = useDeleteManyCompaniesMutation({
refetchQueries: [getOperationName(GET_PIPELINES) ?? ''],
});
const { performOptimisticEvict } = useOptimisticEvict();
const [tableRowIds, setTableRowIds] = useRecoilState(tableRowIdsState);
const deleteSelectedCompanies = async () => {
const rowIdsToDelete = selectedRowIds;
resetRowSelection();
await deleteCompanies({
variables: {
ids: rowIdsToDelete,
},
optimisticResponse: {
__typename: 'Mutation',
deleteManyCompany: {
count: rowIdsToDelete.length,
},
},
update: (cache) => {
setTableRowIds(
tableRowIds.filter((id) => !rowIdsToDelete.includes(id)),
);
rowIdsToDelete.forEach((companyId) => {
cache.evict({
id: cache.identify({ __typename: 'Company', id: companyId }),
});
performOptimisticEvict('PipelineProgress', 'companyId', companyId);
cache.gc();
});
},
});
};
return deleteSelectedCompanies;
};

View File

@ -1,5 +1,5 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions'; import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
import { getCompaniesOptimisticEffectDefinition } from '@/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition'; import { getCompaniesOptimisticEffectDefinition } from '@/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition';
@ -8,14 +8,12 @@ import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCom
import { RecordTable } from '@/ui/object/record-table/components/RecordTable'; import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
import { RecordTableEffect } from '@/ui/object/record-table/components/RecordTableEffect'; import { RecordTableEffect } from '@/ui/object/record-table/components/RecordTableEffect';
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId'; import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
import { TableContext } from '@/ui/object/record-table/contexts/TableContext'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { useUpsertRecordTableItem } from '@/ui/object/record-table/hooks/useUpsertRecordTableItem';
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown'; import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
import { tableColumnsScopedState } from '@/ui/object/record-table/states/tableColumnsScopedState'; import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { tableFiltersScopedState } from '@/ui/object/record-table/states/tableFiltersScopedState';
import { tableSortsScopedState } from '@/ui/object/record-table/states/tableSortsScopedState';
import { ViewBar } from '@/views/components/ViewBar'; import { ViewBar } from '@/views/components/ViewBar';
import { useViewFields } from '@/views/hooks/internal/useViewFields'; import { useViewFields } from '@/views/hooks/internal/useViewFields';
import { useView } from '@/views/hooks/useView';
import { ViewScope } from '@/views/scopes/ViewScope'; import { ViewScope } from '@/views/scopes/ViewScope';
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField'; import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
@ -42,21 +40,21 @@ const StyledContainer = styled.div`
export const CompanyTable = () => { export const CompanyTable = () => {
const viewScopeId = 'company-table-view'; const viewScopeId = 'company-table-view';
const tableScopeId = 'companies'; const tableScopeId = 'companies';
const setTableColumns = useSetRecoilState(
tableColumnsScopedState(tableScopeId),
);
const setTableFilters = useSetRecoilState( const {
tableFiltersScopedState(tableScopeId), setTableFilters,
); setTableSorts,
setTableColumns,
const setTableSorts = useSetRecoilState(tableSortsScopedState(tableScopeId)); upsertRecordTableItem,
} = useRecordTable({
recordTableScopeId: tableScopeId,
});
const [updateEntityMutation] = useUpdateOneCompanyMutation(); const [updateEntityMutation] = useUpdateOneCompanyMutation();
const upsertRecordTableItem = useUpsertRecordTableItem();
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery(); const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
const { persistViewFields } = useViewFields(viewScopeId); const { persistViewFields } = useViewFields(viewScopeId);
const { setEntityCountInCurrentView } = useView({ viewScopeId });
const { setContextMenuEntries, setActionBarEntries } = const { setContextMenuEntries, setActionBarEntries } =
useCompanyTableContextMenuEntries(); useCompanyTableContextMenuEntries();
@ -112,12 +110,14 @@ export const CompanyTable = () => {
}} }}
> >
<StyledContainer> <StyledContainer>
<TableContext.Provider <RecordTableScope
value={{ recordTableScopeId={tableScopeId}
onColumnsChange: useRecoilCallback(() => (columns) => { onColumnsChange={useRecoilCallback(() => (columns) => {
persistViewFields(mapColumnDefinitionsToViewFields(columns)); persistViewFields(mapColumnDefinitionsToViewFields(columns));
}), })}
}} onEntityCountChange={useRecoilCallback(() => (entityCount) => {
setEntityCountInCurrentView(entityCount);
})}
> >
<ViewBar <ViewBar
optionsDropdownButton={<TableOptionsDropdown onImport={onImport} />} optionsDropdownButton={<TableOptionsDropdown onImport={onImport} />}
@ -142,7 +142,7 @@ export const CompanyTable = () => {
variables: UpdateOneCompanyMutationVariables; variables: UpdateOneCompanyMutationVariables;
}) => updateCompany(variables)} }) => updateCompany(variables)}
/> />
</TableContext.Provider> </RecordTableScope>
</StyledContainer> </StyledContainer>
</ViewScope> </ViewScope>
); );

View File

@ -1,9 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions'; import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
import { availableTableColumnsScopedState } from '@/ui/object/record-table/states/availableTableColumnsScopedState'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
import { ViewType } from '@/views/types/ViewType'; import { ViewType } from '@/views/types/ViewType';
import { companyTableFilterDefinitions } from '~/pages/companies/constants/companyTableFilterDefinitions'; import { companyTableFilterDefinitions } from '~/pages/companies/constants/companyTableFilterDefinitions';
@ -18,10 +16,7 @@ const CompanyTableEffect = () => {
setViewObjectId, setViewObjectId,
} = useView(); } = useView();
const [, setAvailableTableColumns] = useRecoilScopedState( const { setAvailableTableColumns } = useRecordTable();
availableTableColumnsScopedState,
TableRecoilScopeContext,
);
useEffect(() => { useEffect(() => {
setAvailableSortDefinitions?.(companyTableSortDefinitions); setAvailableSortDefinitions?.(companyTableSortDefinitions);

View File

@ -1,19 +1,12 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions'; import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
import { useSetRecordTableData } from '@/ui/object/record-table/hooks/useSetRecordTableData'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableColumnsScopedState } from '@/ui/object/record-table/states/tableColumnsScopedState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { mockedCompaniesData } from './companies-mock-data'; import { mockedCompaniesData } from './companies-mock-data';
export const CompanyTableMockDataEffect = () => { export const CompanyTableMockDataEffect = () => {
const [, setTableColumns] = useRecoilScopedState( const { setRecordTableData, setTableColumns } = useRecordTable();
tableColumnsScopedState,
TableRecoilScopeContext,
);
const setRecordTableData = useSetRecordTableData();
useEffect(() => { useEffect(() => {
setRecordTableData(mockedCompaniesData); setRecordTableData(mockedCompaniesData);

View File

@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import { RecordTable } from '@/ui/object/record-table/components/RecordTable'; import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId'; import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown'; import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { ViewBar } from '@/views/components/ViewBar'; import { ViewBar } from '@/views/components/ViewBar';
import { ViewScope } from '@/views/scopes/ViewScope'; import { ViewScope } from '@/views/scopes/ViewScope';
import { useUpdateOneCompanyMutation } from '~/generated/graphql'; import { useUpdateOneCompanyMutation } from '~/generated/graphql';
@ -21,14 +22,20 @@ export const CompanyTableMockMode = () => {
return ( return (
<StyledContainer> <StyledContainer>
<ViewScope viewScopeId="company-table-mock-mode"> <ViewScope viewScopeId="company-table-mock-mode">
<CompanyTableEffect /> <RecordTableScope
<CompanyTableMockDataEffect /> recordTableScopeId="company-table-mock-mode-table"
<ViewBar onColumnsChange={() => {}}
optionsDropdownButton={<TableOptionsDropdown />} onEntityCountChange={() => {}}
optionsDropdownScopeId={TableOptionsDropdownId} >
/> <CompanyTableEffect />
<CompanyTableMockDataEffect />
<ViewBar
optionsDropdownButton={<TableOptionsDropdown />}
optionsDropdownScopeId={TableOptionsDropdownId}
/>
<RecordTable updateEntityMutation={useUpdateOneCompanyMutation} /> <RecordTable updateEntityMutation={useUpdateOneCompanyMutation} />
</RecordTableScope>
</ViewScope> </ViewScope>
</StyledContainer> </StyledContainer>
); );

View File

@ -1,22 +1,21 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { RecordTable } from '@/ui/object/record-table/components/RecordTable'; import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId'; import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
import { TableContext } from '@/ui/object/record-table/contexts/TableContext'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown'; import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
import { tableColumnsScopedState } from '@/ui/object/record-table/states/tableColumnsScopedState'; import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { tableFiltersScopedState } from '@/ui/object/record-table/states/tableFiltersScopedState';
import { tableSortsScopedState } from '@/ui/object/record-table/states/tableSortsScopedState';
import { ViewBar } from '@/views/components/ViewBar'; import { ViewBar } from '@/views/components/ViewBar';
import { useViewFields } from '@/views/hooks/internal/useViewFields'; import { useViewFields } from '@/views/hooks/internal/useViewFields';
import { useView } from '@/views/hooks/useView';
import { ViewScope } from '@/views/scopes/ViewScope'; import { ViewScope } from '@/views/scopes/ViewScope';
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField'; import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
import { useObjectMetadataItemInContext } from '../hooks/useObjectMetadataItemInContext'; import { useFindOneObjectMetadataItem } from '../hooks/useFindOneObjectMetadataItem';
import { useUpdateOneObject } from '../hooks/useUpdateOneObject'; import { useUpdateOneObject } from '../hooks/useUpdateOneObject';
import { RecordTableEffect } from './RecordTableEffect'; import { RecordTableEffect } from './RecordTableEffect';
@ -28,28 +27,29 @@ const StyledContainer = styled.div`
overflow: auto; overflow: auto;
`; `;
export const RecordTableContainer = () => { export const RecordTableContainer = ({
const { columnDefinitions, foundObjectMetadataItem, objectNamePlural } = objectNamePlural,
useObjectMetadataItemInContext(); }: {
objectNamePlural: string;
}) => {
const { columnDefinitions } = useFindOneObjectMetadataItem({
objectNamePlural,
});
const { updateOneObject } = useUpdateOneObject({ const { updateOneObject } = useUpdateOneObject({
objectNamePlural, objectNamePlural,
}); });
const tableScopeId = foundObjectMetadataItem?.namePlural ?? ''; const tableScopeId = objectNamePlural ?? '';
const viewScopeId = objectNamePlural ?? ''; const viewScopeId = objectNamePlural ?? '';
const { persistViewFields } = useViewFields(viewScopeId); const { persistViewFields } = useViewFields(viewScopeId);
const setTableColumns = useSetRecoilState( const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({
tableColumnsScopedState(tableScopeId), recordTableScopeId: tableScopeId,
); });
const setTableFilters = useSetRecoilState( const { setEntityCountInCurrentView } = useView({ viewScopeId });
tableFiltersScopedState(tableScopeId),
);
const setTableSorts = useSetRecoilState(tableSortsScopedState(tableScopeId));
const updateEntity = ({ const updateEntity = ({
variables, variables,
@ -83,11 +83,13 @@ export const RecordTableContainer = () => {
}} }}
> >
<StyledContainer> <StyledContainer>
<TableContext.Provider <RecordTableScope
value={{ recordTableScopeId={tableScopeId}
onColumnsChange: useRecoilCallback(() => (columns) => { onColumnsChange={useRecoilCallback(() => (columns) => {
persistViewFields(mapColumnDefinitionsToViewFields(columns)); persistViewFields(mapColumnDefinitionsToViewFields(columns));
}), })}
onEntityCountChange={(entityCount) => {
setEntityCountInCurrentView(entityCount);
}} }}
> >
<ViewBar <ViewBar
@ -96,7 +98,7 @@ export const RecordTableContainer = () => {
/> />
<RecordTableEffect /> <RecordTableEffect />
<RecordTable updateEntityMutation={updateEntity} /> <RecordTable updateEntityMutation={updateEntity} />
</TableContext.Provider> </RecordTableScope>
</StyledContainer> </StyledContainer>
</ViewScope> </ViewScope>
); );

View File

@ -1,29 +1,27 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil'; import { useRecoilValue } from 'recoil';
import { turnFiltersIntoWhereClauseV2 } from '@/ui/object/object-filter-dropdown/utils/turnFiltersIntoWhereClauseV2'; import { turnFiltersIntoWhereClauseV2 } from '@/ui/object/object-filter-dropdown/utils/turnFiltersIntoWhereClauseV2';
import { turnSortsIntoOrderByV2 } from '@/ui/object/object-sort-dropdown/utils/turnSortsIntoOrderByV2'; import { turnSortsIntoOrderByV2 } from '@/ui/object/object-sort-dropdown/utils/turnSortsIntoOrderByV2';
import { useSetRecordTableData } from '@/ui/object/record-table/hooks/useSetRecordTableData'; import { useRecordTableScopedStates } from '@/ui/object/record-table/hooks/internal/useRecordTableScopedStates';
import { availableTableColumnsScopedState } from '@/ui/object/record-table/states/availableTableColumnsScopedState';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableFiltersScopedState } from '@/ui/object/record-table/states/tableFiltersScopedState';
import { tableSortsScopedState } from '@/ui/object/record-table/states/tableSortsScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
import { ViewType } from '@/views/types/ViewType'; import { ViewType } from '@/views/types/ViewType';
import { useRecordTable } from '../../ui/object/record-table/hooks/useRecordTable';
import { useFindManyObjects } from '../hooks/useFindManyObjects'; import { useFindManyObjects } from '../hooks/useFindManyObjects';
import { useObjectMetadataItemInContext } from '../hooks/useObjectMetadataItemInContext'; import { useFindOneObjectMetadataItem } from '../hooks/useFindOneObjectMetadataItem';
export const RecordTableEffect = () => { export const RecordTableEffect = () => {
const { scopeId } = useRecordTable();
const { const {
foundObjectMetadataItem,
columnDefinitions, columnDefinitions,
filterDefinitions, filterDefinitions,
sortDefinitions, sortDefinitions,
foundObjectMetadataItem, } = useFindOneObjectMetadataItem({
objectNamePlural, objectNamePlural: scopeId,
} = useObjectMetadataItemInContext(); });
const { const {
setAvailableSortDefinitions, setAvailableSortDefinitions,
setAvailableFilterDefinitions, setAvailableFilterDefinitions,
@ -32,20 +30,15 @@ export const RecordTableEffect = () => {
setViewObjectId, setViewObjectId,
} = useView(); } = useView();
const setRecordTableData = useSetRecordTableData(); const { setRecordTableData, setAvailableTableColumns } = useRecordTable();
const tableFilters = useRecoilScopedValue( const { tableFiltersState, tableSortsState } = useRecordTableScopedStates();
tableFiltersScopedState,
TableRecoilScopeContext,
);
const tableSorts = useRecoilScopedValue( const tableFilters = useRecoilValue(tableFiltersState);
tableSortsScopedState, const tableSorts = useRecoilValue(tableSortsState);
TableRecoilScopeContext,
);
const { objects, loading } = useFindManyObjects({ const { objects, loading } = useFindManyObjects({
objectNamePlural: objectNamePlural, objectNamePlural: scopeId,
filter: turnFiltersIntoWhereClauseV2( filter: turnFiltersIntoWhereClauseV2(
tableFilters, tableFilters,
foundObjectMetadataItem?.fields ?? [], foundObjectMetadataItem?.fields ?? [],
@ -64,12 +57,6 @@ export const RecordTableEffect = () => {
} }
}, [objects, setRecordTableData, loading]); }, [objects, setRecordTableData, loading]);
const tableScopeId = foundObjectMetadataItem?.namePlural ?? '';
const setAvailableTableColumns = useSetRecoilState(
availableTableColumnsScopedState(tableScopeId),
);
useEffect(() => { useEffect(() => {
if (!foundObjectMetadataItem) { if (!foundObjectMetadataItem) {
return; return;

View File

@ -12,12 +12,9 @@ import { PageHeader } from '@/ui/layout/page/PageHeader';
import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect'; import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect';
import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar'; import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar';
import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu'; import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useCreateOneObject } from '../hooks/useCreateOneObject'; import { useCreateOneObject } from '../hooks/useCreateOneObject';
import { useFindOneObjectMetadataItem } from '../hooks/useFindOneObjectMetadataItem'; import { useFindOneObjectMetadataItem } from '../hooks/useFindOneObjectMetadataItem';
import { ObjectMetadataItemScope } from '../scopes/ObjectMetadataItemScope';
const StyledTableContainer = styled.div` const StyledTableContainer = styled.div`
display: flex; display: flex;
@ -59,20 +56,11 @@ export const RecordTablePage = () => {
<PageAddButton onClick={handleAddButtonClick} /> <PageAddButton onClick={handleAddButtonClick} />
</PageHeader> </PageHeader>
<PageBody> <PageBody>
<RecoilScope <StyledTableContainer>
scopeId={objectNamePlural} <RecordTableContainer objectNamePlural={objectNamePlural} />
CustomRecoilScopeContext={TableRecoilScopeContext} </StyledTableContainer>
> <RecordTableActionBar />
<StyledTableContainer> <RecordTableContextMenu />
<ObjectMetadataItemScope
objectMetadataItemNamePlural={objectNamePlural}
>
<RecordTableContainer />
</ObjectMetadataItemScope>
</StyledTableContainer>
<RecordTableActionBar />
<RecordTableContextMenu />
</RecoilScope>
</PageBody> </PageBody>
</PageContainer> </PageContainer>
); );

View File

@ -1,18 +0,0 @@
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { ObjectMetadataItemScopeInternalContext } from '../scopes/scope-internal-context/ObjectMetadataItemScopeInternalContext';
type UseObjectMetadataItemProps = {
objectMetadataItemNamePlural?: string;
};
export const useObjectMetadataItem = (props?: UseObjectMetadataItemProps) => {
const scopeId = useAvailableScopeIdOrThrow(
ObjectMetadataItemScopeInternalContext,
props?.objectMetadataItemNamePlural,
);
return {
scopeId,
};
};

View File

@ -1,34 +0,0 @@
import { useContext } from 'react';
import { ObjectMetadataItemScopeInternalContext } from '../scopes/scope-internal-context/ObjectMetadataItemScopeInternalContext';
import { useFindOneObjectMetadataItem } from './useFindOneObjectMetadataItem';
export const useObjectMetadataItemInContext = () => {
const context = useContext(ObjectMetadataItemScopeInternalContext);
if (!context) {
throw new Error(
'Could not find ObjectMetadataItemScopeInternalContext while in useObjectMetadataItemInContext',
);
}
const {
foundObjectMetadataItem,
loading,
columnDefinitions,
filterDefinitions,
sortDefinitions,
} = useFindOneObjectMetadataItem({
objectNamePlural: context.objectNamePlural,
});
return {
...context,
foundObjectMetadataItem,
loading,
columnDefinitions,
filterDefinitions,
sortDefinitions,
};
};

View File

@ -1,14 +1,14 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState'; import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState';
import { useResetTableRowSelection } from '@/ui/object/record-table/hooks/useResetTableRowSelection'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState'; import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState';
import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState'; import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState';
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState'; import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
export const useSetObjectRecordTableData = () => { export const useSetRecordTableData = () => {
const resetTableRowSelection = useResetTableRowSelection(); const { resetTableRowSelection } = useRecordTable();
const { setEntityCountInCurrentView } = useView(); const { setEntityCountInCurrentView } = useView();
return useRecoilCallback( return useRecoilCallback(

View File

@ -1,24 +0,0 @@
import { ReactNode } from 'react';
import { ObjectMetadataItemScopeInternalContext } from './scope-internal-context/ObjectMetadataItemScopeInternalContext';
type ObjectMetadataItemScopeProps = {
children: ReactNode;
objectMetadataItemNamePlural: string;
};
export const ObjectMetadataItemScope = ({
children,
objectMetadataItemNamePlural,
}: ObjectMetadataItemScopeProps) => {
return (
<ObjectMetadataItemScopeInternalContext.Provider
value={{
scopeId: objectMetadataItemNamePlural,
objectNamePlural: objectMetadataItemNamePlural,
}}
>
{children}
</ObjectMetadataItemScopeInternalContext.Provider>
);
};

View File

@ -1,9 +0,0 @@
import { ScopedStateKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopedStateKey';
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
type ObjectMetadataItemScopeInternalContextProps = ScopedStateKey & {
objectNamePlural: string;
};
export const ObjectMetadataItemScopeInternalContext =
createScopeInternalContext<ObjectMetadataItemScopeInternalContextProps>();

View File

@ -11,7 +11,7 @@ import {
} from '@/ui/display/icon'; } from '@/ui/display/icon';
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState'; import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
import { useResetTableRowSelection } from '@/ui/object/record-table/hooks/useResetTableRowSelection'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector'; import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState'; import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
import { import {
@ -30,7 +30,9 @@ export const usePersonTableContextMenuEntries = () => {
const createActivityForPeople = useCreateActivityForPeople(); const createActivityForPeople = useCreateActivityForPeople();
const setTableRowIds = useSetRecoilState(tableRowIdsState); const setTableRowIds = useSetRecoilState(tableRowIdsState);
const resetRowSelection = useResetTableRowSelection(); const { resetTableRowSelection } = useRecordTable({
recordTableScopeId: 'people',
});
const { data } = useGetFavoritesQuery(); const { data } = useGetFavoritesQuery();
const favorites = data?.findFavorites; const favorites = data?.findFavorites;
@ -48,7 +50,7 @@ export const usePersonTableContextMenuEntries = () => {
!!selectedPersonId && !!selectedPersonId &&
!!favorites?.find((favorite) => favorite.person?.id === selectedPersonId); !!favorites?.find((favorite) => favorite.person?.id === selectedPersonId);
resetRowSelection(); resetTableRowSelection();
if (isFavorite) deletePersonFavorite(selectedPersonId); if (isFavorite) deletePersonFavorite(selectedPersonId);
else insertPersonFavorite(selectedPersonId); else insertPersonFavorite(selectedPersonId);
}); });
@ -62,7 +64,7 @@ export const usePersonTableContextMenuEntries = () => {
.getLoadable(selectedRowIdsSelector) .getLoadable(selectedRowIdsSelector)
.getValue(); .getValue();
resetRowSelection(); resetTableRowSelection();
await deleteManyPerson({ await deleteManyPerson({
variables: { variables: {

View File

@ -1,7 +1,7 @@
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { useResetTableRowSelection } from '@/ui/object/record-table/hooks/useResetTableRowSelection'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState'; import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState';
import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState'; import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState';
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState'; import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
@ -18,7 +18,7 @@ import { peopleNameCellFamilyState } from '../states/peopleNamesFamilyState';
import { peoplePhoneFamilyState } from '../states/peoplePhoneFamilyState'; import { peoplePhoneFamilyState } from '../states/peoplePhoneFamilyState';
export const useSetPeopleRecordTable = () => { export const useSetPeopleRecordTable = () => {
const resetTableRowSelection = useResetTableRowSelection(); const { resetTableRowSelection } = useRecordTable();
const currentLocation = useLocation().pathname; const currentLocation = useLocation().pathname;

View File

@ -1,5 +1,4 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useSetRecoilState } from 'recoil';
import { peopleAvailableFieldDefinitions } from '@/people/constants/peopleAvailableFieldDefinitions'; import { peopleAvailableFieldDefinitions } from '@/people/constants/peopleAvailableFieldDefinitions';
import { getPeopleOptimisticEffectDefinition } from '@/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition'; import { getPeopleOptimisticEffectDefinition } from '@/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition';
@ -9,15 +8,13 @@ import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { RecordTable } from '@/ui/object/record-table/components/RecordTable'; import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
import { RecordTableEffect } from '@/ui/object/record-table/components/RecordTableEffect'; import { RecordTableEffect } from '@/ui/object/record-table/components/RecordTableEffect';
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId'; import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
import { TableContext } from '@/ui/object/record-table/contexts/TableContext'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { useUpsertRecordTableItem } from '@/ui/object/record-table/hooks/useUpsertRecordTableItem';
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown'; import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
import { tableColumnsScopedState } from '@/ui/object/record-table/states/tableColumnsScopedState'; import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { tableFiltersScopedState } from '@/ui/object/record-table/states/tableFiltersScopedState';
import { tableSortsScopedState } from '@/ui/object/record-table/states/tableSortsScopedState';
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition'; import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
import { ViewBar } from '@/views/components/ViewBar'; import { ViewBar } from '@/views/components/ViewBar';
import { useViewFields } from '@/views/hooks/internal/useViewFields'; import { useViewFields } from '@/views/hooks/internal/useViewFields';
import { useView } from '@/views/hooks/useView';
import { ViewScope } from '@/views/scopes/ViewScope'; import { ViewScope } from '@/views/scopes/ViewScope';
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField'; import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
@ -36,18 +33,17 @@ import PersonTableEffect from './PersonTableEffect';
export const PersonTable = () => { export const PersonTable = () => {
const viewScopeId = 'person-table-view'; const viewScopeId = 'person-table-view';
const tableScopeId = 'people'; const tableScopeId = 'people';
const setTableColumns = useSetRecoilState(
tableColumnsScopedState(tableScopeId),
);
const setTableFilters = useSetRecoilState( const {
tableFiltersScopedState(tableScopeId), setTableFilters,
); setTableSorts,
setTableColumns,
const setTableSorts = useSetRecoilState(tableSortsScopedState(tableScopeId)); upsertRecordTableItem,
} = useRecordTable({
recordTableScopeId: tableScopeId,
});
const [updateEntityMutation] = useUpdateOnePersonMutation(); const [updateEntityMutation] = useUpdateOnePersonMutation();
const upsertRecordTableItem = useUpsertRecordTableItem();
const { persistViewFields } = useViewFields(viewScopeId); const { persistViewFields } = useViewFields(viewScopeId);
@ -73,6 +69,8 @@ export const PersonTable = () => {
const { openPersonSpreadsheetImport: onImport } = const { openPersonSpreadsheetImport: onImport } =
useSpreadsheetPersonImport(); useSpreadsheetPersonImport();
const { setEntityCountInCurrentView } = useView({ viewScopeId });
const StyledContainer = styled.div` const StyledContainer = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -98,9 +96,11 @@ export const PersonTable = () => {
}} }}
> >
<StyledContainer> <StyledContainer>
<TableContext.Provider <RecordTableScope
value={{ recordTableScopeId={tableScopeId}
onColumnsChange: handleColumnChange, onColumnsChange={handleColumnChange}
onEntityCountChange={(entityCount) => {
setEntityCountInCurrentView(entityCount);
}} }}
> >
<ViewBar <ViewBar
@ -126,7 +126,7 @@ export const PersonTable = () => {
variables: UpdateOnePersonMutationVariables; variables: UpdateOnePersonMutationVariables;
}) => updatePerson(variables)} }) => updatePerson(variables)}
/> />
</TableContext.Provider> </RecordTableScope>
</StyledContainer> </StyledContainer>
</ViewScope> </ViewScope>
); );

View File

@ -1,10 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { peopleAvailableFieldDefinitions } from '@/people/constants/peopleAvailableFieldDefinitions'; import { peopleAvailableFieldDefinitions } from '@/people/constants/peopleAvailableFieldDefinitions';
import { availableTableColumnsScopedState } from '@/ui/object/record-table/states/availableTableColumnsScopedState'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableColumnsScopedState } from '@/ui/object/record-table/states/tableColumnsScopedState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
import { ViewType } from '@/views/types/ViewType'; import { ViewType } from '@/views/types/ViewType';
import { personTableFilterDefinitions } from '~/pages/people/constants/personTableFilterDefinitions'; import { personTableFilterDefinitions } from '~/pages/people/constants/personTableFilterDefinitions';
@ -19,15 +16,7 @@ const PeopleTableEffect = () => {
setViewObjectId, setViewObjectId,
} = useView(); } = useView();
const [, setTableColumns] = useRecoilScopedState( const { setAvailableTableColumns, setTableColumns } = useRecordTable();
tableColumnsScopedState,
TableRecoilScopeContext,
);
const [, setAvailableTableColumns] = useRecoilScopedState(
availableTableColumnsScopedState,
TableRecoilScopeContext,
);
useEffect(() => { useEffect(() => {
setAvailableSortDefinitions?.(personTableSortDefinitions); setAvailableSortDefinitions?.(personTableSortDefinitions);

View File

@ -1,6 +1,6 @@
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { useMoveViewColumns } from '@/ui/object/record-table/hooks/useMoveViewColumns'; import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
import { useUpdatePipelineStageMutation } from '~/generated/graphql'; import { useUpdatePipelineStageMutation } from '~/generated/graphql';
import { boardColumnsState } from '../states/boardColumnsState'; import { boardColumnsState } from '../states/boardColumnsState';

View File

@ -4,8 +4,7 @@ import { useSetRecoilState } from 'recoil';
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries'; import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode'; import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext'; import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { actionBarOpenState } from '../../states/actionBarIsOpenState'; import { actionBarOpenState } from '../../states/actionBarIsOpenState';
@ -24,12 +23,16 @@ const meta: Meta<typeof ActionBar> = {
component: FilledActionBar, component: FilledActionBar,
decorators: [ decorators: [
(Story) => ( (Story) => (
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}> <RecordTableScope
recordTableScopeId="companies"
onColumnsChange={() => {}}
onEntityCountChange={() => {}}
>
<MemoryRouter> <MemoryRouter>
<CompanyTableMockMode /> <CompanyTableMockMode />
<Story /> <Story />
</MemoryRouter> </MemoryRouter>
</RecoilScope> </RecordTableScope>
), ),
ComponentDecorator, ComponentDecorator,
], ],

View File

@ -4,8 +4,7 @@ import { useSetRecoilState } from 'recoil';
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries'; import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode'; import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext'; import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { contextMenuIsOpenState } from '../../states/contextMenuIsOpenState'; import { contextMenuIsOpenState } from '../../states/contextMenuIsOpenState';
@ -30,12 +29,16 @@ const meta: Meta<typeof ContextMenu> = {
component: FilledContextMenu, component: FilledContextMenu,
decorators: [ decorators: [
(Story) => ( (Story) => (
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}> <RecordTableScope
recordTableScopeId="companies"
onColumnsChange={() => {}}
onEntityCountChange={() => {}}
>
<MemoryRouter> <MemoryRouter>
<CompanyTableMockMode></CompanyTableMockMode> <CompanyTableMockMode></CompanyTableMockMode>
<Story /> <Story />
</MemoryRouter> </MemoryRouter>
</RecoilScope> </RecordTableScope>
), ),
ComponentDecorator, ComponentDecorator,
], ],

View File

@ -5,7 +5,7 @@ import { useSetRecoilState } from 'recoil';
import { Checkbox } from '@/ui/input/components/Checkbox'; import { Checkbox } from '@/ui/input/components/Checkbox';
import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState'; import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected'; import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;

View File

@ -10,10 +10,7 @@ import {
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext'; import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus'; import { useRecordTable } from '../hooks/useRecordTable';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
import { TableHotkeyScope } from '../types/TableHotkeyScope'; import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { RecordTableBody } from './RecordTableBody'; import { RecordTableBody } from './RecordTableBody';
@ -89,13 +86,15 @@ type RecordTableProps = {
export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => { export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => {
const tableBodyRef = useRef<HTMLDivElement>(null); const tableBodyRef = useRef<HTMLDivElement>(null);
const setRowSelectedState = useSetRowSelectedState(); const {
const resetTableRowSelection = useResetTableRowSelection(); leaveTableFocus,
setRowSelectedState,
resetTableRowSelection,
useMapKeyboardToSoftFocus,
} = useRecordTable();
useMapKeyboardToSoftFocus(); useMapKeyboardToSoftFocus();
const leaveTableFocus = useLeaveTableFocus();
useListenClickOutside({ useListenClickOutside({
refs: [tableBodyRef], refs: [tableBodyRef],
callback: () => { callback: () => {

View File

@ -12,8 +12,8 @@ import { ColumnContext } from '../contexts/ColumnContext';
import { ColumnIndexContext } from '../contexts/ColumnIndexContext'; import { ColumnIndexContext } from '../contexts/ColumnIndexContext';
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext'; import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
import { RowIdContext } from '../contexts/RowIdContext'; import { RowIdContext } from '../contexts/RowIdContext';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected'; import { TableCell } from '../record-table-cell/components/RecordTableCell';
import { TableCell } from '../table-cell/components/TableCell'; import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected';
import { TableHotkeyScope } from '../types/TableHotkeyScope'; import { TableHotkeyScope } from '../types/TableHotkeyScope';
export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => { export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {

View File

@ -1,10 +1,10 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import defaults from 'lodash/defaults'; import defaults from 'lodash/defaults';
import { useRecoilValue } from 'recoil';
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect'; import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition'; import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { import {
SortOrder, SortOrder,
useGetCompaniesQuery, useGetCompaniesQuery,
@ -13,10 +13,8 @@ import {
import { FilterDefinition } from '../../object-filter-dropdown/types/FilterDefinition'; import { FilterDefinition } from '../../object-filter-dropdown/types/FilterDefinition';
import { SortDefinition } from '../../object-sort-dropdown/types/SortDefinition'; import { SortDefinition } from '../../object-sort-dropdown/types/SortDefinition';
import { useSetRecordTableData } from '../hooks/useSetRecordTableData'; import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext'; import { useRecordTable } from '../hooks/useRecordTable';
import { tablefiltersWhereScopedSelector } from '../states/selectors/tablefiltersWhereScopedSelector';
import { tableSortsOrderByScopedSelector } from '../states/selectors/tableSortsOrderByScopedSelector';
export const RecordTableEffect = ({ export const RecordTableEffect = ({
useGetRequest, useGetRequest,
@ -35,32 +33,28 @@ export const RecordTableEffect = ({
setActionBarEntries?: () => void; setActionBarEntries?: () => void;
setContextMenuEntries?: () => void; setContextMenuEntries?: () => void;
}) => { }) => {
const setRecordTableData = useSetRecordTableData(); const { setRecordTableData } = useRecordTable();
const { tableSortsOrderBySelector, tableFiltersWhereSelector } =
useRecordTableScopedStates();
const { registerOptimisticEffect } = useOptimisticEffect(); const { registerOptimisticEffect } = useOptimisticEffect();
const tableSortsOrderBy = useRecoilScopedValue( const tableSortsOrderBy = useRecoilValue(tableSortsOrderBySelector);
tableSortsOrderByScopedSelector,
TableRecoilScopeContext,
);
const sortsOrderBy = defaults(tableSortsOrderBy, [ const sortsOrderBy = defaults(tableSortsOrderBy, [
{ {
createdAt: SortOrder.Desc, createdAt: SortOrder.Desc,
}, },
]); ]);
const tablefiltersWhere = useRecoilScopedValue( const tableFiltersWhere = useRecoilValue(tableFiltersWhereSelector);
tablefiltersWhereScopedSelector,
TableRecoilScopeContext,
);
useGetRequest({ useGetRequest({
variables: { orderBy: sortsOrderBy, where: tablefiltersWhere }, variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
onCompleted: (data: any) => { onCompleted: (data: any) => {
const entities = data[getRequestResultKey] ?? []; const entities = data[getRequestResultKey] ?? [];
setRecordTableData(entities); setRecordTableData(entities);
registerOptimisticEffect({ registerOptimisticEffect({
variables: { orderBy: sortsOrderBy, where: tablefiltersWhere }, variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
definition: getRequestOptimisticEffectDefinition, definition: getRequestOptimisticEffectDefinition,
}); });
}, },

View File

@ -1,21 +1,16 @@
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilState } from 'recoil'; import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import { IconPlus } from '@/ui/display/icon'; import { IconPlus } from '@/ui/display/icon';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer'; import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { useTableColumns } from '../hooks/useTableColumns'; import { useTableColumns } from '../hooks/useTableColumns';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState'; import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { ColumnHeadWithDropdown } from './ColumnHeadWithDropdown'; import { ColumnHeadWithDropdown } from './ColumnHeadWithDropdown';
import { RecordTableHeaderPlusButtonContent } from './RecordTableHeaderPlusButtonContent'; import { RecordTableHeaderPlusButtonContent } from './RecordTableHeaderPlusButtonContent';
@ -110,22 +105,18 @@ export const RecordTableHeader = () => {
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState( const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
resizeFieldOffsetState, resizeFieldOffsetState,
); );
const tableColumns = useRecoilScopedValue(
tableColumnsScopedState, const {
TableRecoilScopeContext, tableColumnsState,
); tableColumnsByKeySelector,
const tableColumnsByKey = useRecoilScopedValue( hiddenTableColumnsSelector,
tableColumnsByKeyScopedSelector, visibleTableColumnsSelector,
TableRecoilScopeContext, } = useRecordTableScopedStates();
);
const hiddenTableColumns = useRecoilScopedValue( const tableColumns = useRecoilValue(tableColumnsState);
hiddenTableColumnsScopedSelector, const tableColumnsByKey = useRecoilValue(tableColumnsByKeySelector);
TableRecoilScopeContext, const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
); const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
const visibleTableColumns = useRecoilScopedValue(
visibleTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const [initialPointerPositionX, setInitialPointerPositionX] = useState< const [initialPointerPositionX, setInitialPointerPositionX] = useState<
number | null number | null

View File

@ -1,24 +1,22 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useRecoilValue } from 'recoil';
import { IconPlus } from '@/ui/display/icon'; import { IconPlus } from '@/ui/display/icon';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { FieldMetadata } from '../../field/types/FieldMetadata'; import { FieldMetadata } from '../../field/types/FieldMetadata';
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { useTableColumns } from '../hooks/useTableColumns'; import { useTableColumns } from '../hooks/useTableColumns';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
export const RecordTableHeaderPlusButtonContent = () => { export const RecordTableHeaderPlusButtonContent = () => {
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const hiddenTableColumns = useRecoilScopedValue( const { hiddenTableColumnsSelector } = useRecordTableScopedStates();
hiddenTableColumnsScopedSelector,
TableRecoilScopeContext, const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
);
const { handleColumnVisibilityChange } = useTableColumns(); const { handleColumnVisibilityChange } = useTableColumns();

View File

@ -1,12 +1,10 @@
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { ColumnContext } from '../contexts/ColumnContext'; import { ColumnContext } from '../contexts/ColumnContext';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected'; import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext'; import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { CheckboxCell } from './CheckboxCell'; import { CheckboxCell } from './CheckboxCell';
import { RecordTableCell } from './RecordTableCell'; import { RecordTableCell } from './RecordTableCell';
@ -24,10 +22,10 @@ export const RecordTableRow = forwardRef<
HTMLTableRowElement, HTMLTableRowElement,
RecordTableRowProps RecordTableRowProps
>(({ rowId }, ref) => { >(({ rowId }, ref) => {
const visibleTableColumns = useRecoilScopedValue( const { visibleTableColumnsSelector } = useRecordTableScopedStates();
visibleTableColumnsScopedSelector,
TableRecoilScopeContext, const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
);
const { currentRowSelected } = useCurrentRowSelected(); const { currentRowSelected } = useCurrentRowSelected();
return ( return (

View File

@ -1,8 +1,10 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { Checkbox } from '@/ui/input/components/Checkbox'; import { Checkbox } from '@/ui/input/components/Checkbox';
import { useSelectAllRows } from '../hooks/useSelectAllRows'; import { useRecordTable } from '../hooks/useRecordTable';
import { allRowsSelectedStatusSelector } from '../states/selectors/allRowsSelectedStatusSelector';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
@ -14,7 +16,8 @@ const StyledContainer = styled.div`
`; `;
export const SelectAllCheckbox = () => { export const SelectAllCheckbox = () => {
const { selectAllRows, allRowsSelectedStatus } = useSelectAllRows(); const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector);
const { selectAllRows } = useRecordTable();
const checked = allRowsSelectedStatus === 'all'; const checked = allRowsSelectedStatus === 'all';
const indeterminate = allRowsSelectedStatus === 'some'; const indeterminate = allRowsSelectedStatus === 'some';

View File

@ -1,11 +0,0 @@
import { createContext } from 'react';
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { ColumnDefinition } from '../types/ColumnDefinition';
export const TableContext = createContext<{
onColumnsChange?: (
columns: ColumnDefinition<FieldMetadata>[],
) => void | Promise<void>;
}>({});

View File

@ -1,7 +1,7 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState'; import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState';
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState'; import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
export const useCloseCurrentTableCellInEditMode = () => export const useCloseCurrentTableCellInEditMode = () =>
useRecoilCallback(({ set, snapshot }) => { useRecoilCallback(({ set, snapshot }) => {

View File

@ -1,8 +1,8 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState'; import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { isSoftFocusOnTableCellFamilyState } from '../states/isSoftFocusOnTableCellFamilyState'; import { isSoftFocusOnTableCellFamilyState } from '../../states/isSoftFocusOnTableCellFamilyState';
import { softFocusPositionState } from '../states/softFocusPositionState'; import { softFocusPositionState } from '../../states/softFocusPositionState';
export const useDisableSoftFocus = () => export const useDisableSoftFocus = () =>
useRecoilCallback(({ set, snapshot }) => { useRecoilCallback(({ set, snapshot }) => {

View File

@ -1,7 +1,7 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState'; import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState';
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState'; import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
export const useGetIsSomeCellInEditMode = () => { export const useGetIsSomeCellInEditMode = () => {
return useRecoilCallback( return useRecoilCallback(

View File

@ -2,8 +2,8 @@ import { useRecoilCallback } from 'recoil';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState'; import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { TableHotkeyScope } from '../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useCloseCurrentTableCellInEditMode } from './useCloseCurrentTableCellInEditMode'; import { useCloseCurrentTableCellInEditMode } from './useCloseCurrentTableCellInEditMode';
import { useDisableSoftFocus } from './useDisableSoftFocus'; import { useDisableSoftFocus } from './useDisableSoftFocus';

View File

@ -1,8 +1,8 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState'; import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState';
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState'; import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
import { TableCellPosition } from '../types/TableCellPosition'; import { TableCellPosition } from '../../types/TableCellPosition';
export const useMoveEditModeToTableCellPosition = () => export const useMoveEditModeToTableCellPosition = () =>
useRecoilCallback(({ set, snapshot }) => { useRecoilCallback(({ set, snapshot }) => {

View File

@ -0,0 +1,46 @@
import { RecordTableScopeInternalContext } from '@/ui/object/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getRecordTableScopedStates } from '../../utils/getRecordTableScopedStates';
export const useRecordTableScopedStates = (args?: {
customRecordTableScopeId?: string;
}) => {
const { customRecordTableScopeId } = args ?? {};
const scopeId = useAvailableScopeIdOrThrow(
RecordTableScopeInternalContext,
customRecordTableScopeId,
);
const {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,
onEntityCountChangeState,
onColumnsChangeState,
} = getRecordTableScopedStates({
recordTableScopeId: scopeId,
});
return {
scopeId,
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,
onEntityCountChangeState,
onColumnsChangeState,
};
};

View File

@ -1,7 +1,7 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState'; import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState';
import { tableRowIdsState } from '../states/tableRowIdsState'; import { tableRowIdsState } from '../../states/tableRowIdsState';
export const useResetTableRowSelection = () => export const useResetTableRowSelection = () =>
useRecoilCallback( useRecoilCallback(

View File

@ -1,12 +1,10 @@
import { useRecoilCallback, useRecoilValue } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState'; import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState';
import { allRowsSelectedStatusSelector } from '../states/selectors/allRowsSelectedStatusSelector'; import { allRowsSelectedStatusSelector } from '../../states/selectors/allRowsSelectedStatusSelector';
import { tableRowIdsState } from '../states/tableRowIdsState'; import { tableRowIdsState } from '../../states/tableRowIdsState';
export const useSelectAllRows = () => { export const useSelectAllRows = () => {
const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector);
const selectAllRows = useRecoilCallback( const selectAllRows = useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>
() => { () => {
@ -35,7 +33,6 @@ export const useSelectAllRows = () => {
); );
return { return {
allRowsSelectedStatus,
selectAllRows, selectAllRows,
}; };
}; };

View File

@ -1,17 +1,21 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState'; import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState';
import { useView } from '@/views/hooks/useView';
import { isFetchingRecordTableDataState } from '../states/isFetchingRecordTableDataState'; import { isFetchingRecordTableDataState } from '../../states/isFetchingRecordTableDataState';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState'; import { numberOfTableRowsState } from '../../states/numberOfTableRowsState';
import { tableRowIdsState } from '../states/tableRowIdsState'; import { tableRowIdsState } from '../../states/tableRowIdsState';
import { useResetTableRowSelection } from './useResetTableRowSelection'; import { useResetTableRowSelection } from './useResetTableRowSelection';
export const useSetRecordTableData = () => { type useSetRecordTableDataProps = {
onEntityCountChange: (entityCount: number) => void;
};
export const useSetRecordTableData = ({
onEntityCountChange,
}: useSetRecordTableDataProps) => {
const resetTableRowSelection = useResetTableRowSelection(); const resetTableRowSelection = useResetTableRowSelection();
const { setEntityCountInCurrentView } = useView();
return useRecoilCallback( return useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>
@ -39,9 +43,9 @@ export const useSetRecordTableData = () => {
resetTableRowSelection(); resetTableRowSelection();
set(numberOfTableRowsState, entityIds.length); set(numberOfTableRowsState, entityIds.length);
setEntityCountInCurrentView(entityIds.length); onEntityCountChange(entityIds.length);
set(isFetchingRecordTableDataState, false); set(isFetchingRecordTableDataState, false);
}, },
[resetTableRowSelection, setEntityCountInCurrentView], [onEntityCountChange, resetTableRowSelection],
); );
}; };

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState'; import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState';
export const useSetRowSelectedState = () => export const useSetRowSelectedState = () =>
useRecoilCallback(({ set }) => (rowId: string, selected: boolean) => { useRecoilCallback(({ set }) => (rowId: string, selected: boolean) => {

View File

@ -1,9 +1,9 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState'; import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { isSoftFocusOnTableCellFamilyState } from '../states/isSoftFocusOnTableCellFamilyState'; import { isSoftFocusOnTableCellFamilyState } from '../../states/isSoftFocusOnTableCellFamilyState';
import { softFocusPositionState } from '../states/softFocusPositionState'; import { softFocusPositionState } from '../../states/softFocusPositionState';
import { TableCellPosition } from '../types/TableCellPosition'; import { TableCellPosition } from '../../types/TableCellPosition';
export const useSetSoftFocusPosition = () => export const useSetSoftFocusPosition = () =>
useRecoilCallback(({ set, snapshot }) => { useRecoilCallback(({ set, snapshot }) => {

View File

@ -1,48 +0,0 @@
import { useCurrentTableCellEditMode } from '../table-cell/hooks/useCurrentTableCellEditMode';
import { useTableCell } from '../table-cell/hooks/useTableCell';
import { useMoveSoftFocus } from './useMoveSoftFocus';
export const useCellInputEventHandlers = <T>({
onSubmit,
onCancel,
}: {
onSubmit?: (newValue: T) => void;
onCancel?: () => void;
}) => {
const { closeTableCell: closeEditableCell } = useTableCell();
const { isCurrentTableCellInEditMode: isCurrentCellInEditMode } =
useCurrentTableCellEditMode();
const { moveRight, moveLeft, moveDown } = useMoveSoftFocus();
return {
handleClickOutside: (event: MouseEvent | TouchEvent, newValue: T) => {
if (isCurrentCellInEditMode) {
event.stopImmediatePropagation();
onSubmit?.(newValue);
closeEditableCell();
}
},
handleEscape: () => {
closeEditableCell();
onCancel?.();
},
handleEnter: (newValue: T) => {
onSubmit?.(newValue);
closeEditableCell();
moveDown();
},
handleTab: (newValue: T) => {
onSubmit?.(newValue);
closeEditableCell();
moveRight();
},
handleShiftTab: (newValue: T) => {
onSubmit?.(newValue);
closeEditableCell();
moveLeft();
},
};
};

View File

@ -1,9 +0,0 @@
import { useContext } from 'react';
import { RowIdContext } from '../contexts/RowIdContext';
export const useCurrentRowEntityId = () => {
const currentEntityId = useContext(RowIdContext);
return currentEntityId;
};

View File

@ -1,62 +0,0 @@
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { useDisableSoftFocus } from './useDisableSoftFocus';
import { useMoveSoftFocus } from './useMoveSoftFocus';
export const useMapKeyboardToSoftFocus = () => {
const { moveDown, moveLeft, moveRight, moveUp } = useMoveSoftFocus();
const disableSoftFocus = useDisableSoftFocus();
const setHotkeyScope = useSetHotkeyScope();
useScopedHotkeys(
[Key.ArrowUp, `${Key.Shift}+${Key.Enter}`],
() => {
moveUp();
},
TableHotkeyScope.TableSoftFocus,
[moveUp],
);
useScopedHotkeys(
Key.ArrowDown,
() => {
moveDown();
},
TableHotkeyScope.TableSoftFocus,
[moveDown],
);
useScopedHotkeys(
[Key.ArrowLeft, `${Key.Shift}+${Key.Tab}`],
() => {
moveLeft();
},
TableHotkeyScope.TableSoftFocus,
[moveLeft],
);
useScopedHotkeys(
[Key.ArrowRight, Key.Tab],
() => {
moveRight();
},
TableHotkeyScope.TableSoftFocus,
[moveRight],
);
useScopedHotkeys(
[Key.Escape],
() => {
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
disableSoftFocus();
},
TableHotkeyScope.TableSoftFocus,
[disableSoftFocus],
);
};

View File

@ -1,159 +0,0 @@
import { useRecoilCallback } from 'recoil';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { numberOfTableColumnsScopedSelector } from '../states/selectors/numberOfTableColumnsScopedSelector';
import { softFocusPositionState } from '../states/softFocusPositionState';
import { useSetSoftFocusPosition } from './useSetSoftFocusPosition';
// TODO: stories
export const useMoveSoftFocus = () => {
const tableScopeId = useRecoilScopeId(TableRecoilScopeContext);
const setSoftFocusPosition = useSetSoftFocusPosition();
const moveUp = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row - 1;
if (newRowNumber < 0) {
newRowNumber = 0;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveDown = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row + 1;
if (newRowNumber >= numberOfTableRows) {
newRowNumber = numberOfTableRows - 1;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveRight = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsScopedSelector(tableScopeId))
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsState)
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isLastRowAndLastColumn =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber === numberOfTableRows - 1;
const isLastColumnButNotLastRow =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber !== numberOfTableRows - 1;
const isNotLastColumn =
currentColumnNumber !== numberOfTableColumns - 1;
if (isLastRowAndLastColumn) {
return;
}
if (isNotLastColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber + 1,
});
} else if (isLastColumnButNotLastRow) {
setSoftFocusPosition({
row: currentRowNumber + 1,
column: 0,
});
}
},
[setSoftFocusPosition, tableScopeId],
);
const moveLeft = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsScopedSelector(tableScopeId))
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isFirstRowAndFirstColumn =
currentColumnNumber === 0 && currentRowNumber === 0;
const isFirstColumnButNotFirstRow =
currentColumnNumber === 0 && currentRowNumber > 0;
const isNotFirstColumn = currentColumnNumber > 0;
if (isFirstRowAndFirstColumn) {
return;
}
if (isNotFirstColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber - 1,
});
} else if (isFirstColumnButNotFirstRow) {
setSoftFocusPosition({
row: currentRowNumber - 1,
column: numberOfTableColumns - 1,
});
}
},
[setSoftFocusPosition, tableScopeId],
);
return {
moveDown,
moveLeft,
moveRight,
moveUp,
};
};

View File

@ -0,0 +1,316 @@
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { RecordTableScopeInternalContext } from '@/ui/object/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { onColumnsChangeScopedState } from '@/ui/object/record-table/states/onColumnsChangeScopedState';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getScopedState } from '@/ui/utilities/recoil-scope/utils/getScopedState';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { FieldMetadata } from '../../field/types/FieldMetadata';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
import { onEntityCountChangeScopedState } from '../states/onEntityCountChange';
import { numberOfTableColumnsScopedSelector } from '../states/selectors/numberOfTableColumnsScopedSelector';
import { softFocusPositionState } from '../states/softFocusPositionState';
import { ColumnDefinition } from '../types/ColumnDefinition';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { useDisableSoftFocus } from './internal/useDisableSoftFocus';
import { useGetIsSomeCellInEditMode } from './internal/useGetIsSomeCellInEditMode';
import { useLeaveTableFocus } from './internal/useLeaveTableFocus';
import { useRecordTableScopedStates } from './internal/useRecordTableScopedStates';
import { useResetTableRowSelection } from './internal/useResetTableRowSelection';
import { useSelectAllRows } from './internal/useSelectAllRows';
import { useSetRecordTableData } from './internal/useSetRecordTableData';
import { useSetRowSelectedState } from './internal/useSetRowSelectedState';
import { useSetSoftFocusPosition } from './internal/useSetSoftFocusPosition';
import { useUpsertRecordTableItem } from './internal/useUpsertRecordTableItem';
type useRecordTableProps = {
recordTableScopeId?: string;
};
export const useRecordTable = (props?: useRecordTableProps) => {
const scopeId = useAvailableScopeIdOrThrow(
RecordTableScopeInternalContext,
props?.recordTableScopeId,
);
const {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableColumnsState,
} = useRecordTableScopedStates({
customRecordTableScopeId: scopeId,
});
const setAvailableTableColumns = useSetRecoilState(
availableTableColumnsState,
);
const setTableFilters = useSetRecoilState(tableFiltersState);
const setTableSorts = useSetRecoilState(tableSortsState);
const setTableColumns = useSetRecoilState(tableColumnsState);
const onColumnsChange = useRecoilCallback(
({ snapshot }) =>
(columns: ColumnDefinition<FieldMetadata>[]) => {
const onColumnsChangeState = getScopedState(
onColumnsChangeScopedState,
scopeId,
);
const onColumnsChange = getSnapshotValue(
snapshot,
onColumnsChangeState,
);
onColumnsChange?.(columns);
},
[scopeId],
);
const onEntityCountChange = useRecoilCallback(
({ snapshot }) =>
(count: number) => {
const onEntityCountChangeState = getScopedState(
onEntityCountChangeScopedState,
scopeId,
);
const onEntityCountChange = getSnapshotValue(
snapshot,
onEntityCountChangeState,
);
onEntityCountChange?.(count);
},
[scopeId],
);
const setRecordTableData = useSetRecordTableData({ onEntityCountChange });
const leaveTableFocus = useLeaveTableFocus();
const getIsSomeCellInEditMode = useGetIsSomeCellInEditMode();
const setRowSelectedState = useSetRowSelectedState();
const resetTableRowSelection = useResetTableRowSelection();
const upsertRecordTableItem = useUpsertRecordTableItem();
const setSoftFocusPosition = useSetSoftFocusPosition();
const moveUp = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row - 1;
if (newRowNumber < 0) {
newRowNumber = 0;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveDown = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row + 1;
if (newRowNumber >= numberOfTableRows) {
newRowNumber = numberOfTableRows - 1;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveRight = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsScopedSelector(scopeId))
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsState)
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isLastRowAndLastColumn =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber === numberOfTableRows - 1;
const isLastColumnButNotLastRow =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber !== numberOfTableRows - 1;
const isNotLastColumn =
currentColumnNumber !== numberOfTableColumns - 1;
if (isLastRowAndLastColumn) {
return;
}
if (isNotLastColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber + 1,
});
} else if (isLastColumnButNotLastRow) {
setSoftFocusPosition({
row: currentRowNumber + 1,
column: 0,
});
}
},
[scopeId, setSoftFocusPosition],
);
const moveLeft = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsScopedSelector(scopeId))
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isFirstRowAndFirstColumn =
currentColumnNumber === 0 && currentRowNumber === 0;
const isFirstColumnButNotFirstRow =
currentColumnNumber === 0 && currentRowNumber > 0;
const isNotFirstColumn = currentColumnNumber > 0;
if (isFirstRowAndFirstColumn) {
return;
}
if (isNotFirstColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber - 1,
});
} else if (isFirstColumnButNotFirstRow) {
setSoftFocusPosition({
row: currentRowNumber - 1,
column: numberOfTableColumns - 1,
});
}
},
[scopeId, setSoftFocusPosition],
);
const useMapKeyboardToSoftFocus = () => {
const disableSoftFocus = useDisableSoftFocus();
const setHotkeyScope = useSetHotkeyScope();
useScopedHotkeys(
[Key.ArrowUp, `${Key.Shift}+${Key.Enter}`],
() => {
moveUp();
},
TableHotkeyScope.TableSoftFocus,
[moveUp],
);
useScopedHotkeys(
Key.ArrowDown,
() => {
moveDown();
},
TableHotkeyScope.TableSoftFocus,
[moveDown],
);
useScopedHotkeys(
[Key.ArrowLeft, `${Key.Shift}+${Key.Tab}`],
() => {
moveLeft();
},
TableHotkeyScope.TableSoftFocus,
[moveLeft],
);
useScopedHotkeys(
[Key.ArrowRight, Key.Tab],
() => {
moveRight();
},
TableHotkeyScope.TableSoftFocus,
[moveRight],
);
useScopedHotkeys(
[Key.Escape],
() => {
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
disableSoftFocus();
},
TableHotkeyScope.TableSoftFocus,
[disableSoftFocus],
);
};
const { selectAllRows } = useSelectAllRows();
return {
scopeId,
onColumnsChange,
setAvailableTableColumns,
setTableFilters,
setTableSorts,
setRecordTableData,
setTableColumns,
leaveTableFocus,
getIsSomeCellInEditMode,
setRowSelectedState,
resetTableRowSelection,
upsertRecordTableItem,
moveDown,
moveLeft,
moveRight,
moveUp,
useMapKeyboardToSoftFocus,
selectAllRows,
};
};

View File

@ -1,42 +1,35 @@
import { useCallback, useContext } from 'react'; import { useCallback } from 'react';
import { useSetRecoilState } from 'recoil'; import { useRecoilValue, useSetRecoilState } from 'recoil';
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata'; import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { useMoveViewColumns } from '@/ui/object/record-table/hooks/useMoveViewColumns'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState'; import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
import { TableContext } from '../contexts/TableContext';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { savedTableColumnsFamilyState } from '../states/savedTableColumnsFamilyState'; import { savedTableColumnsFamilyState } from '../states/savedTableColumnsFamilyState';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
export const useTableColumns = () => { import { useRecordTableScopedStates } from './internal/useRecordTableScopedStates';
const { onColumnsChange } = useContext(TableContext);
const [availableTableColumns] = useRecoilScopedState( export const useTableColumns = () => {
availableTableColumnsScopedState, const { onColumnsChange, setTableColumns } = useRecordTable();
TableRecoilScopeContext, const {
); availableTableColumnsState,
tableColumnsState,
visibleTableColumnsSelector,
} = useRecordTableScopedStates();
const availableTableColumns = useRecoilValue(availableTableColumnsState);
const { currentViewId } = useView(); const { currentViewId } = useView();
const setSavedTableColumns = useSetRecoilState( const setSavedTableColumns = useSetRecoilState(
savedTableColumnsFamilyState(currentViewId), savedTableColumnsFamilyState(currentViewId),
); );
const [tableColumns, setTableColumns] = useRecoilScopedState(
tableColumnsScopedState,
TableRecoilScopeContext,
);
const visibleTableColumns = useRecoilScopedValue( const tableColumns = useRecoilValue(tableColumnsState);
visibleTableColumnsScopedSelector, const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
TableRecoilScopeContext,
);
const { handleColumnMove } = useMoveViewColumns(); const { handleColumnMove } = useMoveViewColumns();
const handleColumnsChange = useCallback( const handleColumnsChange = useCallback(

View File

@ -1,33 +0,0 @@
import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState';
export const useUpsertRecordTableItems = () =>
useRecoilCallback(
({ set, snapshot }) =>
<T extends { id: string }>(entities: T[]) => {
// Create a map of new entities for quick lookup.
const newEntityMap = new Map(
entities.map((entity) => [entity.id, entity]),
);
// Filter out entities that are already the same in the state.
const entitiesToUpdate = entities.filter((entity) => {
const currentEntity = snapshot
.getLoadable(entityFieldsFamilyState(entity.id))
.valueMaybe();
return (
!currentEntity ||
JSON.stringify(currentEntity) !==
JSON.stringify(newEntityMap.get(entity.id))
);
});
// Batch set state for the filtered entities.
for (const entity of entitiesToUpdate) {
set(entityFieldsFamilyState(entity.id), entity);
}
},
[],
);

View File

@ -2,6 +2,9 @@ import { useRecoilCallback } from 'recoil';
import { tableRowIdsState } from '../states/tableRowIdsState'; import { tableRowIdsState } from '../states/tableRowIdsState';
// Used only in company table and people table
// Remove after refactoring
export const useUpsertTableRowId = () => export const useUpsertTableRowId = () =>
useRecoilCallback( useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>

View File

@ -1,17 +0,0 @@
import { useRecoilCallback } from 'recoil';
import { tableRowIdsState } from '../states/tableRowIdsState';
export const useUpsertTableRowIds = () =>
useRecoilCallback(
({ set, snapshot }) =>
(rowIds: string[]) => {
const currentRowIds = snapshot
.getLoadable(tableRowIdsState)
.valueOrThrow();
const uniqueRowIds = Array.from(new Set([...rowIds, ...currentRowIds]));
set(tableRowIdsState, uniqueRowIds);
},
[],
);

View File

@ -11,15 +11,12 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
import { useView } from '@/views/hooks/useView'; import { useView } from '@/views/hooks/useView';
import { useRecordTableScopedStates } from '../../hooks/internal/useRecordTableScopedStates';
import { useTableColumns } from '../../hooks/useTableColumns'; import { useTableColumns } from '../../hooks/useTableColumns';
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
import { hiddenTableColumnsScopedSelector } from '../../states/selectors/hiddenTableColumnsScopedSelector';
import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibleTableColumnsScopedSelector';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope'; import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
type TableOptionsMenu = 'fields'; type TableOptionsMenu = 'fields';
@ -43,14 +40,11 @@ export const TableOptionsDropdownContent = ({
const viewEditInputRef = useRef<HTMLInputElement>(null); const viewEditInputRef = useRef<HTMLInputElement>(null);
const visibleTableColumns = useRecoilScopedValue( const { hiddenTableColumnsSelector, visibleTableColumnsSelector } =
visibleTableColumnsScopedSelector, useRecordTableScopedStates();
TableRecoilScopeContext,
); const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
const hiddenTableColumns = useRecoilScopedValue( const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
hiddenTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const { handleColumnVisibilityChange, handleColumnReorder } = const { handleColumnVisibilityChange, handleColumnReorder } =
useTableColumns(); useTableColumns();

View File

@ -3,10 +3,10 @@ import { FieldInput } from '@/ui/object/field/components/FieldInput';
import { FieldInputEvent } from '@/ui/object/field/types/FieldInputEvent'; import { FieldInputEvent } from '@/ui/object/field/types/FieldInputEvent';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useMoveSoftFocus } from '../../hooks/useMoveSoftFocus'; import { useRecordTable } from '../../hooks/useRecordTable';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellContainer } from './TableCellContainer'; import { TableCellContainer } from './RecordTableCellContainer';
export const TableCell = ({ export const TableCell = ({
customHotkeyScope, customHotkeyScope,
@ -15,7 +15,7 @@ export const TableCell = ({
}) => { }) => {
const { closeTableCell } = useTableCell(); const { closeTableCell } = useTableCell();
const { moveLeft, moveRight, moveDown } = useMoveSoftFocus(); const { moveLeft, moveRight, moveDown } = useRecordTable();
const handleEnter: FieldInputEvent = (persistField) => { const handleEnter: FieldInputEvent = (persistField) => {
persistField(); persistField();

View File

@ -9,18 +9,18 @@ import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { CellHotkeyScopeContext } from '../../contexts/CellHotkeyScopeContext'; import { CellHotkeyScopeContext } from '../../contexts/CellHotkeyScopeContext';
import { ColumnIndexContext } from '../../contexts/ColumnIndexContext'; import { ColumnIndexContext } from '../../contexts/ColumnIndexContext';
import { useGetIsSomeCellInEditMode } from '../../hooks/useGetIsSomeCellInEditMode'; import { useRecordTable } from '../../hooks/useRecordTable';
import { useMoveSoftFocusToCurrentCellOnHover } from '../../hooks/useMoveSoftFocusToCurrentCellOnHover';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useCurrentTableCellEditMode } from '../hooks/useCurrentTableCellEditMode'; import { useCurrentTableCellEditMode } from '../hooks/useCurrentTableCellEditMode';
import { useIsSoftFocusOnCurrentTableCell } from '../hooks/useIsSoftFocusOnCurrentTableCell'; import { useIsSoftFocusOnCurrentTableCell } from '../hooks/useIsSoftFocusOnCurrentTableCell';
import { useMoveSoftFocusToCurrentCellOnHover } from '../hooks/useMoveSoftFocusToCurrentCellOnHover';
import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell'; import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellButton } from './TableCellButton'; import { TableCellButton } from './RecordTableCellButton';
import { TableCellDisplayMode } from './TableCellDisplayMode'; import { TableCellDisplayMode } from './RecordTableCellDisplayMode';
import { TableCellEditMode } from './TableCellEditMode'; import { TableCellEditMode } from './RecordTableCellEditMode';
import { TableCellSoftFocusMode } from './TableCellSoftFocusMode'; import { TableCellSoftFocusMode } from './RecordTableCellSoftFocusMode';
const StyledCellBaseContainer = styled.div` const StyledCellBaseContainer = styled.div`
align-items: center; align-items: center;
@ -57,7 +57,7 @@ export const TableCellContainer = ({
}: TableCellContainerProps) => { }: TableCellContainerProps) => {
const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode(); const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode();
const getIsSomeCellInEditMode = useGetIsSomeCellInEditMode(); const { getIsSomeCellInEditMode } = useRecordTable();
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);

View File

@ -3,7 +3,7 @@ import { useIsFieldInputOnly } from '@/ui/object/field/hooks/useIsFieldInputOnly
import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell'; import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellDisplayContainer } from './TableCellDisplayContainer'; import { TableCellDisplayContainer } from './RecordTableCellDisplayContainer';
export const TableCellDisplayMode = ({ export const TableCellDisplayMode = ({
children, children,

View File

@ -9,7 +9,7 @@ import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritin
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellDisplayContainer } from './TableCellDisplayContainer'; import { TableCellDisplayContainer } from './RecordTableCellDisplayContainer';
type TableCellSoftFocusModeProps = PropsWithChildren<unknown>; type TableCellSoftFocusModeProps = PropsWithChildren<unknown>;

View File

@ -1,7 +1,7 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { useMoveEditModeToTableCellPosition } from '../../hooks/useMoveEditModeToCellPosition'; import { useMoveEditModeToTableCellPosition } from '../../hooks/internal/useMoveEditModeToCellPosition';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState'; import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
import { useCurrentTableCellPosition } from './useCurrentCellPosition'; import { useCurrentTableCellPosition } from './useCurrentCellPosition';

View File

@ -2,10 +2,11 @@ import { useRecoilCallback } from 'recoil';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState'; import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState';
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState'; import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
import { useSetSoftFocusOnCurrentTableCell } from '../table-cell/hooks/useSetSoftFocusOnCurrentTableCell'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { useSetSoftFocusOnCurrentTableCell } from './useSetSoftFocusOnCurrentTableCell';
export const useMoveSoftFocusToCurrentCellOnHover = () => { export const useMoveSoftFocusToCurrentCellOnHover = () => {
const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell(); const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell();

View File

@ -2,7 +2,7 @@ import { useRecoilCallback } from 'recoil';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useSetSoftFocusPosition } from '../../hooks/useSetSoftFocusPosition'; import { useSetSoftFocusPosition } from '../../hooks/internal/useSetSoftFocusPosition';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState'; import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';

View File

@ -12,7 +12,7 @@ import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { CellHotkeyScopeContext } from '../../contexts/CellHotkeyScopeContext'; import { CellHotkeyScopeContext } from '../../contexts/CellHotkeyScopeContext';
import { ColumnIndexContext } from '../../contexts/ColumnIndexContext'; import { ColumnIndexContext } from '../../contexts/ColumnIndexContext';
import { useCloseCurrentTableCellInEditMode } from '../../hooks/useCloseCurrentTableCellInEditMode'; import { useCloseCurrentTableCellInEditMode } from '../../hooks/internal/useCloseCurrentTableCellInEditMode';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useCurrentTableCellEditMode } from './useCurrentTableCellEditMode'; import { useCurrentTableCellEditMode } from './useCurrentTableCellEditMode';

View File

@ -1,7 +1,7 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilCallback, useRecoilState } from 'recoil'; import { useRecoilCallback, useRecoilState } from 'recoil';
import { RowIdContext } from '../contexts/RowIdContext'; import { RowIdContext } from '../../contexts/RowIdContext';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState'; import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
export const useCurrentRowSelected = () => { export const useCurrentRowSelected = () => {

View File

@ -0,0 +1,37 @@
import { ReactNode } from 'react';
import { FieldMetadata } from '../../field/types/FieldMetadata';
import { ColumnDefinition } from '../types/ColumnDefinition';
import { RecordTableScopeInternalContext } from './scope-internal-context/RecordTableScopeInternalContext';
import { RecordTableScopeInitEffect } from './RecordTableScopeInitEffect';
type RecordTableScopeProps = {
children: ReactNode;
recordTableScopeId: string;
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
onEntityCountChange: (entityCount: number) => void;
};
export const RecordTableScope = ({
children,
recordTableScopeId,
onColumnsChange,
onEntityCountChange,
}: RecordTableScopeProps) => {
return (
<RecordTableScopeInternalContext.Provider
value={{
scopeId: recordTableScopeId,
onColumnsChange,
onEntityCountChange,
}}
>
<RecordTableScopeInitEffect
onColumnsChange={onColumnsChange}
onEntityCountChange={onEntityCountChange}
/>
{children}
</RecordTableScopeInternalContext.Provider>
);
};

View File

@ -0,0 +1,34 @@
import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
import { FieldMetadata } from '../../field/types/FieldMetadata';
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { ColumnDefinition } from '../types/ColumnDefinition';
type RecordTableScopeInitEffectProps = {
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
onEntityCountChange?: (count: number) => void | Promise<void>;
};
export const RecordTableScopeInitEffect = ({
onColumnsChange,
onEntityCountChange,
}: RecordTableScopeInitEffectProps) => {
const { onColumnsChangeState, onEntityCountChangeState } =
useRecordTableScopedStates();
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
const setOnColumnsChange = useSetRecoilState(onColumnsChangeState);
useEffect(() => {
setOnEntityCountChange(() => onEntityCountChange);
setOnColumnsChange(() => onColumnsChange);
}, [
onColumnsChange,
onEntityCountChange,
setOnColumnsChange,
setOnEntityCountChange,
]);
return <></>;
};

View File

@ -0,0 +1,13 @@
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { ScopedStateKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopedStateKey';
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
import { ColumnDefinition } from '../../types/ColumnDefinition';
type RecordTableScopeInternalContextProps = ScopedStateKey & {
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
onEntityCountChange: (entityCount: number) => void;
};
export const RecordTableScopeInternalContext =
createScopeInternalContext<RecordTableScopeInternalContextProps>();

View File

@ -1,13 +1,11 @@
import { atomFamily } from 'recoil';
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata'; import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
export const availableTableColumnsScopedState = atomFamily< export const availableTableColumnsScopedState = createScopedState<
ColumnDefinition<FieldMetadata>[], ColumnDefinition<FieldMetadata>[]
string
>({ >({
key: 'availableTableColumnsScopedState', key: 'availableTableColumnsScopedState',
default: [], defaultValue: [],
}); });

View File

@ -0,0 +1,11 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { FieldMetadata } from '../../field/types/FieldMetadata';
import { ColumnDefinition } from '../types/ColumnDefinition';
export const onColumnsChangeScopedState = createScopedState<
((columns: ColumnDefinition<FieldMetadata>[]) => void) | undefined
>({
key: 'onColumnsChangeScopedState',
defaultValue: undefined,
});

View File

@ -0,0 +1,8 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const onEntityCountChangeScopedState = createScopedState<
((entityCount: number) => void) | undefined
>({
key: 'onEntityCountChangeScopedState',
defaultValue: undefined,
});

View File

@ -1,3 +0,0 @@
import { createContext } from 'react';
export const TableRecoilScopeContext = createContext<string | null>(null);

View File

@ -8,10 +8,10 @@ export const hiddenTableColumnsScopedSelector = selectorFamily({
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => { ({ get }) => {
const columns = get(tableColumnsScopedState(scopeId)); const columns = get(tableColumnsScopedState({ scopeId }));
const columnKeys = columns.map(({ fieldId }) => fieldId); const columnKeys = columns.map(({ fieldId }) => fieldId);
const otherAvailableColumns = get( const otherAvailableColumns = get(
availableTableColumnsScopedState(scopeId), availableTableColumnsScopedState({ scopeId }),
).filter(({ fieldId }) => !columnKeys.includes(fieldId)); ).filter(({ fieldId }) => !columnKeys.includes(fieldId));
return [ return [

View File

@ -7,5 +7,5 @@ export const numberOfTableColumnsScopedSelector = selectorFamily({
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => ({ get }) =>
get(tableColumnsScopedState(scopeId)).length, get(tableColumnsScopedState({ scopeId })).length,
}); });

View File

@ -1,6 +1,6 @@
import { selector } from 'recoil'; import { selector } from 'recoil';
import { isRowSelectedFamilyState } from '../isRowSelectedFamilyState'; import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState';
import { tableRowIdsState } from '../tableRowIdsState'; import { tableRowIdsState } from '../tableRowIdsState';
export const selectedRowIdsSelector = selector<string[]>({ export const selectedRowIdsSelector = selector<string[]>({

View File

@ -10,7 +10,7 @@ export const tableColumnsByKeyScopedSelector = selectorFamily({
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => ({ get }) =>
get(tableColumnsScopedState(scopeId)).reduce< get(tableColumnsScopedState({ scopeId })).reduce<
Record<string, ColumnDefinition<FieldMetadata>> Record<string, ColumnDefinition<FieldMetadata>>
>((result, column) => ({ ...result, [column.fieldId]: column }), {}), >((result, column) => ({ ...result, [column.fieldId]: column }), {}),
}); });

View File

@ -10,7 +10,9 @@ export const tableSortsOrderByScopedSelector = selectorFamily({
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => { ({ get }) => {
const orderBy = reduceSortsToOrderBy(get(tableSortsScopedState(scopeId))); const orderBy = reduceSortsToOrderBy(
get(tableSortsScopedState({ scopeId })),
);
return orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }]; return orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }];
}, },
}); });

View File

@ -3,11 +3,13 @@ import { selectorFamily } from 'recoil';
import { turnFilterIntoWhereClause } from '../../../object-filter-dropdown/utils/turnFilterIntoWhereClause'; import { turnFilterIntoWhereClause } from '../../../object-filter-dropdown/utils/turnFilterIntoWhereClause';
import { tableFiltersScopedState } from '../tableFiltersScopedState'; import { tableFiltersScopedState } from '../tableFiltersScopedState';
export const tablefiltersWhereScopedSelector = selectorFamily({ export const tableFiltersWhereScopedSelector = selectorFamily({
key: 'tablefiltersWhereScopedSelector', key: 'tablefiltersWhereScopedSelector',
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => ({ ({ get }) => ({
AND: get(tableFiltersScopedState(scopeId)).map(turnFilterIntoWhereClause), AND: get(tableFiltersScopedState({ scopeId })).map(
turnFilterIntoWhereClause,
),
}), }),
}); });

View File

@ -8,9 +8,9 @@ export const visibleTableColumnsScopedSelector = selectorFamily({
get: get:
(scopeId: string) => (scopeId: string) =>
({ get }) => { ({ get }) => {
const columns = get(tableColumnsScopedState(scopeId)); const columns = get(tableColumnsScopedState({ scopeId }));
const availableColumnKeys = get( const availableColumnKeys = get(
availableTableColumnsScopedState(scopeId), availableTableColumnsScopedState({ scopeId }),
).map(({ fieldId }) => fieldId); ).map(({ fieldId }) => fieldId);
return [...columns] return [...columns]

View File

@ -1,13 +1,11 @@
import { atomFamily } from 'recoil';
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata'; import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
export const tableColumnsScopedState = atomFamily< export const tableColumnsScopedState = createScopedState<
ColumnDefinition<FieldMetadata>[], ColumnDefinition<FieldMetadata>[]
string
>({ >({
key: 'tableColumnsScopedState', key: 'tableColumnsScopedState',
default: [], defaultValue: [],
}); });

View File

@ -1,8 +1,8 @@
import { atomFamily } from 'recoil'; import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { Filter } from '../../object-filter-dropdown/types/Filter'; import { Filter } from '../../object-filter-dropdown/types/Filter';
export const tableFiltersScopedState = atomFamily<Filter[], string>({ export const tableFiltersScopedState = createScopedState<Filter[]>({
key: 'tableFiltersScopedState', key: 'tableFiltersScopedState',
default: [], defaultValue: [],
}); });

View File

@ -1,8 +1,8 @@
import { atomFamily } from 'recoil'; import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { Sort } from '../../object-sort-dropdown/types/Sort'; import { Sort } from '../../object-sort-dropdown/types/Sort';
export const tableSortsScopedState = atomFamily<Sort[], string>({ export const tableSortsScopedState = createScopedState<Sort[]>({
key: 'tableSortsScopedState', key: 'tableSortsScopedState',
default: [], defaultValue: [],
}); });

View File

@ -0,0 +1,79 @@
import { getScopedState } from '@/ui/utilities/recoil-scope/utils/getScopedState';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
import { onColumnsChangeScopedState } from '../states/onColumnsChangeScopedState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { tableFiltersWhereScopedSelector } from '../states/selectors/tablefiltersWhereScopedSelector';
import { tableSortsOrderByScopedSelector } from '../states/selectors/tableSortsOrderByScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { tableFiltersScopedState } from '../states/tableFiltersScopedState';
import { tableSortsScopedState } from '../states/tableSortsScopedState';
import { onEntityCountChangeScopedState } from './../states/onEntityCountChange';
export const getRecordTableScopedStates = ({
recordTableScopeId,
}: {
recordTableScopeId: string;
}) => {
const availableTableColumnsState = getScopedState(
availableTableColumnsScopedState,
recordTableScopeId,
);
const tableFiltersState = getScopedState(
tableFiltersScopedState,
recordTableScopeId,
);
const tableSortsState = getScopedState(
tableSortsScopedState,
recordTableScopeId,
);
const tableSortsOrderBySelector =
tableSortsOrderByScopedSelector(recordTableScopeId);
const tableFiltersWhereSelector =
tableFiltersWhereScopedSelector(recordTableScopeId);
const tableColumnsState = getScopedState(
tableColumnsScopedState,
recordTableScopeId,
);
const tableColumnsByKeySelector =
tableColumnsByKeyScopedSelector(recordTableScopeId);
const hiddenTableColumnsSelector =
hiddenTableColumnsScopedSelector(recordTableScopeId);
const visibleTableColumnsSelector =
visibleTableColumnsScopedSelector(recordTableScopeId);
const onColumnsChangeState = getScopedState(
onColumnsChangeScopedState,
recordTableScopeId,
);
const onEntityCountChangeState = getScopedState(
onEntityCountChangeScopedState,
recordTableScopeId,
);
return {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,
onColumnsChangeState,
onEntityCountChangeState,
};
};

View File

@ -21,7 +21,9 @@ export const useViewFilters = (viewScopeId: string) => {
}); });
const apolloClient = useApolloClient(); const apolloClient = useApolloClient();
const { currentViewFiltersState } = useViewScopedStates(); const { currentViewFiltersState } = useViewScopedStates({
customViewScopeId: viewScopeId,
});
const persistViewFilters = useRecoilCallback( const persistViewFilters = useRecoilCallback(
({ snapshot, set }) => ({ snapshot, set }) =>

View File

@ -21,7 +21,9 @@ export const useViewSorts = (viewScopeId: string) => {
}); });
const apolloClient = useApolloClient(); const apolloClient = useApolloClient();
const { currentViewSortsState } = useViewScopedStates(); const { currentViewSortsState } = useViewScopedStates({
customViewScopeId: viewScopeId,
});
const persistViewSorts = useRecoilCallback( const persistViewSorts = useRecoilCallback(
({ snapshot, set }) => ({ snapshot, set }) =>

View File

@ -14,10 +14,8 @@ import { PageHeader } from '@/ui/layout/page/PageHeader';
import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect'; import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect';
import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar'; import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar';
import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu'; import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu';
import { useUpsertRecordTableItem } from '@/ui/object/record-table/hooks/useUpsertRecordTableItem'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { useUpsertTableRowId } from '@/ui/object/record-table/hooks/useUpsertTableRowId'; import { useUpsertTableRowId } from '@/ui/object/record-table/hooks/useUpsertTableRowId';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useInsertOneCompanyMutation } from '~/generated/graphql'; import { useInsertOneCompanyMutation } from '~/generated/graphql';
const StyledTableContainer = styled.div` const StyledTableContainer = styled.div`
@ -27,7 +25,9 @@ const StyledTableContainer = styled.div`
export const Companies = () => { export const Companies = () => {
const [insertCompany] = useInsertOneCompanyMutation(); const [insertCompany] = useInsertOneCompanyMutation();
const upsertRecordTableItem = useUpsertRecordTableItem(); const { upsertRecordTableItem } = useRecordTable({
recordTableScopeId: 'companies',
});
const upsertTableRowIds = useUpsertTableRowId(); const upsertTableRowIds = useUpsertTableRowId();
const { triggerOptimisticEffects } = useOptimisticEffect(); const { triggerOptimisticEffects } = useOptimisticEffect();
@ -61,16 +61,11 @@ export const Companies = () => {
<PageAddButton onClick={handleAddButtonClick} /> <PageAddButton onClick={handleAddButtonClick} />
</PageHeader> </PageHeader>
<PageBody> <PageBody>
<RecoilScope <StyledTableContainer>
scopeId="companies" <CompanyTable />
CustomRecoilScopeContext={TableRecoilScopeContext} </StyledTableContainer>
> <RecordTableActionBar />
<StyledTableContainer> <RecordTableContextMenu />
<CompanyTable />
</StyledTableContainer>
<RecordTableActionBar />
<RecordTableContextMenu />
</RecoilScope>
</PageBody> </PageBody>
</PageContainer> </PageContainer>
</SpreadsheetImportProvider> </SpreadsheetImportProvider>

View File

@ -5,8 +5,6 @@ import { IconBuildingSkyscraper } from '@/ui/display/icon';
import { PageBody } from '@/ui/layout/page/PageBody'; import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer'; import { PageContainer } from '@/ui/layout/page/PageContainer';
import { PageHeader } from '@/ui/layout/page/PageHeader'; import { PageHeader } from '@/ui/layout/page/PageHeader';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
const StyledTableContainer = styled.div` const StyledTableContainer = styled.div`
display: flex; display: flex;
@ -18,11 +16,9 @@ export const CompaniesMockMode = () => {
<PageContainer> <PageContainer>
<PageHeader title="Companies" Icon={IconBuildingSkyscraper} /> <PageHeader title="Companies" Icon={IconBuildingSkyscraper} />
<PageBody> <PageBody>
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}> <StyledTableContainer>
<StyledTableContainer> <CompanyTableMockMode />
<CompanyTableMockMode /> </StyledTableContainer>
</StyledTableContainer>
</RecoilScope>
</PageBody> </PageBody>
</PageContainer> </PageContainer>
); );

View File

@ -12,10 +12,8 @@ import { PageHeader } from '@/ui/layout/page/PageHeader';
import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect'; import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect';
import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar'; import { RecordTableActionBar } from '@/ui/object/record-table/action-bar/components/RecordTableActionBar';
import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu'; import { RecordTableContextMenu } from '@/ui/object/record-table/context-menu/components/RecordTableContextMenu';
import { useUpsertRecordTableItem } from '@/ui/object/record-table/hooks/useUpsertRecordTableItem'; import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
import { useUpsertTableRowId } from '@/ui/object/record-table/hooks/useUpsertTableRowId'; import { useUpsertTableRowId } from '@/ui/object/record-table/hooks/useUpsertTableRowId';
import { TableRecoilScopeContext } from '@/ui/object/record-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useInsertOnePersonMutation } from '~/generated/graphql'; import { useInsertOnePersonMutation } from '~/generated/graphql';
const StyledTableContainer = styled.div` const StyledTableContainer = styled.div`
@ -25,7 +23,9 @@ const StyledTableContainer = styled.div`
export const People = () => { export const People = () => {
const [insertOnePerson] = useInsertOnePersonMutation(); const [insertOnePerson] = useInsertOnePersonMutation();
const upsertRecordTableItem = useUpsertRecordTableItem(); const { upsertRecordTableItem } = useRecordTable({
recordTableScopeId: 'people',
});
const upsertTableRowIds = useUpsertTableRowId(); const upsertTableRowIds = useUpsertTableRowId();
const { triggerOptimisticEffects } = useOptimisticEffect(); const { triggerOptimisticEffects } = useOptimisticEffect();
@ -57,16 +57,11 @@ export const People = () => {
<PageAddButton onClick={handleAddButtonClick} /> <PageAddButton onClick={handleAddButtonClick} />
</PageHeader> </PageHeader>
<PageBody> <PageBody>
<RecoilScope <StyledTableContainer>
scopeId="people" <PersonTable />
CustomRecoilScopeContext={TableRecoilScopeContext} </StyledTableContainer>
> <RecordTableActionBar />
<StyledTableContainer> <RecordTableContextMenu />
<PersonTable />
</StyledTableContainer>
<RecordTableActionBar />
<RecordTableContextMenu />
</RecoilScope>
</PageBody> </PageBody>
</PageContainer> </PageContainer>
</SpreadsheetImportProvider> </SpreadsheetImportProvider>