Refactor ObjectDataTable to work with new views system (#2274)
Complete work
This commit is contained in:
@ -1,6 +1,14 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableFiltersScopedState } from '@/ui/data/data-table/states/tableFiltersScopedState';
|
||||
import { tableSortsScopedState } from '@/ui/data/data-table/states/tableSortsScopedState';
|
||||
import { turnFiltersIntoWhereClauseV2 } from '@/ui/data/filter/utils/turnFiltersIntoWhereClauseV2';
|
||||
import { turnSortsIntoOrderByV2 } from '@/ui/data/sort/utils/turnSortsIntoOrderByV2';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
|
||||
import { useFindManyObjects } from '../hooks/useFindManyObjects';
|
||||
import { useMetadataObjectInContext } from '../hooks/useMetadataObjectInContext';
|
||||
import { useSetObjectDataTableData } from '../hooks/useSetDataTableData';
|
||||
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
|
||||
|
||||
@ -9,14 +17,33 @@ export type ObjectDataTableEffectProps = Pick<
|
||||
'objectNamePlural'
|
||||
>;
|
||||
|
||||
// TODO: merge in a single effect component
|
||||
// This should be migrated to DataTable at some point
|
||||
export const ObjectDataTableEffect = ({
|
||||
objectNamePlural,
|
||||
}: ObjectDataTableEffectProps) => {
|
||||
const setDataTableData = useSetObjectDataTableData();
|
||||
const { foundMetadataObject } = useMetadataObjectInContext();
|
||||
|
||||
const tableFilters = useRecoilScopedValue(
|
||||
tableFiltersScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const tableSorts = useRecoilScopedValue(
|
||||
tableSortsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const { objects, loading } = useFindManyObjects({
|
||||
objectNamePlural,
|
||||
objectNamePlural: objectNamePlural,
|
||||
filter: turnFiltersIntoWhereClauseV2(
|
||||
tableFilters,
|
||||
foundMetadataObject?.fields ?? [],
|
||||
),
|
||||
orderBy: turnSortsIntoOrderByV2(
|
||||
tableSorts,
|
||||
foundMetadataObject?.fields ?? [],
|
||||
),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -9,6 +9,7 @@ import { InlineCell } from '@/ui/data/inline-cell/components/InlineCell';
|
||||
import { PropertyBox } from '@/ui/data/inline-cell/property-box/components/PropertyBox';
|
||||
import { InlineCellHotkeyScope } from '@/ui/data/inline-cell/types/InlineCellHotkeyScope';
|
||||
import { IconBuildingSkyscraper } from '@/ui/display/icon';
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
import { PageBody } from '@/ui/layout/page/PageBody';
|
||||
import { PageContainer } from '@/ui/layout/page/PageContainer';
|
||||
import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton';
|
||||
@ -33,6 +34,8 @@ export const ObjectShowPage = () => {
|
||||
objectId: string;
|
||||
}>();
|
||||
|
||||
const { icons } = useLazyLoadIcons();
|
||||
|
||||
const { foundMetadataObject } = useFindOneMetadataObject({
|
||||
objectNameSingular,
|
||||
});
|
||||
@ -130,6 +133,7 @@ export const ObjectShowPage = () => {
|
||||
field: metadataField,
|
||||
position: index,
|
||||
metadataObject: foundMetadataObject,
|
||||
icons,
|
||||
}),
|
||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||
|
||||
@ -1,11 +1,23 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { DataTable } from '@/ui/data/data-table/components/DataTable';
|
||||
import { TableOptionsDropdownId } from '@/ui/data/data-table/constants/TableOptionsDropdownId';
|
||||
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
|
||||
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
||||
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
|
||||
import { tableFiltersScopedState } from '@/ui/data/data-table/states/tableFiltersScopedState';
|
||||
import { tableSortsScopedState } from '@/ui/data/data-table/states/tableSortsScopedState';
|
||||
import { ViewBar } from '@/views/components/ViewBar';
|
||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { columnDefinitionsToViewFields } from '@/views/utils/columnDefinitionToViewField';
|
||||
import { viewFieldsToColumnDefinitions } from '@/views/utils/viewFieldsToColumnDefinitions';
|
||||
import { viewFiltersToFilters } from '@/views/utils/viewFiltersToFilters';
|
||||
import { viewSortsToSorts } from '@/views/utils/viewSortsToSorts';
|
||||
|
||||
import { useMetadataObjectInContext } from '../hooks/useMetadataObjectInContext';
|
||||
import { useUpdateOneObject } from '../hooks/useUpdateOneObject';
|
||||
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
|
||||
|
||||
@ -28,9 +40,26 @@ export const ObjectTable = ({ objectNamePlural }: ObjectTableProps) => {
|
||||
const { updateOneObject } = useUpdateOneObject({
|
||||
objectNamePlural,
|
||||
});
|
||||
|
||||
const { columnDefinitions, foundMetadataObject } =
|
||||
useMetadataObjectInContext();
|
||||
const tableScopeId = foundMetadataObject?.namePlural ?? '';
|
||||
const viewScopeId = objectNamePlural ?? '';
|
||||
|
||||
const { persistViewFields } = useViewFields(viewScopeId);
|
||||
const { setCurrentViewFields } = useView({
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
const setTableColumns = useSetRecoilState(
|
||||
tableColumnsScopedState(tableScopeId),
|
||||
);
|
||||
|
||||
const setTableFilters = useSetRecoilState(
|
||||
tableFiltersScopedState(tableScopeId),
|
||||
);
|
||||
|
||||
const setTableSorts = useSetRecoilState(tableSortsScopedState(tableScopeId));
|
||||
|
||||
const updateEntity = ({
|
||||
variables,
|
||||
}: {
|
||||
@ -48,16 +77,32 @@ export const ObjectTable = ({ objectNamePlural }: ObjectTableProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<ViewScope viewScopeId={viewScopeId} onViewFieldsChange={() => {}}>
|
||||
<ViewScope
|
||||
viewScopeId={viewScopeId}
|
||||
onViewFieldsChange={(viewFields) => {
|
||||
setTableColumns(
|
||||
viewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
||||
);
|
||||
}}
|
||||
onViewFiltersChange={(viewFilters) => {
|
||||
setTableFilters(viewFiltersToFilters(viewFilters));
|
||||
}}
|
||||
onViewSortsChange={(viewSorts) => {
|
||||
setTableSorts(viewSortsToSorts(viewSorts));
|
||||
}}
|
||||
>
|
||||
<StyledContainer>
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
onColumnsChange: () => {},
|
||||
onColumnsChange: useRecoilCallback(() => (columns) => {
|
||||
setCurrentViewFields?.(columnDefinitionsToViewFields(columns));
|
||||
persistViewFields(columnDefinitionsToViewFields(columns));
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<ViewBar
|
||||
optionsDropdownButton={<TableOptionsDropdown />}
|
||||
optionsDropdownScopeId="table-dropdown-option"
|
||||
optionsDropdownScopeId={TableOptionsDropdownId}
|
||||
/>
|
||||
<ObjectTableEffect />
|
||||
<ObjectDataTableEffect objectNamePlural={objectNamePlural} />
|
||||
|
||||
@ -16,69 +16,43 @@ export const ObjectTableEffect = () => {
|
||||
setViewObjectId,
|
||||
} = useView();
|
||||
|
||||
// const [, setTableColumns] = useRecoilScopedState(
|
||||
// tableColumnsScopedState,
|
||||
// TableRecoilScopeContext,
|
||||
// );
|
||||
const {
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
sortDefinitions,
|
||||
foundMetadataObject,
|
||||
} = useMetadataObjectInContext();
|
||||
|
||||
// const [, setTableSorts] = useRecoilScopedState(
|
||||
// tableSortsScopedState,
|
||||
// TableRecoilScopeContext,
|
||||
// );
|
||||
|
||||
// const [, setTableFilters] = useRecoilScopedState(
|
||||
// tableFiltersScopedState,
|
||||
// TableRecoilScopeContext,
|
||||
// );
|
||||
|
||||
const { columnDefinitions, objectNamePlural } = useMetadataObjectInContext();
|
||||
const tableScopeId = foundMetadataObject?.namePlural ?? '';
|
||||
|
||||
const setAvailableTableColumns = useSetRecoilState(
|
||||
availableTableColumnsScopedState(objectNamePlural ?? ''),
|
||||
availableTableColumnsScopedState(tableScopeId),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setAvailableSortDefinitions?.([]); // TODO: extract from metadata fields
|
||||
setAvailableFilterDefinitions?.([]); // TODO: extract from metadata fields
|
||||
setAvailableFieldDefinitions?.(columnDefinitions);
|
||||
setViewObjectId?.(objectNamePlural);
|
||||
if (!foundMetadataObject) {
|
||||
return;
|
||||
}
|
||||
setViewObjectId?.(foundMetadataObject.id);
|
||||
setViewType?.(ViewType.Table);
|
||||
|
||||
setAvailableSortDefinitions?.(sortDefinitions);
|
||||
setAvailableFilterDefinitions?.(filterDefinitions);
|
||||
setAvailableFieldDefinitions?.(columnDefinitions);
|
||||
|
||||
setAvailableTableColumns(columnDefinitions);
|
||||
}, [
|
||||
setAvailableTableColumns,
|
||||
setViewObjectId,
|
||||
setViewType,
|
||||
columnDefinitions,
|
||||
objectNamePlural,
|
||||
setAvailableSortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setAvailableFieldDefinitions,
|
||||
foundMetadataObject,
|
||||
sortDefinitions,
|
||||
filterDefinitions,
|
||||
]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (currentViewFields) {
|
||||
// setTableColumns([...currentViewFields].sort((a, b) => a.index - b.index));
|
||||
// }
|
||||
// }, [currentViewFields, setTableColumns]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (currentViewSorts) {
|
||||
// setTableSorts(currentViewSorts);
|
||||
// }
|
||||
// }, [currentViewFields, currentViewSorts, setTableColumns, setTableSorts]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (currentViewFilters) {
|
||||
// setTableFilters(currentViewFilters);
|
||||
// }
|
||||
// }, [
|
||||
// currentViewFields,
|
||||
// currentViewFilters,
|
||||
// setTableColumns,
|
||||
// setTableFilters,
|
||||
// setTableSorts,
|
||||
// ]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@ -49,9 +49,7 @@ export const ObjectTablePage = () => {
|
||||
});
|
||||
|
||||
const handleAddButtonClick = async () => {
|
||||
createOneObject?.({
|
||||
name: 'Test',
|
||||
});
|
||||
createOneObject?.({});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -2,9 +2,14 @@ import { gql } from '@apollo/client';
|
||||
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
||||
import { SortDefinition } from '@/ui/data/sort/types/SortDefinition';
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
|
||||
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
|
||||
import { formatMetadataFieldAsColumnDefinition } from '../utils/formatMetadataFieldAsColumnDefinition';
|
||||
import { formatMetadataFieldAsFilterDefinition } from '../utils/formatMetadataFieldAsFilterDefinition';
|
||||
import { formatMetadataFieldAsSortDefinition } from '../utils/formatMetadataFieldAsSortDefinition';
|
||||
import { generateCreateOneObjectMutation } from '../utils/generateCreateOneObjectMutation';
|
||||
import { generateDeleteOneObjectMutation } from '../utils/generateDeleteOneObjectMutation';
|
||||
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
|
||||
@ -25,6 +30,8 @@ export const useFindOneMetadataObject = ({
|
||||
object.nameSingular === objectNameSingular,
|
||||
);
|
||||
|
||||
const { icons } = useLazyLoadIcons();
|
||||
|
||||
const objectNotFoundInMetadata =
|
||||
metadataObjects.length === 0 ||
|
||||
(metadataObjects.length > 0 && !foundMetadataObject);
|
||||
@ -35,6 +42,23 @@ export const useFindOneMetadataObject = ({
|
||||
position: index,
|
||||
field,
|
||||
metadataObject: foundMetadataObject,
|
||||
icons,
|
||||
}),
|
||||
) ?? [];
|
||||
|
||||
const filterDefinitions: FilterDefinition[] =
|
||||
foundMetadataObject?.fields.map((field) =>
|
||||
formatMetadataFieldAsFilterDefinition({
|
||||
field,
|
||||
icons,
|
||||
}),
|
||||
) ?? [];
|
||||
|
||||
const sortDefinitions: SortDefinition[] =
|
||||
foundMetadataObject?.fields.map((field) =>
|
||||
formatMetadataFieldAsSortDefinition({
|
||||
field,
|
||||
icons,
|
||||
}),
|
||||
) ?? [];
|
||||
|
||||
@ -93,6 +117,8 @@ export const useFindOneMetadataObject = ({
|
||||
foundMetadataObject,
|
||||
objectNotFoundInMetadata,
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
sortDefinitions,
|
||||
findManyQuery,
|
||||
findOneQuery,
|
||||
createOneMutation,
|
||||
|
||||
@ -13,15 +13,22 @@ export const useMetadataObjectInContext = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const { foundMetadataObject, loading, columnDefinitions } =
|
||||
useFindOneMetadataObject({
|
||||
objectNamePlural: context.objectNamePlural,
|
||||
});
|
||||
const {
|
||||
foundMetadataObject,
|
||||
loading,
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
sortDefinitions,
|
||||
} = useFindOneMetadataObject({
|
||||
objectNamePlural: context.objectNamePlural,
|
||||
});
|
||||
|
||||
return {
|
||||
...context,
|
||||
foundMetadataObject,
|
||||
loading,
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
sortDefinitions,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,16 +3,13 @@ import { useRecoilCallback } from 'recoil';
|
||||
import { useResetTableRowSelection } from '@/ui/data/data-table/hooks/useResetTableRowSelection';
|
||||
import { isFetchingDataTableDataState } from '@/ui/data/data-table/states/isFetchingDataTableDataState';
|
||||
import { numberOfTableRowsState } from '@/ui/data/data-table/states/numberOfTableRowsState';
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableRowIdsState } from '@/ui/data/data-table/states/tableRowIdsState';
|
||||
import { entityFieldsFamilyState } from '@/ui/data/field/states/entityFieldsFamilyState';
|
||||
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||
import { availableSortDefinitionsScopedState } from '@/views/states/availableSortDefinitionsScopedState';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
|
||||
export const useSetObjectDataTableData = () => {
|
||||
const resetTableRowSelection = useResetTableRowSelection();
|
||||
|
||||
const tableContextScopeId = useRecoilScopeId(TableRecoilScopeContext);
|
||||
const { setEntityCountInCurrentView } = useView();
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@ -40,14 +37,10 @@ export const useSetObjectDataTableData = () => {
|
||||
resetTableRowSelection();
|
||||
|
||||
set(numberOfTableRowsState, entityIds.length);
|
||||
|
||||
set(
|
||||
availableSortDefinitionsScopedState({ scopeId: tableContextScopeId }),
|
||||
[],
|
||||
);
|
||||
setEntityCountInCurrentView(entityIds.length);
|
||||
|
||||
set(isFetchingDataTableDataState, false);
|
||||
},
|
||||
[resetTableRowSelection, tableContextScopeId],
|
||||
[resetTableRowSelection, setEntityCountInCurrentView],
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,30 +1,20 @@
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { FieldType } from '@/ui/data/field/types/FieldType';
|
||||
import { IconBrandLinkedin } from '@/ui/display/icon';
|
||||
|
||||
import { MetadataObject } from '../types/MetadataObject';
|
||||
|
||||
const parseFieldType = (fieldType: string): FieldType => {
|
||||
if (fieldType === 'url') {
|
||||
return 'urlV2';
|
||||
}
|
||||
|
||||
if (fieldType === 'money') {
|
||||
return 'moneyAmountV2';
|
||||
}
|
||||
|
||||
return fieldType as FieldType;
|
||||
};
|
||||
import { parseFieldType } from './parseFieldType';
|
||||
|
||||
export const formatMetadataFieldAsColumnDefinition = ({
|
||||
position,
|
||||
field,
|
||||
metadataObject,
|
||||
icons,
|
||||
}: {
|
||||
position: number;
|
||||
field: MetadataObject['fields'][0];
|
||||
metadataObject: Omit<MetadataObject, 'fields'>;
|
||||
icons: Record<string, any>;
|
||||
}): ColumnDefinition<FieldMetadata> => ({
|
||||
position,
|
||||
fieldId: field.id,
|
||||
@ -35,7 +25,7 @@ export const formatMetadataFieldAsColumnDefinition = ({
|
||||
fieldName: field.name,
|
||||
placeHolder: field.label,
|
||||
},
|
||||
Icon: IconBrandLinkedin,
|
||||
Icon: icons[field.icon ?? 'Icon123'],
|
||||
isVisible: true,
|
||||
basePathToShowPage: `/object/${metadataObject.nameSingular}/`,
|
||||
});
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
||||
|
||||
import { MetadataObject } from '../types/MetadataObject';
|
||||
|
||||
export const formatMetadataFieldAsFilterDefinition = ({
|
||||
field,
|
||||
icons,
|
||||
}: {
|
||||
field: MetadataObject['fields'][0];
|
||||
icons: Record<string, any>;
|
||||
}): FilterDefinition => ({
|
||||
fieldId: field.id,
|
||||
label: field.label,
|
||||
Icon: icons[field.icon ?? 'Icon123'],
|
||||
type: 'text',
|
||||
});
|
||||
@ -0,0 +1,15 @@
|
||||
import { SortDefinition } from '@/ui/data/sort/types/SortDefinition';
|
||||
|
||||
import { MetadataObject } from '../types/MetadataObject';
|
||||
|
||||
export const formatMetadataFieldAsSortDefinition = ({
|
||||
field,
|
||||
icons,
|
||||
}: {
|
||||
field: MetadataObject['fields'][0];
|
||||
icons: Record<string, any>;
|
||||
}): SortDefinition => ({
|
||||
fieldId: field.id,
|
||||
label: field.label,
|
||||
Icon: icons[field.icon ?? 'Icon123'],
|
||||
});
|
||||
13
front/src/modules/metadata/utils/parseFieldType.ts
Normal file
13
front/src/modules/metadata/utils/parseFieldType.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { FieldType } from '@/ui/data/field/types/FieldType';
|
||||
|
||||
export const parseFieldType = (fieldType: string): FieldType => {
|
||||
if (fieldType === 'url') {
|
||||
return 'urlV2';
|
||||
}
|
||||
|
||||
if (fieldType === 'money') {
|
||||
return 'moneyAmountV2';
|
||||
}
|
||||
|
||||
return fieldType as FieldType;
|
||||
};
|
||||
Reference in New Issue
Block a user