download record sample - Import (#12489)

<img width="400" alt="Screenshot 2025-06-10 at 18 14 17"
src="https://github.com/user-attachments/assets/05591b46-c36d-45c6-a236-3469c29d7420"
/>


closes https://github.com/twentyhq/core-team-issues/issues/915

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Etienne
2025-06-16 16:01:27 +02:00
committed by GitHub
parent 79b8c4660c
commit c16ba6a7d7
32 changed files with 753 additions and 481 deletions

View File

@ -3,5 +3,7 @@ import { COMPOSITE_FIELD_TYPES } from '@/settings/data-model/types/CompositeFiel
export const ALL_SUB_FIELDS = COMPOSITE_FIELD_TYPES.flatMap(
(compositeFieldType) =>
SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[compositeFieldType].subFields,
SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[compositeFieldType].subFields.map(
(subField) => subField.subFieldName,
),
);

View File

@ -25,11 +25,16 @@ import {
} from 'twenty-ui/display';
import { FieldMetadataType } from '~/generated-metadata/graphql';
type CompositeSubFieldConfig<T> = {
subFieldName: keyof T;
subFieldLabel: string;
isImportable: boolean;
isFilterable: boolean;
};
export type SettingsCompositeFieldTypeConfig<T> = SettingsFieldTypeConfig<T> & {
subFields: (keyof T)[];
filterableSubFields: (keyof T)[];
labelBySubField: Record<keyof T, string>;
exampleValue: T;
subFields: CompositeSubFieldConfig<T>[];
exampleValues: [T, T, T];
};
type SettingsCompositeFieldTypeConfigArray = Record<
@ -41,215 +46,415 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = {
[FieldMetadataType.CURRENCY]: {
label: 'Currency',
Icon: IllustrationIconCurrency,
subFields: ['amountMicros', 'currencyCode'],
filterableSubFields: ['amountMicros', 'currencyCode'],
labelBySubField: {
amountMicros:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY]
.amountMicros,
currencyCode:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY]
.currencyCode,
},
exampleValue: {
amountMicros: 2000000000,
currencyCode: CurrencyCode.USD,
},
subFields: [
{
subFieldName: 'amountMicros',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY]
.amountMicros,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'currencyCode',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.CURRENCY]
.currencyCode,
isImportable: true,
isFilterable: true,
},
],
exampleValues: [
{
amountMicros: 2000000000,
currencyCode: CurrencyCode.USD,
},
{
amountMicros: 3000000000,
currencyCode: CurrencyCode.GBP,
},
{
amountMicros: 100000000,
currencyCode: CurrencyCode.AED,
},
],
category: 'Basic',
} as const satisfies SettingsCompositeFieldTypeConfig<FieldCurrencyValue>,
[FieldMetadataType.EMAILS]: {
label: 'Emails',
Icon: IllustrationIconMail,
subFields: ['primaryEmail', 'additionalEmails'],
filterableSubFields: ['primaryEmail', 'additionalEmails'],
labelBySubField: {
primaryEmail: 'Primary Email',
additionalEmails: 'Additional Emails',
},
exampleValue: {
primaryEmail: 'john@twenty.com',
additionalEmails: [
'tim@twenty.com',
'timapple@twenty.com',
'johnappletim@twenty.com',
],
},
subFields: [
{
subFieldName: 'primaryEmail',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.EMAILS]
.primaryEmail,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'additionalEmails',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.EMAILS]
.additionalEmails,
isImportable: true,
isFilterable: true,
},
],
exampleValues: [
{
primaryEmail: 'tim@twenty.com',
additionalEmails: [
'tim@twenty.com',
'timapple@twenty.com',
'johnappletim@twenty.com',
],
},
{
primaryEmail: 'jane@twenty.com',
additionalEmails: ['jane@twenty.com', 'jane.doe@twenty.com'],
},
{
primaryEmail: 'john@twenty.com',
additionalEmails: ['john.doe@twenty.com'],
},
],
category: 'Basic',
} as const satisfies SettingsCompositeFieldTypeConfig<FieldEmailsValue>,
[FieldMetadataType.LINKS]: {
label: 'Links',
Icon: IllustrationIconLink,
exampleValue: {
primaryLinkUrl: 'twenty.com',
primaryLinkLabel: '',
secondaryLinks: [{ url: 'twenty.com', label: 'Twenty' }],
},
category: 'Basic',
subFields: ['primaryLinkUrl', 'primaryLinkLabel', 'secondaryLinks'],
filterableSubFields: [
'primaryLinkUrl',
'primaryLinkLabel',
'secondaryLinks',
subFields: [
{
subFieldName: 'primaryLinkUrl',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.primaryLinkUrl,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'primaryLinkLabel',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.primaryLinkLabel,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'secondaryLinks',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.secondaryLinks,
isImportable: true,
isFilterable: true,
},
],
labelBySubField: {
primaryLinkUrl:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.primaryLinkUrl,
primaryLinkLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.primaryLinkLabel,
secondaryLinks:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.LINKS]
.secondaryLinks,
},
exampleValues: [
{
primaryLinkUrl: 'twenty.com',
primaryLinkLabel: '',
secondaryLinks: [{ url: 'twenty.com', label: 'Twenty' }],
},
{
primaryLinkUrl: 'github.com/twentyhq/twenty',
primaryLinkLabel: 'Twenty Repo',
secondaryLinks: [{ url: 'twenty.com', label: '' }],
},
{
primaryLinkUrl: 'react.dev',
primaryLinkLabel: '',
secondaryLinks: [],
},
],
category: 'Basic',
} as const satisfies SettingsCompositeFieldTypeConfig<FieldLinksValue>,
[FieldMetadataType.PHONES]: {
label: 'Phones',
Icon: IllustrationIconPhone,
exampleValue: {
primaryPhoneCallingCode: '+33',
primaryPhoneCountryCode: 'FR',
primaryPhoneNumber: '789012345',
additionalPhones: [
{ number: '617272323', callingCode: '+33', countryCode: 'FR' },
],
},
subFields: [
'primaryPhoneNumber',
'primaryPhoneCountryCode',
'primaryPhoneCallingCode',
'additionalPhones',
{
subFieldName: 'primaryPhoneCallingCode',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneCallingCode,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'primaryPhoneCountryCode',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneCountryCode,
isImportable: true,
isFilterable: false,
},
{
subFieldName: 'primaryPhoneNumber',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneNumber,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'additionalPhones',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.additionalPhones,
isImportable: true,
isFilterable: true,
},
],
filterableSubFields: [
'primaryPhoneNumber',
'primaryPhoneCallingCode',
'additionalPhones',
exampleValues: [
{
primaryPhoneCallingCode: '+33',
primaryPhoneCountryCode: 'FR',
primaryPhoneNumber: '789012345',
additionalPhones: [
{ number: '617272323', callingCode: '+33', countryCode: 'FR' },
],
},
{
primaryPhoneCallingCode: '+1',
primaryPhoneCountryCode: 'US',
primaryPhoneNumber: '612345789',
additionalPhones: [
{ number: '123456789', callingCode: '+1', countryCode: 'US' },
{ number: '617272323', callingCode: '+1', countryCode: 'US' },
],
},
{
primaryPhoneCallingCode: '+33',
primaryPhoneCountryCode: 'FR',
primaryPhoneNumber: '123456789',
additionalPhones: [],
},
],
labelBySubField: {
primaryPhoneNumber:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneNumber,
primaryPhoneCountryCode:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneCountryCode,
primaryPhoneCallingCode:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.primaryPhoneCallingCode,
additionalPhones:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.PHONES]
.additionalPhones,
},
category: 'Basic',
} as const satisfies SettingsCompositeFieldTypeConfig<FieldPhonesValue>,
[FieldMetadataType.FULL_NAME]: {
label: 'Full Name',
Icon: IllustrationIconUser,
exampleValue: { firstName: 'John', lastName: 'Doe' },
subFields: [
{
subFieldName: 'firstName',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME]
.firstName,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'lastName',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME]
.lastName,
isImportable: true,
isFilterable: true,
},
],
exampleValues: [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Doe' },
{ firstName: 'John', lastName: 'Smith' },
],
category: 'Basic',
subFields: ['firstName', 'lastName'],
filterableSubFields: ['firstName', 'lastName'],
labelBySubField: {
firstName:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME].firstName,
lastName:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.FULL_NAME].lastName,
},
} as const satisfies SettingsCompositeFieldTypeConfig<FieldFullNameValue>,
[FieldMetadataType.ADDRESS]: {
label: 'Address',
Icon: IllustrationIconMap,
subFields: [
'addressStreet1',
'addressStreet2',
'addressCity',
'addressState',
'addressCountry',
'addressPostcode',
'addressLat',
'addressLng',
{
subFieldName: 'addressStreet1',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressStreet1,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressStreet2',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressStreet2,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressCity',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressCity,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressState',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressState,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressCountry',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressCountry,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressPostcode',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressPostcode,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'addressLat',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressLat,
isImportable: false,
isFilterable: false,
},
{
subFieldName: 'addressLng',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressLng,
isImportable: false,
isFilterable: false,
},
],
filterableSubFields: [
'addressStreet1',
'addressStreet2',
'addressCity',
'addressState',
'addressCountry',
'addressPostcode',
exampleValues: [
{
addressStreet1: '456 Oak Street',
addressStreet2: '',
addressCity: 'Springfield',
addressState: 'California',
addressCountry: 'United States',
addressPostcode: '90210',
addressLat: 34.0522,
addressLng: -118.2437,
},
{
addressStreet1: '123 Main Street',
addressStreet2: '',
addressCity: 'New York',
addressState: 'New York',
addressCountry: 'United States',
addressPostcode: '10001',
addressLat: 40.7128,
addressLng: -74.006,
},
{
addressStreet1: '8 rue Saint-Anne',
addressStreet2: '',
addressCity: 'Paris',
addressState: 'Ile-de-France',
addressCountry: 'France',
addressPostcode: '75001',
addressLat: 40.7128,
addressLng: -74.006,
},
],
labelBySubField: {
addressStreet1:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressStreet1,
addressStreet2:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressStreet2,
addressCity:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS].addressCity,
addressState:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressState,
addressCountry:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressCountry,
addressPostcode:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS]
.addressPostcode,
addressLat:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS].addressLat,
addressLng:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ADDRESS].addressLng,
},
exampleValue: {
addressStreet1: '456 Oak Street',
addressStreet2: '',
addressCity: 'Springfield',
addressState: 'California',
addressCountry: 'United States',
addressPostcode: '90210',
addressLat: 34.0522,
addressLng: -118.2437,
},
category: 'Basic',
} as const satisfies SettingsCompositeFieldTypeConfig<FieldAddressValue>,
[FieldMetadataType.ACTOR]: {
label: 'Actor',
Icon: IllustrationIconSetting,
category: 'Basic',
subFields: ['source', 'name'],
filterableSubFields: ['source', 'name'],
labelBySubField: {
source: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].source,
name: COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].name,
workspaceMemberId:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR]
.workspaceMemberId,
context:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].context,
},
exampleValue: {
source: 'IMPORT',
name: 'name',
workspaceMemberId: 'id',
context: { provider: ConnectedAccountProvider.GOOGLE },
},
subFields: [
{
subFieldName: 'source',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].source,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'name',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].name,
isImportable: true,
isFilterable: true,
},
{
subFieldName: 'workspaceMemberId',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR]
.workspaceMemberId,
isImportable: true,
isFilterable: false,
},
{
subFieldName: 'context',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.ACTOR].context,
isImportable: true,
isFilterable: false,
},
],
exampleValues: [
{
source: 'IMPORT',
name: 'name',
workspaceMemberId: 'id',
context: { provider: ConnectedAccountProvider.GOOGLE },
},
{
source: 'MANUAL',
name: 'name',
workspaceMemberId: 'id',
context: { provider: ConnectedAccountProvider.MICROSOFT },
},
{
source: 'WEBHOOK',
name: 'name',
workspaceMemberId: 'id',
context: {},
},
],
} as const satisfies SettingsCompositeFieldTypeConfig<FieldActorValue>,
[FieldMetadataType.RICH_TEXT_V2]: {
label: 'Rich Text',
Icon: IllustrationIconText,
subFields: ['blocknote', 'markdown'],
filterableSubFields: [],
labelBySubField: {
blocknote:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2]
.blocknote,
markdown:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2]
.markdown,
},
exampleValue: {
blocknote: '[{"type":"heading","content":"Hello"}]',
markdown: '# Hello',
},
category: 'Basic',
subFields: [
{
subFieldName: 'blocknote',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2]
.blocknote,
isImportable: false,
isFilterable: false,
},
{
subFieldName: 'markdown',
subFieldLabel:
COMPOSITE_FIELD_SUB_FIELD_LABELS[FieldMetadataType.RICH_TEXT_V2]
.markdown,
isImportable: false,
isFilterable: false,
},
],
exampleValues: [
{
blocknote: '[{"type":"heading","content":"Hello"}]',
markdown: '# Hello',
},
{
blocknote: '[{"type":"heading","content":"Hello World"}]',
markdown: '# Hello World',
},
{
blocknote: '[{"type":"heading","content":"Hello Again"}]',
markdown: '# Hello Again',
},
],
} as const satisfies SettingsCompositeFieldTypeConfig<FieldRichTextV2Value>,
} as const satisfies SettingsCompositeFieldTypeConfigArray;

