Refactor ObjectDataTable to work with new views system (#2274)
Complete work
This commit is contained in:
@ -79,6 +79,7 @@ const StyledTableContainer = styled.div`
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
type DataTableProps = {
|
||||
@ -121,20 +122,20 @@ export const DataTable = ({ updateEntityMutation }: DataTableProps) => {
|
||||
return (
|
||||
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
|
||||
<StyledTableWithHeader>
|
||||
<StyledTableContainer ref={tableBodyRef}>
|
||||
<StyledTableContainer>
|
||||
<ScrollWrapper>
|
||||
<div>
|
||||
<div ref={tableBodyRef}>
|
||||
<StyledTable className="entity-table-cell">
|
||||
<DataTableHeader />
|
||||
<DataTableBody />
|
||||
</StyledTable>
|
||||
<DragSelect
|
||||
dragSelectable={tableBodyRef}
|
||||
onDragSelectionStart={resetTableRowSelection}
|
||||
onDragSelectionChange={setRowSelectedState}
|
||||
/>
|
||||
</div>
|
||||
</ScrollWrapper>
|
||||
<DragSelect
|
||||
dragSelectable={tableBodyRef}
|
||||
onDragSelectionStart={resetTableRowSelection}
|
||||
onDragSelectionChange={setRowSelectedState}
|
||||
/>
|
||||
</StyledTableContainer>
|
||||
</StyledTableWithHeader>
|
||||
</EntityUpdateMutationContext.Provider>
|
||||
|
||||
@ -23,10 +23,8 @@ export const DataTableEffect = ({
|
||||
getRequestResultKey,
|
||||
getRequestOptimisticEffectDefinition,
|
||||
|
||||
filterDefinitionArray,
|
||||
setActionBarEntries,
|
||||
setContextMenuEntries,
|
||||
sortDefinitionArray,
|
||||
}: {
|
||||
useGetRequest: typeof useGetCompaniesQuery | typeof useGetPeopleQuery;
|
||||
getRequestResultKey: string;
|
||||
@ -59,7 +57,7 @@ export const DataTableEffect = ({
|
||||
onCompleted: (data: any) => {
|
||||
const entities = data[getRequestResultKey] ?? [];
|
||||
|
||||
setDataTableData(entities, filterDefinitionArray, sortDefinitionArray);
|
||||
setDataTableData(entities);
|
||||
|
||||
registerOptimisticEffect({
|
||||
variables: { orderBy: sortsOrderBy, where: tablefiltersWhere },
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { entityFieldsFamilyState } from '@/ui/data/field/states/entityFieldsFamilyState';
|
||||
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
||||
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { availableSortDefinitionsScopedState } from '@/views/states/availableSortDefinitionsScopedState';
|
||||
|
||||
import { SortDefinition } from '../../sort/types/SortDefinition';
|
||||
import { isFetchingDataTableDataState } from '../states/isFetchingDataTableDataState';
|
||||
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
|
||||
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableRowIdsState } from '../states/tableRowIdsState';
|
||||
|
||||
import { useResetTableRowSelection } from './useResetTableRowSelection';
|
||||
@ -18,15 +13,9 @@ export const useSetDataTableData = () => {
|
||||
const resetTableRowSelection = useResetTableRowSelection();
|
||||
const { setEntityCountInCurrentView } = useView();
|
||||
|
||||
const tableContextScopeId = useRecoilScopeId(TableRecoilScopeContext);
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
<T extends { id: string }>(
|
||||
newEntityArray: T[],
|
||||
filterDefinitionArray: FilterDefinition[],
|
||||
sortDefinitionArray: SortDefinition[],
|
||||
) => {
|
||||
<T extends { id: string }>(newEntityArray: T[]) => {
|
||||
for (const entity of newEntityArray) {
|
||||
const currentEntity = snapshot
|
||||
.getLoadable(entityFieldsFamilyState(entity.id))
|
||||
@ -50,16 +39,9 @@ export const useSetDataTableData = () => {
|
||||
resetTableRowSelection();
|
||||
|
||||
set(numberOfTableRowsState, entityIds.length);
|
||||
|
||||
setEntityCountInCurrentView(entityIds.length);
|
||||
|
||||
set(
|
||||
availableSortDefinitionsScopedState({ scopeId: tableContextScopeId }),
|
||||
sortDefinitionArray,
|
||||
);
|
||||
|
||||
set(isFetchingDataTableDataState, false);
|
||||
},
|
||||
[resetTableRowSelection, setEntityCountInCurrentView, tableContextScopeId],
|
||||
[resetTableRowSelection, setEntityCountInCurrentView],
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { Field } from '~/generated/graphql';
|
||||
|
||||
import { Filter } from '../types/Filter';
|
||||
|
||||
type FilterToTurnIntoWhereClause = Omit<Filter, 'definition'> & {
|
||||
definition: {
|
||||
type: Filter['definition']['type'];
|
||||
};
|
||||
};
|
||||
|
||||
export const turnFiltersIntoWhereClauseV2 = (
|
||||
filters: FilterToTurnIntoWhereClause[],
|
||||
fields: Pick<Field, 'id' | 'name'>[],
|
||||
) => {
|
||||
const whereClause: Record<string, any> = {};
|
||||
|
||||
filters.forEach((filter) => {
|
||||
const correspondingField = fields.find(
|
||||
(field) => field.id === filter.fieldId,
|
||||
);
|
||||
if (!correspondingField) {
|
||||
throw new Error(
|
||||
`Could not find field ${filter.fieldId} in metadata object`,
|
||||
);
|
||||
}
|
||||
|
||||
switch (filter.definition.type) {
|
||||
case 'text':
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.Contains:
|
||||
whereClause[correspondingField.name] = {
|
||||
eq: filter.value,
|
||||
};
|
||||
return;
|
||||
case ViewFilterOperand.DoesNotContain:
|
||||
whereClause[correspondingField.name] = {
|
||||
not: {
|
||||
eq: filter.value,
|
||||
},
|
||||
};
|
||||
return;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
|
||||
);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown filter type');
|
||||
}
|
||||
});
|
||||
return whereClause;
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
||||
import { availableSortDefinitionsScopedState } from '@/views/states/availableSortDefinitionsScopedState';
|
||||
|
||||
import { availableSortDefinitionsScopedState } from '../states/availableSortDefinitionsScopedState';
|
||||
import { isSortSelectedScopedState } from '../states/isSortSelectedScopedState';
|
||||
|
||||
export const useSortStates = (scopeId: string) => {
|
||||
|
||||
@ -2,7 +2,9 @@ import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScope
|
||||
|
||||
import { SortDefinition } from '../types/SortDefinition';
|
||||
|
||||
export const availableSortsScopedState = createScopedState<SortDefinition[]>({
|
||||
key: 'availableSortsScopedState',
|
||||
export const availableSortDefinitionsScopedState = createScopedState<
|
||||
SortDefinition[]
|
||||
>({
|
||||
key: 'availableSortDefinitionsScopedState',
|
||||
defaultValue: [],
|
||||
});
|
||||
@ -0,0 +1,26 @@
|
||||
import { Field } from '~/generated/graphql';
|
||||
|
||||
import { Sort } from '../types/Sort';
|
||||
|
||||
export const turnSortsIntoOrderByV2 = (
|
||||
sorts: Sort[],
|
||||
fields: Pick<Field, 'id' | 'name'>[],
|
||||
) => {
|
||||
const sortsObject: Record<string, 'AscNullsFirst' | 'DescNullsLast'> = {};
|
||||
sorts.forEach((sort) => {
|
||||
const correspondingField = fields.find(
|
||||
(field) => field.id === sort.fieldId,
|
||||
);
|
||||
if (!correspondingField) {
|
||||
throw new Error(
|
||||
`Could not find field ${sort.fieldId} in metadata object`,
|
||||
);
|
||||
}
|
||||
const direction =
|
||||
sort.direction === 'asc' ? 'AscNullsFirst' : 'DescNullsLast';
|
||||
|
||||
sortsObject[correspondingField.name] = direction;
|
||||
});
|
||||
|
||||
return sortsObject;
|
||||
};
|
||||
@ -42,6 +42,7 @@ const StyledWrapper = styled.div`
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { MemoryRouter } from 'react-router-dom';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTableActionBarEntries';
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
@ -12,7 +12,7 @@ import { actionBarOpenState } from '../../states/actionBarIsOpenState';
|
||||
import { ActionBar } from '../ActionBar';
|
||||
|
||||
const FilledActionBar = (props: { selectedIds: string[] }) => {
|
||||
const { setActionBarEntries } = useCompanyTableActionBarEntries();
|
||||
const { setActionBarEntries } = useCompanyTableContextMenuEntries();
|
||||
setActionBarEntries();
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
setActionBarOpenState(true);
|
||||
|
||||
Reference in New Issue
Block a user