Introduce main identifier to power RelationFieldDisplay (#2577)

* Introduce main identifier to power RelationFieldDisplay, FilterDrodown, TableFirstColumn

* Apply to RelationPicker
This commit is contained in:
Charles Bochet
2023-11-20 10:33:36 +01:00
committed by GitHub
parent 18ee95179e
commit 25950ab82a
75 changed files with 412 additions and 717 deletions

View File

@ -10,6 +10,13 @@ export type GenericFieldContextType = {
entityId: string;
recoilScopeId?: string;
hotkeyScope: string;
isMainIdentifier: boolean;
mainIdentifierMapper?: (record: any) => {
name: string;
avatarUrl?: string;
avatarType: string;
};
basePathToShowPage?: string;
};
export const FieldContext = createContext<GenericFieldContextType>(

View File

@ -10,10 +10,8 @@ export const useIsFieldEmpty = () => {
const isFieldEmpty = useRecoilValue(
isEntityFieldEmptyFamilySelector({
fieldDefinition: {
fieldMetadataId: fieldDefinition.fieldMetadataId,
label: fieldDefinition.label,
type: fieldDefinition.type,
metadata: fieldDefinition.metadata,
metadata: { ...fieldDefinition.metadata, mainIdentifierMapper: null },
},
entityId,
}),

View File

@ -18,6 +18,7 @@ export const FieldContextProvider = ({
<FieldContext.Provider
value={{
entityId: entityId ?? '1',
isMainIdentifier: false,
recoilScopeId: '1',
hotkeyScope: 'hotkey-scope',
fieldDefinition,

View File

@ -2,14 +2,12 @@ import { useChipField } from '../../hooks/useChipField';
import { ChipDisplay } from '../content-display/components/ChipDisplay';
export const ChipFieldDisplay = () => {
const { avatarFieldValue, contentFieldValue, entityType, entityId } =
useChipField();
const { avatarFieldValue, contentFieldValue, entityId } = useChipField();
return (
<ChipDisplay
displayName={contentFieldValue}
avatarUrlValue={avatarFieldValue}
entityType={entityType}
entityId={entityId}
/>
);

View File

@ -2,7 +2,7 @@ import { useDoubleTextChipField } from '../../hooks/useDoubleTextChipField';
import { ChipDisplay } from '../content-display/components/ChipDisplay';
export const DoubleTextChipFieldDisplay = () => {
const { avatarUrl, firstValue, secondValue, entityType, entityId } =
const { avatarUrl, firstValue, secondValue, entityId } =
useDoubleTextChipField();
const content = [firstValue, secondValue].filter(Boolean).join(' ');
@ -11,7 +11,6 @@ export const DoubleTextChipFieldDisplay = () => {
<ChipDisplay
displayName={content}
avatarUrlValue={avatarUrl}
entityType={entityType}
entityId={entityId}
/>
);

View File

@ -1,22 +1,23 @@
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
import { getEntityChipFromFieldMetadata } from '@/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata';
import { useRelationField } from '../../hooks/useRelationField';
export const RelationFieldDisplay = () => {
const { fieldValue, fieldDefinition } = useRelationField();
const entityChipProps = getEntityChipFromFieldMetadata(
fieldDefinition,
fieldValue,
);
if (!fieldValue || !fieldDefinition) {
return <></>;
}
const mainIdentifierMapped =
fieldDefinition.metadata.mainIdentifierMapper(fieldValue);
return (
<EntityChip
entityId={entityChipProps.entityId}
name={entityChipProps.name}
pictureUrl={entityChipProps.pictureUrl}
avatarType={entityChipProps.avatarType}
entityId={fieldValue.id}
name={mainIdentifierMapped.name}
avatarUrl={mainIdentifierMapped.avatarUrl}
avatarType={mainIdentifierMapped.avatarType}
/>
);
};

View File

@ -26,6 +26,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'date',
label: 'Date',

View File

@ -25,6 +25,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'email',
label: 'Email',

View File

@ -25,6 +25,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'enum',
label: 'Enum',

View File

@ -24,6 +24,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'money',
label: 'Money',

View File

@ -24,6 +24,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'number',
label: 'Number',

View File

@ -25,6 +25,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'phone',
label: 'Phone',

View File

@ -24,6 +24,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'text',
label: 'Text',

View File

@ -25,6 +25,7 @@ const meta: Meta = {
<FieldContext.Provider
value={{
entityId: '',
isMainIdentifier: false,
fieldDefinition: {
fieldMetadataId: 'URL',
label: 'URL',

View File

@ -1,45 +1,34 @@
import { CompanyChip } from '@/companies/components/CompanyChip';
import { PersonChip } from '@/people/components/PersonChip';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { getLogoUrlFromDomainName } from '~/utils';
import { logError } from '~/utils/logError';
type ChipDisplayProps = {
entityType: Entity;
displayName: string;
entityId: string | null;
avatarUrlValue?: string;
};
export const ChipDisplay = ({
entityType,
displayName,
entityId,
avatarUrlValue,
}: ChipDisplayProps) => {
switch (entityType) {
case Entity.Company: {
return (
<CompanyChip
id={entityId ?? ''}
name={displayName}
pictureUrl={getLogoUrlFromDomainName(avatarUrlValue)}
/>
);
}
case Entity.Person: {
return (
<PersonChip
id={entityId ?? ''}
name={displayName}
pictureUrl={avatarUrlValue}
/>
);
}
switch (true) {
// case Entity.Company: {
// return (
// <CompanyChip
// id={entityId ?? ''}
// name={displayName}
// avatarUrl={getLogoUrlFromDomainName(avatarUrlValue)}
// />
// );
// }
// case Entity.Person: {
// return (
// <PersonChip
// id={entityId ?? ''}
// name={displayName}
// avatarUrl={avatarUrlValue}
// />
// );
// }
default:
logError(
`Unknown relation type: "${entityType}" in DoubleTextChipDisplay`,
);
return <> </>;
}
};

View File

@ -1,42 +0,0 @@
import { EntityChipProps } from '@/ui/display/chip/components/EntityChip';
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
import { getLogoUrlFromDomainName } from '~/utils';
export const getEntityChipFromFieldMetadata = (
fieldDefinition: FieldDefinition<FieldRelationMetadata>,
fieldValue: any,
) => {
const { entityChipDisplayMapper } = fieldDefinition;
const { fieldName } = fieldDefinition.metadata;
const defaultChipValue: Pick<
EntityChipProps,
'name' | 'pictureUrl' | 'avatarType' | 'entityId'
> = {
name: '',
pictureUrl: '',
avatarType: 'rounded',
entityId: fieldValue?.id,
};
if (['accountOwner', 'person'].includes(fieldName) && fieldValue) {
return {
...defaultChipValue,
name: `${fieldValue.firstName} ${fieldValue.lastName}`,
};
}
if (fieldName === 'company' && fieldValue) {
return {
...defaultChipValue,
name: fieldValue.name,
pictureUrl: getLogoUrlFromDomainName(fieldValue.domainName),
};
}
return {
...defaultChipValue,
...entityChipDisplayMapper?.(fieldValue),
};
};

View File

@ -29,8 +29,6 @@ export const useChipField = () => {
}),
);
const entityType = fieldDefinition.metadata.relationType;
const fieldInitialValue = useFieldInitialValue();
const initialContentValue = fieldInitialValue?.isEmpty
@ -51,7 +49,6 @@ export const useChipField = () => {
avatarFieldValue,
initialAvatarValue,
setAvatarFieldValue,
entityType,
entityId,
hotkeyScope,
};

View File

@ -39,8 +39,6 @@ export const useDoubleTextChipField = () => {
const fullValue = [firstValue, secondValue].filter(Boolean).join(' ');
const entityType = fieldDefinition.metadata.entityType;
const fieldInitialValue = useFieldInitialValue();
const initialFirstValue = fieldInitialValue?.isEmpty
@ -68,7 +66,6 @@ export const useDoubleTextChipField = () => {
firstValue,
setFirstValue,
fullValue,
entityType,
entityId,
hotkeyScope,
initialAvatarUrl,

View File

@ -1,10 +1,8 @@
import { useEffect } from 'react';
import styled from '@emotion/styled';
import { CompanyPicker } from '@/companies/components/CompanyPicker';
import { PeoplePicker } from '@/people/components/PeoplePicker';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { WorkspaceMemberPicker } from '@/workspace-member/components/WorkspaceMemberPicker';
import { RelationPicker } from '@/ui/object/field/meta-types/input/components/internal/RelationPicker';
import { usePersistField } from '../../../hooks/usePersistField';
import { useRelationField } from '../../hooks/useRelationField';
@ -32,14 +30,21 @@ export const RelationFieldInput = ({
const persistField = usePersistField();
const handleSubmit = (newEntity: EntityForSelect | null) => {
onSubmit?.(() => persistField(newEntity?.originalEntity ?? null));
onSubmit?.(() => persistField(newEntity?.record ?? null));
};
useEffect(() => {}, [initialSearchValue]);
return (
<StyledRelationPickerContainer>
{fieldDefinition.metadata.fieldName === 'person' ? (
<RelationPicker
fieldDefinition={fieldDefinition}
recordId={initialValue?.id ?? ''}
onSubmit={handleSubmit}
onCancel={onCancel}
initialSearchFilter={initialSearchValue}
/>
{/* {fieldDefinition.metadata.fieldName === 'person' ? (
<PeoplePicker
personId={initialValue?.id ?? ''}
companyId={initialValue?.companyId ?? ''}
@ -47,13 +52,6 @@ export const RelationFieldInput = ({
onCancel={onCancel}
initialSearchFilter={initialSearchValue}
/>
) : fieldDefinition.metadata.fieldName === 'accountOwner' ? (
<WorkspaceMemberPicker
userId={initialValue?.id ?? ''}
onSubmit={handleSubmit}
onCancel={onCancel}
initialSearchFilter={initialSearchValue}
/>
) : fieldDefinition.metadata.fieldName === 'company' ? (
<CompanyPicker
companyId={initialValue?.id ?? ''}
@ -61,7 +59,7 @@ export const RelationFieldInput = ({
onCancel={onCancel}
initialSearchFilter={initialSearchValue}
/>
) : null}
) : null} */}
</StyledRelationPickerContainer>
);
};

View File

@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
@ -52,7 +51,6 @@ const ChipFieldInputWithContext = ({
contentFieldName: 'name',
urlFieldName: 'xURL',
placeHolder: 'X URL',
relationType: Entity.Person,
},
}}
entityId={entityId}

View File

@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
@ -67,7 +66,7 @@ const DoubleTextChipFieldInputWithContext = ({
secondValueFieldName: 'Second-text',
secondValuePlaceholder: 'Second-text',
avatarUrlFieldName: 'avatarUrl',
entityType: Entity.Person,
fieldName: '',
},
}}
entityId={entityId}

View File

@ -3,7 +3,6 @@ import { expect, jest } from '@storybook/jest';
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
@ -52,7 +51,6 @@ const RelationFieldInputWithContext = ({
iconName: 'IconLink',
metadata: {
fieldName: 'Relation',
relationType: Entity.Person,
},
}}
entityId={entityId}

View File

@ -0,0 +1,74 @@
import { useEffect } from 'react';
import { useQuery } from '@apollo/client';
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
import { IconUserCircle } from '@/ui/display/icon';
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
export type RelationPickerProps = {
recordId: string;
onSubmit: (newUser: EntityForSelect | null) => void;
onCancel?: () => void;
width?: number;
initialSearchFilter?: string | null;
fieldDefinition: FieldDefinition<FieldRelationMetadata>;
};
export const RelationPicker = ({
recordId,
onSubmit,
onCancel,
width,
initialSearchFilter,
fieldDefinition,
}: RelationPickerProps) => {
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
useRecoilScopedState(relationPickerSearchFilterScopedState);
useEffect(() => {
setRelationPickerSearchFilter(initialSearchFilter ?? '');
}, [initialSearchFilter, setRelationPickerSearchFilter]);
const { findManyQuery } = useFindOneObjectMetadataItem({
objectNameSingular: fieldDefinition.metadata.objectMetadataNameSingular,
});
const useFindManyQuery = (options: any) => useQuery(findManyQuery, options);
const workspaceMembers = useFilteredSearchEntityQuery({
queryHook: useFindManyQuery,
filters: [
{
fieldNames: fieldDefinition.metadata.searchFields,
filter: relationPickerSearchFilter,
},
],
orderByField: 'createdAt',
mappingFunction: fieldDefinition.metadata.mainIdentifierMapper,
selectedIds: recordId ? [recordId] : [],
objectNamePlural: fieldDefinition.metadata.objectMetadataNamePlural,
});
const handleEntitySelected = async (selectedUser: any | null | undefined) => {
onSubmit(selectedUser ?? null);
};
return (
<SingleEntitySelect
EmptyIcon={IconUserCircle}
emptyLabel="No Owner"
entitiesToSelect={workspaceMembers.entitiesToSelect}
loading={workspaceMembers.loading}
onCancel={onCancel}
onEntitySelected={handleEntitySelected}
selectedEntity={workspaceMembers.selectedEntities[0]}
width={width}
/>
);
};

View File

@ -34,10 +34,9 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
fieldDefinition,
entityId,
}: {
fieldDefinition: Pick<
FieldDefinition<FieldMetadata>,
'type' | 'metadata' | 'fieldMetadataId' | 'label'
>;
fieldDefinition: Pick<FieldDefinition<FieldMetadata>, 'type'> & {
metadata: Omit<FieldMetadata, 'mainIdentifierMapper'>;
};
entityId: string;
}) => {
return ({ get }) => {

View File

@ -1,5 +1,3 @@
import { AvatarType } from '@/users/components/Avatar';
import { FieldMetadata } from './FieldMetadata';
import { FieldType } from './FieldType';
@ -15,12 +13,5 @@ export type FieldDefinition<T extends FieldMetadata> = {
iconName: string;
type: FieldType;
metadata: T;
basePathToShowPage?: string;
infoTooltipContent?: string;
entityChipDisplayMapper?: (dataObject: any) => {
name: string;
pictureUrl?: string;
avatarType: AvatarType;
};
relationType?: FieldDefinitionRelationType;
};

View File

@ -1,5 +1,5 @@
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
import { ThemeColor } from '@/ui/theme/constants/colors';
export type FieldUuidMetadata = {
@ -58,14 +58,23 @@ export type FieldEmailMetadata = {
placeHolder: string;
};
export type FieldDefinitionRelationType =
| 'FROM_MANY_OBJECTS'
| 'FROM_ONE_OBJECT'
| 'TO_MANY_OBJECTS'
| 'TO_ONE_OBJECT';
export type FieldRelationMetadata = {
relationType: Entity;
fieldName: string;
useEditButton?: boolean;
relationType?: FieldDefinitionRelationType;
mainIdentifierMapper: MainIdentifierMapper;
searchFields: string[];
objectMetadataNameSingular: string;
objectMetadataNamePlural: string;
};
export type FieldChipMetadata = {
relationType: Entity;
contentFieldName: string;
urlFieldName: string;
placeHolder: string;
@ -84,7 +93,6 @@ export type FieldDoubleTextChipMetadata = {
secondValueFieldName: string;
secondValuePlaceholder: string;
avatarUrlFieldName: string;
entityType: Entity;
};
export type FieldProbabilityMetadata = {

View File

@ -0,0 +1,9 @@
import { AvatarType } from '@/users/components/Avatar';
export type MainIdentifierMapper = (record: any) => {
id: string;
name: string;
avatarUrl?: string;
avatarType: AvatarType;
record: any;
};

View File

@ -0,0 +1,14 @@
import { MainIdentifierMapper } from '@/ui/object/field/types/MainIdentifierMapper';
export type FieldDefinitionRelationType =
| 'FROM_MANY_OBJECTS'
| 'FROM_ONE_OBJECT'
| 'TO_MANY_OBJECTS'
| 'TO_ONE_OBJECT';
export type RelationFieldConfig = {
relationType?: FieldDefinitionRelationType;
mainIdentifierMapper: MainIdentifierMapper;
searchFields: string[];
objectMetadataNameSingular: string;
};

View File

@ -16,7 +16,7 @@ export const GenericEntityFilterChip = ({
entityId={filter.value}
name={filter.displayValue}
avatarType="rounded"
pictureUrl={filter.displayAvatarUrl}
avatarUrl={filter.displayAvatarUrl}
LeftIcon={Icon}
/>
);

View File

@ -1,9 +1,10 @@
import { useContext } from 'react';
import { useSetRecoilState } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
import { useRecordTableScopedStates } from '@/ui/object/record-table/hooks/internal/useRecordTableScopedStates';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { FieldContext } from '../../field/contexts/FieldContext';
@ -20,6 +21,9 @@ export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const currentRowId = useContext(RowIdContext);
const { objectMetadataConfigState } = useRecordTableScopedStates();
const objectMetadataConfig = useRecoilValue(objectMetadataConfigState);
const { setCurrentRowSelected } = useCurrentRowSelected();
@ -56,6 +60,10 @@ export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {
fieldDefinition: columnDefinition,
useUpdateEntityMutation: () => [updateEntityMutation, {}],
hotkeyScope: customHotkeyScope,
isMainIdentifier:
columnDefinition.fieldMetadataId ===
objectMetadataConfig?.mainIdentifierFieldMetadataId,
mainIdentifierMapper: objectMetadataConfig?.mainIdentifierMapper,
}}
>
<TableCell customHotkeyScope={{ scope: customHotkeyScope }} />

View File

@ -18,6 +18,7 @@ export const useRecordTableScopedStates = (args?: {
tableFiltersState,
tableSortsState,
tableColumnsState,
objectMetadataConfigState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,
@ -33,6 +34,7 @@ export const useRecordTableScopedStates = (args?: {
tableFiltersState,
tableSortsState,
tableColumnsState,
objectMetadataConfigState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,

View File

@ -43,6 +43,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
tableFiltersState,
tableSortsState,
tableColumnsState,
objectMetadataConfigState,
onEntityCountChangeState,
} = useRecordTableScopedStates({
customRecordTableScopeId: scopeId,
@ -54,6 +55,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
const setTableFilters = useSetRecoilState(tableFiltersState);
const setObjectMetadataConfig = useSetRecoilState(objectMetadataConfigState);
const setTableSorts = useSetRecoilState(tableSortsState);
@ -301,6 +303,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
setAvailableTableColumns,
setTableFilters,
setTableSorts,
setObjectMetadataConfig,
setOnEntityCountChange,
setRecordTableData,
setTableColumns,

View File

@ -37,7 +37,8 @@ export const useTableCell = () => {
const isEmpty = useIsFieldEmpty();
const { entityId, fieldDefinition } = useContext(FieldContext);
const { entityId, fieldDefinition, basePathToShowPage } =
useContext(FieldContext);
const [, setFieldInitialValue] = useRecoilState(
entityFieldInitialValueFamilyState({
@ -47,8 +48,8 @@ export const useTableCell = () => {
);
const openTableCell = (options?: { initialValue?: FieldInitialValue }) => {
if (isFirstColumnCell && !isEmpty && fieldDefinition.basePathToShowPage) {
navigate(`${fieldDefinition.basePathToShowPage}${entityId}`);
if (isFirstColumnCell && !isEmpty && basePathToShowPage) {
navigate(`${basePathToShowPage}${entityId}`);
return;
}

View File

@ -0,0 +1,8 @@
import { ObjectMetadataConfig } from '@/ui/object/record-table/types/ObjectMetadataConfig';
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const objectMetadataConfigScopedState =
createScopedState<ObjectMetadataConfig | null>({
key: 'objectMetadataConfigScopedState',
defaultValue: null,
});

View File

@ -0,0 +1,11 @@
import { AvatarType } from '@/users/components/Avatar';
export type ObjectMetadataConfig = {
mainIdentifierFieldMetadataId: string;
mainIdentifierMapper: (record: any) => {
name: string;
avatarUrl?: string;
avatarType: AvatarType;
};
basePathToShowPage: string;
};

View File

@ -1,3 +1,4 @@
import { objectMetadataConfigScopedState } from '@/ui/object/record-table/states/objectMetadataConfigScopedState';
import { getScopedState } from '@/ui/utilities/recoil-scope/utils/getScopedState';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
@ -36,6 +37,11 @@ export const getRecordTableScopedStates = ({
recordTableScopeId,
);
const objectMetadataConfigState = getScopedState(
objectMetadataConfigScopedState,
recordTableScopeId,
);
const tableColumnsByKeySelector =
tableColumnsByKeyScopedSelector(recordTableScopeId);
@ -60,6 +66,7 @@ export const getRecordTableScopedStates = ({
tableFiltersState,
tableSortsState,
tableColumnsState,
objectMetadataConfigState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,