View File

@ -15,7 +15,6 @@ import {
import { DEFAULT_DATE_VALUE } from '@/settings/data-model/constants/DefaultDateValue';
import { SettingsFieldTypeCategoryType } from '@/settings/data-model/types/SettingsFieldTypeCategoryType';
import { SettingsNonCompositeFieldType } from '@/settings/data-model/types/SettingsNonCompositeFieldType';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import {
IconComponent,
IllustrationIconArray,
@ -31,13 +30,14 @@ import {
IllustrationIconToggle,
IllustrationIconUid,
} from 'twenty-ui/display';
import { FieldMetadataType } from '~/generated-metadata/graphql';
DEFAULT_DATE_VALUE.setFullYear(DEFAULT_DATE_VALUE.getFullYear() + 2);
export type SettingsFieldTypeConfig<T> = {
label: string;
Icon: IconComponent;
exampleValue?: T;
exampleValues?: [T, T, T];
category: SettingsFieldTypeCategoryType;
};
@ -52,44 +52,59 @@ export const SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS: SettingsNonCompositeFiel
[FieldMetadataType.UUID]: {
label: 'Unique ID',
Icon: IllustrationIconUid,
exampleValue: '00000000-0000-0000-0000-000000000000',
exampleValues: [
'00000000-0000-0000-0000-000000000000',
'00000000-0000-0000-0000-000000000001',
'00000000-0000-0000-0000-000000000002',
],
category: 'Advanced',
} as const satisfies SettingsFieldTypeConfig<FieldUUidValue>,
[FieldMetadataType.TEXT]: {
label: 'Text',
Icon: IllustrationIconText,
exampleValue:
exampleValues: [
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum magna enim, dapibus non enim in, lacinia faucibus nunc. Sed interdum ante sed felis facilisis, eget ultricies neque molestie. Mauris auctor, justo eu volutpat cursus, libero erat tempus nulla, non sodales lorem lacus a est.',
'Vestibulum magna enim, dapibus non enim in, lacinia faucibus nunc. Sed interdum ante sed felis facilisis, eget ultricies neque molestie. Mauris auctor, justo eu volutpat cursus, libero erat tempus nulla, non sodales lorem lacus a est.',
'Sed interdum ante sed felis facilisis, eget ultricies neque molestie. Mauris auctor, justo eu volutpat cursus, libero erat tempus nulla, non sodales lorem lacus a est.',
],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldTextValue>,
[FieldMetadataType.NUMERIC]: {
label: 'Numeric',
Icon: IllustrationIconNumbers,
exampleValue: 2000,
exampleValues: [2000, 3000, 4000],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldNumberValue>,
[FieldMetadataType.NUMBER]: {
label: 'Number',
Icon: IllustrationIconNumbers,
exampleValue: 2000,
exampleValues: [2000, 3000, 4000],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldNumberValue>,
[FieldMetadataType.BOOLEAN]: {
label: 'True/False',
Icon: IllustrationIconToggle,
exampleValue: true,
exampleValues: [true, false, true],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldBooleanValue>,
[FieldMetadataType.DATE_TIME]: {
label: 'Date and Time',
Icon: IllustrationIconCalendarTime,
exampleValue: DEFAULT_DATE_VALUE.toISOString(),
exampleValues: [
DEFAULT_DATE_VALUE.toISOString(),
'2025-06-10T12:01:00.000Z',
'2018-07-14T12:02:00.000Z',
],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldDateTimeValue>,
[FieldMetadataType.DATE]: {
label: 'Date',
Icon: IllustrationIconCalendarEvent,
exampleValue: DEFAULT_DATE_VALUE.toISOString(),
exampleValues: [
DEFAULT_DATE_VALUE.toISOString(),
'2025-06-10T00:00:00.000Z',
'2018-07-14T00:00:00.000Z',
],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldDateValue>,
[FieldMetadataType.SELECT]: {
@ -110,19 +125,19 @@ export const SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS: SettingsNonCompositeFiel
[FieldMetadataType.RATING]: {
label: 'Rating',
Icon: IllustrationIconStar,
exampleValue: 'RATING_3',
exampleValues: ['RATING_3', 'RATING_4', 'RATING_5'],
category: 'Basic',
} as const satisfies SettingsFieldTypeConfig<FieldRatingValue>,
[FieldMetadataType.RAW_JSON]: {
label: 'JSON',
Icon: IllustrationIconJson,
exampleValue: { key: 'value' },
exampleValues: [{ key: 'value1' }, { key: 'value2', key2: 'value2' }, {}],
category: 'Advanced',
} as const satisfies SettingsFieldTypeConfig<FieldJsonValue>,
[FieldMetadataType.ARRAY]: {
label: 'Array',
Icon: IllustrationIconArray,
category: 'Advanced',
exampleValue: ['value1', 'value2'],
exampleValues: [['value1', 'value2'], ['value3'], []],
} as const satisfies SettingsFieldTypeConfig<FieldArrayValue>,
};

View File

@ -51,7 +51,7 @@ describe('getFieldPreviewValue', () => {
// Then
expect(result).toBe(2000);
expect(result).toBe(
getSettingsFieldTypeConfig(FieldMetadataType.NUMBER).exampleValue,
getSettingsFieldTypeConfig(FieldMetadataType.NUMBER).exampleValues?.[0],
);
});

View File

@ -18,7 +18,7 @@ export const getAddressFieldPreviewValue = ({
FieldMetadataType.ADDRESS,
);
const placeholderDefaultValue = addressFieldTypeConfig.exampleValue;
const placeholderDefaultValue = addressFieldTypeConfig.exampleValues?.[0];
const addressCountry =
fieldMetadataItem.defaultValue?.addressCountry &&

View File

@ -20,7 +20,7 @@ export const getCurrencyFieldPreviewValue = ({
FieldMetadataType.CURRENCY,
);
const placeholderDefaultValue = currencyFieldTypeConfig.exampleValue;
const placeholderDefaultValue = currencyFieldTypeConfig.exampleValues?.[0];
return currencyFieldDefaultValueSchema
.transform((value) => ({

View File

@ -31,10 +31,10 @@ export const getFieldPreviewValue = ({
if (
isDefined(fieldTypeConfig) &&
'exampleValue' in fieldTypeConfig &&
isDefined(fieldTypeConfig.exampleValue)
'exampleValues' in fieldTypeConfig &&
isDefined(fieldTypeConfig.exampleValues?.[0])
) {
return fieldTypeConfig.exampleValue;
return fieldTypeConfig.exampleValues?.[0];
}
return null;

View File

@ -38,7 +38,7 @@ export const getPhonesFieldPreviewValue = ({
FieldMetadataType.PHONES,
);
const placeholderDefaultValue = phonesFieldTypeConfig.exampleValue;
const placeholderDefaultValue = phonesFieldTypeConfig.exampleValues?.[0];
const primaryPhoneCountryCode =
fieldMetadataItem.defaultValue?.primaryPhoneCountryCode &&
fieldMetadataItem.defaultValue.primaryPhoneCountryCode !== ''

View File

@ -5,9 +5,10 @@ import { COMPOSITE_FIELD_TYPES } from '@/settings/data-model/types/CompositeFiel
export const isValidSubFieldName = (
subFieldName: string,
): subFieldName is CompositeFieldSubFieldName => {
const allSubFields = COMPOSITE_FIELD_TYPES.flatMap(
(compositeFieldType) =>
SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[compositeFieldType].subFields,
const allSubFields = COMPOSITE_FIELD_TYPES.flatMap((compositeFieldType) =>
SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[compositeFieldType].subFields.map(
(subField) => subField.subFieldName,
),
);
return allSubFields.includes(subFieldName as any);