Redesign Object/Field tables (#16844)

Redesign the data model pages for more clarity / better distinction
between fields and relations
This commit is contained in:
Félix Malfait
2025-12-30 09:49:55 +01:00
committed by GitHub
parent 8d130908c2
commit 4f1f0eb177
16 changed files with 571 additions and 200 deletions
@@ -18,6 +18,7 @@ import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { useEffect, useMemo, useState } from 'react';
import { useRecoilState } from 'recoil';
import { FieldMetadataType } from 'twenty-shared/types';
import { IconArchive, IconFilter, IconSearch } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { MenuItemToggle } from 'twenty-ui/navigation';
@@ -25,7 +26,18 @@ import { useMapFieldMetadataItemToSettingsObjectDetailTableItem } from '~/pages/
import { type SettingsObjectDetailTableItem } from '~/pages/settings/data-model/types/SettingsObjectDetailTableItem';
import { normalizeSearchText } from '~/utils/normalizeSearchText';
const GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_STANDARD: TableMetadata<SettingsObjectDetailTableItem> =
const StyledSearchAndFilterContainer = styled.div`
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;
const StyledSearchInput = styled(SettingsTextInput)`
flex: 1;
`;
const SETTINGS_OBJECT_FIELD_TABLE_METADATA: TableMetadata<SettingsObjectDetailTableItem> =
{
tableId: 'settingsObjectDetail',
fields: [
@@ -36,7 +48,7 @@ const GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_STANDARD: TableMetadata<Settings
align: 'left',
},
{
fieldLabel: msg`Field type`,
fieldLabel: msg`App`,
fieldName: 'fieldType',
fieldType: 'string',
align: 'left',
@@ -54,63 +66,23 @@ const GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_STANDARD: TableMetadata<Settings
},
};
const GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_CUSTOM: TableMetadata<SettingsObjectDetailTableItem> =
{
tableId: 'settingsObjectDetail',
fields: [
{
fieldLabel: msg`Name`,
fieldName: 'label',
fieldType: 'string',
align: 'left',
},
{
fieldLabel: msg`Identifier`,
fieldName: 'identifierType',
fieldType: 'string',
align: 'left',
},
{
fieldLabel: msg`Data type`,
fieldName: 'dataType',
fieldType: 'string',
align: 'left',
},
],
initialSort: {
fieldName: 'label',
orderBy: 'AscNullsLast',
},
};
const StyledSearchAndFilterContainer = styled.div`
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;
const StyledSearchInput = styled(SettingsTextInput)`
flex: 1;
`;
export type SettingsObjectFieldTableProps = {
objectMetadataItem: ObjectMetadataItem;
mode: 'view' | 'new-field';
excludeRelations?: boolean;
};
// TODO: find another way than using mode which feels like it could be replaced by another pattern
export const SettingsObjectFieldTable = ({
objectMetadataItem,
mode,
excludeRelations = false,
}: SettingsObjectFieldTableProps) => {
const { t } = useLingui();
const [searchTerm, setSearchTerm] = useState('');
const [showInactive, setShowInactive] = useState(true);
const tableMetadata = objectMetadataItem.isCustom
? GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_CUSTOM
: GET_SETTINGS_OBJECT_DETAIL_TABLE_METADATA_STANDARD;
const tableMetadata = SETTINGS_OBJECT_FIELD_TABLE_METADATA;
const { mapFieldMetadataItemToSettingsObjectDetailTableItem } =
useMapFieldMetadataItemToSettingsObjectDetailTableItem(objectMetadataItem);
@@ -130,14 +102,23 @@ export const SettingsObjectFieldTable = ({
(fieldMetadataItem) => !fieldMetadataItem.isSystem,
);
const fieldsToDisplay = excludeRelations
? nonSystemFields?.filter(
(fieldMetadataItem) =>
fieldMetadataItem.type !== FieldMetadataType.RELATION &&
fieldMetadataItem.type !== FieldMetadataType.MORPH_RELATION,
)
: nonSystemFields;
return (
nonSystemFields?.map(
fieldsToDisplay?.map(
mapFieldMetadataItemToSettingsObjectDetailTableItem,
) ?? []
);
}, [
settingsObjectFields,
mapFieldMetadataItemToSettingsObjectDetailTableItem,
excludeRelations,
]);
const sortedAllObjectSettingsDetailItems = useSortedArray(