Support Full Name as Record Text Identifier (#11610)

closes #11296 


[recording.webm](https://github.com/user-attachments/assets/da0f2587-a435-4bee-a802-81eb9ca92733)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Gaurav
2025-05-20 03:33:30 +05:30
committed by GitHub
parent 477a10ba4a
commit 98e199c01d
6 changed files with 31 additions and 20 deletions

View File

@ -3,4 +3,5 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
export const LABEL_IDENTIFIER_FIELD_METADATA_TYPES = [ export const LABEL_IDENTIFIER_FIELD_METADATA_TYPES = [
FieldMetadataType.NUMBER, FieldMetadataType.NUMBER,
FieldMetadataType.TEXT, FieldMetadataType.TEXT,
FieldMetadataType.FULL_NAME,
]; ];

View File

@ -9,16 +9,16 @@ export const getLabelIdentifierFieldValue = (
labelIdentifierFieldMetadataItem: FieldMetadataItem | undefined, labelIdentifierFieldMetadataItem: FieldMetadataItem | undefined,
objectNameSingular: string, objectNameSingular: string,
): string => { ): string => {
if (!isDefined(labelIdentifierFieldMetadataItem)) {
return record.id;
}
if ( if (
objectNameSingular === CoreObjectNameSingular.WorkspaceMember || objectNameSingular === CoreObjectNameSingular.WorkspaceMember ||
labelIdentifierFieldMetadataItem?.type === FieldMetadataType.FULL_NAME labelIdentifierFieldMetadataItem.type === FieldMetadataType.FULL_NAME
) { ) {
return `${record.name?.firstName ?? ''} ${record.name?.lastName ?? ''}`; return `${record[labelIdentifierFieldMetadataItem.name]?.firstName ?? ''} ${record[labelIdentifierFieldMetadataItem.name]?.lastName ?? ''}`;
} }
if (isDefined(labelIdentifierFieldMetadataItem?.name)) { return record[labelIdentifierFieldMetadataItem.name] ?? '';
return record[labelIdentifierFieldMetadataItem.name] ?? '';
}
return '';
}; };

View File

@ -1,5 +1,4 @@
import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext'; import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext';
import { generateDefaultRecordChipData } from '@/object-metadata/utils/generateDefaultRecordChipData';
import { RecordChipData } from '@/object-record/record-field/types/RecordChipData'; import { RecordChipData } from '@/object-record/record-field/types/RecordChipData';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { useContext } from 'react'; import { useContext } from 'react';
@ -23,16 +22,13 @@ export const useRecordChipData = ({
const identifierChipGenerator = const identifierChipGenerator =
identifierChipGeneratorPerObject[objectNameSingular]; identifierChipGeneratorPerObject[objectNameSingular];
if (isDefined(identifierChipGenerator)) { if (!isDefined(identifierChipGenerator)) {
return { throw new Error(
recordChipData: identifierChipGenerator(record), `No identifier chip generator found for object name singular: ${objectNameSingular}`,
}; );
} }
return { return {
recordChipData: generateDefaultRecordChipData({ recordChipData: identifierChipGenerator(record),
objectNameSingular,
record,
}),
}; };
}; };

View File

@ -11,8 +11,8 @@ import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifie
import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldIdentifierDisplay'; import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldIdentifierDisplay';
import { RecordChipData } from '@/object-record/record-field/types/RecordChipData'; import { RecordChipData } from '@/object-record/record-field/types/RecordChipData';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataType } from '~/generated-metadata/graphql';
export const getRecordChipGenerators = ( export const getRecordChipGenerators = (
objectMetadataItems: ObjectMetadataItem[], objectMetadataItems: ObjectMetadataItem[],

View File

@ -13,7 +13,8 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { Select } from '@/ui/input/components/Select'; import { Select } from '@/ui/input/components/Select';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import { IconCircleOff, useIcons } from 'twenty-ui/display'; import { useNavigate } from 'react-router-dom';
import { IconCircleOff, IconPlus, useIcons } from 'twenty-ui/display';
import { SelectOption } from 'twenty-ui/input'; import { SelectOption } from 'twenty-ui/input';
export const settingsDataModelObjectIdentifiersFormSchema = export const settingsDataModelObjectIdentifiersFormSchema =
@ -100,6 +101,9 @@ export const SettingsDataModelObjectIdentifiersForm = ({
label: 'None', label: 'None',
value: null, value: null,
}; };
const navigate = useNavigate();
return ( return (
<StyledContainer> <StyledContainer>
{[ {[
@ -124,12 +128,23 @@ export const SettingsDataModelObjectIdentifiersForm = ({
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<Select <Select
label={label} label={label}
disabled={!objectMetadataItem.isCustom || !options.length}
fullWidth fullWidth
dropdownId={`${fieldName}-select`} dropdownId={`${fieldName}-select`}
emptyOption={emptyOption} emptyOption={emptyOption}
options={options} options={options}
value={value} value={value}
withSearchInput={label === t`Record label`}
callToActionButton={
label === t`Record label`
? {
text: 'Create Text Field',
Icon: IconPlus,
onClick: () => {
navigate('./new-field/select');
},
}
: undefined
}
onChange={(value) => { onChange={(value) => {
onChange(value); onChange(value);
formConfig.handleSubmit(handleSave)(); formConfig.handleSubmit(handleSave)();

View File

@ -50,7 +50,6 @@ const reservedKeywords = [
'links', 'links',
'currency', 'currency',
'currencies', 'currencies',
'fullName',
'fullNames', 'fullNames',
'address', 'address',
'addresses', 'addresses',