d5a7dec117
## Summary - Renames `ObjectMetadataItem` to `EnrichedObjectMetadataItem` across the entire frontend (~440 files) to clarify that this type includes derived fields (`readableFields`, `updatableFields`, nested `fields[]`, `indexMetadatas[]`) computed at read time from the metadata store - Creates `splitObjectMetadataGqlResponse` that goes directly from a GraphQL `ObjectMetadataItemsQuery` response to flat store items (combining the old `mapPaginatedObjectMetadataItemsToObjectMetadataItems` + `splitObjectMetadataItemWithRelated` two-step flow into one call) - Removes `ObjectMetadataItemWithRelated` type and all "WithRelated" naming - Renames `generatedMockObjectMetadataItems` to `generateTestEnrichedObjectMetadataItemsMock` to make it clear this is test-only enriched data - Deletes `useLoadMockedObjectMetadataItems` hook (consolidated into `useLoadMockedMinimalMetadata`) - Ensures nothing destined for the metadata store computes `readableFields`/`updatableFields` (preventing the localStorage bloat from #18809) ## Type hierarchy (before → after) **Before:** ``` ObjectMetadataItemsQuery → mapPaginated → ObjectMetadataItemWithRelated → enrich → ObjectMetadataItem → split → FlatObjectMetadataItem (store) ``` **After:** ``` ObjectMetadataItemsQuery → splitObjectMetadataGqlResponse → FlatObjectMetadataItem (store) → mapPaginated + enrich (tests only) → EnrichedObjectMetadataItem ``` ## Test plan - [x] `npx nx typecheck twenty-front` passes - [x] `npx nx test twenty-front` passes (767 suites, 4505 tests) - [x] `npx nx lint twenty-front` passes - [ ] CI checks pass Made with [Cursor](https://cursor.com)
77 lines
2.9 KiB
TypeScript
77 lines
2.9 KiB
TypeScript
import { type EnrichedObjectMetadataItem } from '@/object-metadata/types/EnrichedObjectMetadataItem';
|
|
import { isHiddenSystemField } from '@/object-metadata/utils/isHiddenSystemField';
|
|
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
|
|
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
|
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
|
|
|
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
|
import { availableFieldMetadataItemsForSortFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForSortFamilySelector';
|
|
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
|
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
|
import { useMemo } from 'react';
|
|
|
|
export const useColumnDefinitionsFromObjectMetadata = (
|
|
objectMetadataItem: EnrichedObjectMetadataItem,
|
|
) => {
|
|
const filterableFieldMetadataItems = useAtomFamilySelectorValue(
|
|
availableFieldMetadataItemsForFilterFamilySelector,
|
|
{
|
|
objectMetadataItemId: objectMetadataItem.id,
|
|
},
|
|
);
|
|
|
|
const sortableFieldMetadataItems = useAtomFamilySelectorValue(
|
|
availableFieldMetadataItemsForSortFamilySelector,
|
|
{
|
|
objectMetadataItemId: objectMetadataItem.id,
|
|
},
|
|
);
|
|
|
|
const columnDefinitions: ColumnDefinition<FieldMetadata>[] = useMemo(() => {
|
|
const activeFieldMetadataItems = objectMetadataItem.readableFields.filter(
|
|
(field) =>
|
|
field.isActive &&
|
|
(!isHiddenSystemField(field) ||
|
|
field.id === objectMetadataItem.labelIdentifierFieldMetadataId),
|
|
);
|
|
|
|
return activeFieldMetadataItems
|
|
.map((field, index) =>
|
|
formatFieldMetadataItemAsColumnDefinition({
|
|
position: index,
|
|
field,
|
|
objectMetadataItem,
|
|
}),
|
|
)
|
|
.filter(filterAvailableTableColumns)
|
|
.filter((column) => {
|
|
const restrictedFieldMetadataIds: string[] = [];
|
|
return !restrictedFieldMetadataIds.includes(column.fieldMetadataId);
|
|
})
|
|
.map((column) => {
|
|
const existsInFilterDefinitions = filterableFieldMetadataItems.some(
|
|
(fieldMetadataItem) =>
|
|
fieldMetadataItem.id === column.fieldMetadataId,
|
|
);
|
|
|
|
const existsInSortDefinitions = sortableFieldMetadataItems.some(
|
|
(fieldMetadataItem) =>
|
|
fieldMetadataItem.id === column.fieldMetadataId,
|
|
);
|
|
return {
|
|
...column,
|
|
isFilterable: existsInFilterDefinitions,
|
|
isSortable: existsInSortDefinitions,
|
|
};
|
|
});
|
|
}, [
|
|
filterableFieldMetadataItems,
|
|
sortableFieldMetadataItems,
|
|
objectMetadataItem,
|
|
]);
|
|
|
|
return {
|
|
columnDefinitions,
|
|
};
|
|
};
|