diff --git a/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts b/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts index 27cee2fbd6f..eed6dc94227 100644 --- a/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts +++ b/packages/twenty-front/src/modules/object-metadata/graphql/mutations.ts @@ -34,6 +34,7 @@ export const CREATE_ONE_FIELD_METADATA_ITEM = gql` icon isCustom isActive + isUnique isNullable createdAt updatedAt @@ -59,6 +60,7 @@ export const UPDATE_ONE_FIELD_METADATA_ITEM = gql` icon isCustom isActive + isUnique isNullable createdAt updatedAt @@ -128,6 +130,7 @@ export const DELETE_ONE_FIELD_METADATA_ITEM = gql` icon isCustom isActive + isUnique isNullable createdAt updatedAt diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFieldMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFieldMetadataItem.ts index 730c1460fb6..b132423526d 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFieldMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__mocks__/useFieldMetadataItem.ts @@ -17,6 +17,7 @@ export const queries = { icon isCustom isActive + isUnique isNullable createdAt updatedAt @@ -99,6 +100,7 @@ export const queries = { icon isCustom isActive + isUnique isNullable createdAt updatedAt @@ -131,6 +133,7 @@ export const variables = { options: undefined, settings: undefined, isLabelSyncedWithName: true, + isUnique: undefined, objectMetadataId, type: 'TEXT', }, diff --git a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemInput.ts b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemInput.ts index 7f6c3be3f77..1f52a2fb289 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemInput.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemInput.ts @@ -13,6 +13,7 @@ export const formatFieldMetadataItemInput = ( | 'options' | 'settings' | 'isLabelSyncedWithName' + | 'isUnique' > >, ) => { @@ -25,5 +26,6 @@ export const formatFieldMetadataItemInput = ( options: input.options, settings: input.settings, isLabelSyncedWithName: input.isLabelSyncedWithName, + isUnique: input.isUnique, }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhonesFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhonesFieldInput.tsx index 793fd2a392b..e2abccdff6a 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhonesFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhonesFieldInput.tsx @@ -18,8 +18,6 @@ import { TEXT_INPUT_STYLE } from 'twenty-ui/theme'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString'; -export const DEFAULT_PHONE_CALLING_CODE = '1'; - const StyledCustomPhoneInputContainer = styled.div<{ hasItem: boolean; hasError?: boolean; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx index 60fa4a5721a..58f359bfbbd 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx @@ -18,7 +18,6 @@ type SettingsOptionCardContentSelectProps = { const StyledSelectContainer = styled.div` margin-left: auto; - width: 120px; `; export const SettingsOptionCardContentSelect = ({ diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm.tsx new file mode 100644 index 00000000000..1ba76a92357 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm.tsx @@ -0,0 +1,57 @@ +import { Controller, useFormContext } from 'react-hook-form'; + +import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; + +import { Separator } from '@/settings/components/Separator'; +import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect'; +import { canBeUnique } from '@/settings/data-model/fields/forms/utils/canBeUnique.util'; +import { t } from '@lingui/core/macro'; +import { IconKey } from 'twenty-ui/display'; +import { Toggle } from 'twenty-ui/input'; + +type SettingsDataModelFieldIsUniqueFormValues = { + isUnique: boolean; +}; + +type SettingsDataModelFieldIsUniqueFormProps = { + fieldMetadataItem: Pick; +}; + +export const SettingsDataModelFieldIsUniqueForm = ({ + fieldMetadataItem, +}: SettingsDataModelFieldIsUniqueFormProps) => { + const { control } = + useFormContext(); + + if (!canBeUnique(fieldMetadataItem)) { + return null; + } + + return ( + { + const isUnique = value ?? false; + + return ( + <> + + + onChange(value)} + /> + + + ); + }} + /> + ); +}; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard.tsx index 6d9cff7833e..efccbb72779 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard.tsx @@ -9,7 +9,8 @@ import { settingsDataModelFieldAddressFormSchema } from '@/settings/data-model/f import { SettingsDataModelFieldAddressSettingsFormCard } from '@/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressSettingsFormCard'; import { settingsDataModelFieldBooleanFormSchema } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm'; import { SettingsDataModelFieldBooleanSettingsFormCard } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanSettingsFormCard'; -import { settingsDataModelFieldtextFormSchema } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; +import { settingsDataModelFieldTextFormSchema } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm'; import { SettingsDataModelFieldTextSettingsFormCard } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard'; import { settingsDataModelFieldCurrencyFormSchema } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm'; import { SettingsDataModelFieldCurrencySettingsFormCard } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencySettingsFormCard'; @@ -32,6 +33,10 @@ import { } from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard'; import { FieldMetadataType } from '~/generated-metadata/graphql'; +const isUniqueFieldFormSchema = z.object({ + isUnique: z.boolean().nullable().optional(), +}); + const booleanFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.BOOLEAN) }) .merge(settingsDataModelFieldBooleanFormSchema); @@ -42,11 +47,13 @@ const currencyFieldFormSchema = z const dateFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.DATE) }) - .merge(settingsDataModelFieldDateFormSchema); + .merge(settingsDataModelFieldDateFormSchema) + .merge(isUniqueFieldFormSchema); const dateTimeFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.DATE_TIME) }) - .merge(settingsDataModelFieldDateFormSchema); + .merge(settingsDataModelFieldDateFormSchema) + .merge(isUniqueFieldFormSchema); const relationFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.RELATION) }) @@ -62,11 +69,13 @@ const multiSelectFieldFormSchema = z const numberFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.NUMBER) }) - .merge(settingsDataModelFieldNumberFormSchema); + .merge(settingsDataModelFieldNumberFormSchema) + .merge(isUniqueFieldFormSchema); const textFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.TEXT) }) - .merge(settingsDataModelFieldtextFormSchema); + .merge(settingsDataModelFieldTextFormSchema) + .merge(isUniqueFieldFormSchema); const addressFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.ADDRESS) }) @@ -74,27 +83,30 @@ const addressFieldFormSchema = z const phonesFieldFormSchema = z .object({ type: z.literal(FieldMetadataType.PHONES) }) - .merge(settingsDataModelFieldPhonesFormSchema); + .merge(settingsDataModelFieldPhonesFormSchema) + .merge(isUniqueFieldFormSchema); -const otherFieldsFormSchema = z.object({ - type: z.enum( - Object.keys( - omit(SETTINGS_FIELD_TYPE_CONFIGS, [ - FieldMetadataType.BOOLEAN, - FieldMetadataType.CURRENCY, - FieldMetadataType.RELATION, - FieldMetadataType.SELECT, - FieldMetadataType.MULTI_SELECT, - FieldMetadataType.DATE, - FieldMetadataType.DATE_TIME, - FieldMetadataType.NUMBER, - FieldMetadataType.ADDRESS, - FieldMetadataType.PHONES, - FieldMetadataType.TEXT, - ]), - ) as [FieldMetadataType, ...FieldMetadataType[]], - ), -}); +const otherFieldsFormSchema = z + .object({ + type: z.enum( + Object.keys( + omit(SETTINGS_FIELD_TYPE_CONFIGS, [ + FieldMetadataType.BOOLEAN, + FieldMetadataType.CURRENCY, + FieldMetadataType.RELATION, + FieldMetadataType.SELECT, + FieldMetadataType.MULTI_SELECT, + FieldMetadataType.DATE, + FieldMetadataType.DATE_TIME, + FieldMetadataType.NUMBER, + FieldMetadataType.ADDRESS, + FieldMetadataType.PHONES, + FieldMetadataType.TEXT, + ]), + ) as [FieldMetadataType, ...FieldMetadataType[]], + ), + }) + .merge(isUniqueFieldFormSchema); export const settingsDataModelFieldSettingsFormSchema = z.discriminatedUnion( 'type', @@ -144,6 +156,7 @@ const previewableTypes = [ FieldMetadataType.RELATION, FieldMetadataType.SELECT, FieldMetadataType.TEXT, + FieldMetadataType.UUID, ]; export const SettingsDataModelFieldSettingsFormCard = ({ @@ -249,6 +262,11 @@ export const SettingsDataModelFieldSettingsFormCard = ({ objectMetadataItem={objectMetadataItem} /> } + form={ + + } /> ); }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm.tsx index ad7463d07c3..613e00b299d 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm.tsx @@ -12,20 +12,26 @@ type SettingsDataModelFieldTextFormProps = { disabled?: boolean; fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'defaultValue' | 'settings' + | 'icon' + | 'label' + | 'type' + | 'defaultValue' + | 'settings' + | 'isUnique' + | 'isCustom' >; }; -export const textFieldDefaultValueSchema = z.object({ +const textFieldDefaultValueSchema = z.object({ displayedMaxRows: z.number().nullable(), }); -export const settingsDataModelFieldtextFormSchema = z.object({ +export const settingsDataModelFieldTextFormSchema = z.object({ settings: textFieldDefaultValueSchema, }); export type SettingsDataModelFieldTextFormValues = z.infer< - typeof settingsDataModelFieldtextFormSchema + typeof settingsDataModelFieldTextFormSchema >; export const SettingsDataModelFieldTextForm = ({ @@ -46,25 +52,23 @@ export const SettingsDataModelFieldTextForm = ({ const displayedMaxRows = value?.displayedMaxRows ?? 0; return ( - <> - - - dropdownId="text-wrap" - value={displayedMaxRows} - onChange={(value) => onChange({ displayedMaxRows: value })} - disabled={disabled} - options={TEXT_DATA_MODEL_SELECT_OPTIONS.map((option) => ({ - ...option, - label: t(option.label), - }))} - selectSizeVariant="small" - /> - - + + + dropdownId="text-wrap" + value={displayedMaxRows} + onChange={(value) => onChange({ displayedMaxRows: value })} + disabled={disabled} + options={TEXT_DATA_MODEL_SELECT_OPTIONS.map((option) => ({ + ...option, + label: t(option.label), + }))} + selectSizeVariant="small" + /> + ); }} /> diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard.tsx index 1f3c4f39517..49abe7c643a 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; import { SettingsDataModelFieldTextForm } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm'; import { SettingsDataModelFieldPreviewCard, @@ -14,7 +15,7 @@ type SettingsDataModelFieldTextSettingsFormCardProps = { disabled?: boolean; fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'defaultValue' + 'icon' | 'label' | 'type' | 'defaultValue' | 'isUnique' | 'isCustom' >; } & Pick; @@ -41,10 +42,15 @@ export const SettingsDataModelFieldTextSettingsFormCard = ({ /> } form={ - + <> + + + } /> ); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateSettingsFormCard.tsx index e6edc8a5bc4..f1ade5d0258 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateSettingsFormCard.tsx @@ -3,6 +3,7 @@ import { useFormContext } from 'react-hook-form'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; import { SettingsDataModelFieldDateForm, SettingsDataModelFieldDateFormValues, @@ -17,7 +18,7 @@ type SettingsDataModelFieldDateSettingsFormCardProps = { disabled?: boolean; fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'settings' + 'icon' | 'label' | 'type' | 'isUnique' | 'isCustom' | 'settings' >; } & Pick; @@ -60,10 +61,15 @@ export const SettingsDataModelFieldDateSettingsFormCard = ({ /> } form={ - + <> + + + } /> ); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberSettingsFormCard.tsx index 3a0ef61a3c9..5833bdd1ad3 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberSettingsFormCard.tsx @@ -2,6 +2,7 @@ import styled from '@emotion/styled'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; import { SettingsDataModelFieldNumberForm } from '@/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberForm'; import { SettingsDataModelFieldPreviewCard, @@ -13,7 +14,7 @@ type SettingsDataModelFieldNumberSettingsFormCardProps = { disabled?: boolean; fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'defaultValue' | 'settings' + 'icon' | 'label' | 'type' | 'defaultValue' | 'isUnique' | 'isCustom' >; } & Pick; @@ -43,10 +44,16 @@ export const SettingsDataModelFieldNumberSettingsFormCard = ({ /> } form={ - + <> + + + + } /> ); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesSettingsFormCard.tsx index 70210d1be69..42b10345611 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesSettingsFormCard.tsx @@ -4,6 +4,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; import { SettingsDataModelFieldPhonesForm } from '@/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm'; import { SettingsDataModelFieldPreviewCard, @@ -14,7 +15,7 @@ type SettingsDataModelFieldPhonesSettingsFormCardProps = { disabled?: boolean; fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'defaultValue' + 'icon' | 'label' | 'type' | 'defaultValue' | 'isUnique' | 'isCustom' >; } & Pick; @@ -36,10 +37,15 @@ export const SettingsDataModelFieldPhonesSettingsFormCard = ({ /> } form={ - + <> + + + } /> ); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard.tsx index 15a01bcb03f..1a481900046 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard.tsx @@ -4,6 +4,7 @@ import { z } from 'zod'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard'; +import { SettingsDataModelFieldIsUniqueForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIsUniqueForm'; import { settingsDataModelFieldMultiSelectFormSchema, SettingsDataModelFieldSelectForm, @@ -23,7 +24,13 @@ type SettingsDataModelFieldSelectOrMultiSelectFormValues = z.infer< type SettingsDataModelFieldSelectSettingsFormCardProps = { fieldMetadataItem: Pick< FieldMetadataItem, - 'icon' | 'label' | 'type' | 'defaultValue' | 'options' + | 'icon' + | 'label' + | 'type' + | 'defaultValue' + | 'options' + | 'isUnique' + | 'isCustom' >; } & Pick; @@ -57,9 +64,14 @@ export const SettingsDataModelFieldSelectSettingsFormCard = ({ /> } form={ - + <> + + + } /> ); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/utils/canBeUnique.util.ts b/packages/twenty-front/src/modules/settings/data-model/fields/forms/utils/canBeUnique.util.ts new file mode 100644 index 00000000000..fa57b658516 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/utils/canBeUnique.util.ts @@ -0,0 +1,22 @@ +import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType'; +import { SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsCompositeFieldTypeConfigs'; +import { FieldMetadataType } from 'twenty-shared/types'; + +export const canBeUnique = ( + field: Pick, +) => { + if ( + [FieldMetadataType.MORPH_RELATION, FieldMetadataType.RELATION].includes( + field.type, + ) || + (isCompositeFieldType(field.type) && + SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[field.type].subFields.every( + (subField) => !subField.isIncludedInUniqueConstraint, + )) + ) { + return false; + } + + return true; +}; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue.ts b/packages/twenty-front/src/modules/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue.ts index 903f2dad91e..e53da47f5e2 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue.ts +++ b/packages/twenty-front/src/modules/settings/data-model/fields/preview/utils/getPhonesFieldPreviewValue.ts @@ -1,5 +1,4 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { DEFAULT_PHONE_CALLING_CODE } from '@/object-record/record-field/meta-types/input/components/PhonesFieldInput'; import { FieldPhonesValue } from '@/object-record/record-field/types/FieldMetadata'; import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig'; import { @@ -16,12 +15,12 @@ const isStrCountryCodeGuard = (str: string): str is CountryCode => { export const countryCodeToCallingCode = (countryCode: string): string => { if (!countryCode || !isStrCountryCodeGuard(countryCode)) { - return `+${DEFAULT_PHONE_CALLING_CODE}`; + return ''; } const callingCode = getCountryCallingCode(countryCode); - return callingCode ? `+${callingCode}` : `+${DEFAULT_PHONE_CALLING_CODE}`; + return callingCode ? `+${callingCode}` : ''; }; export const getPhonesFieldPreviewValue = ({ diff --git a/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx index bcac8f21b49..63bd7280e86 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx @@ -3,7 +3,6 @@ import React, { useMemo } from 'react'; import { FieldPhonesValue } from '@/object-record/record-field/types/FieldMetadata'; import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList'; -import { DEFAULT_PHONE_CALLING_CODE } from '@/object-record/record-field/meta-types/input/components/PhonesFieldInput'; import { styled } from '@linaria/react'; import { parsePhoneNumber } from 'libphonenumber-js'; import { isDefined } from 'twenty-shared/utils'; @@ -49,7 +48,7 @@ export const PhonesDisplay = ({ callingCode: value.primaryPhoneCallingCode || value.primaryPhoneCountryCode || - `+${DEFAULT_PHONE_CALLING_CODE}`, + '', } : null, ...parseAdditionalPhones(value?.additionalPhones), diff --git a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/validate-can-create-unique-index.util.spec.ts b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/validate-can-create-unique-index.util.spec.ts index a0fb079b051..fd1a3204cf3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/validate-can-create-unique-index.util.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/__tests__/validate-can-create-unique-index.util.spec.ts @@ -8,7 +8,6 @@ describe('validateCanCreateUniqueIndex', () => { const field = { name: 'testField', type: FieldMetadataType.MORPH_RELATION, - isCustom: true, }; expect(() => validateCanCreateUniqueIndex(field)).toThrow( @@ -23,7 +22,6 @@ describe('validateCanCreateUniqueIndex', () => { const field = { name: 'testField', type: FieldMetadataType.RELATION, - isCustom: true, }; expect(() => validateCanCreateUniqueIndex(field)).toThrow( @@ -38,7 +36,6 @@ describe('validateCanCreateUniqueIndex', () => { const field = { name: 'testField', type: FieldMetadataType.FULL_NAME, - isCustom: true, }; expect(() => validateCanCreateUniqueIndex(field)).toThrow( @@ -53,7 +50,6 @@ describe('validateCanCreateUniqueIndex', () => { const field = { name: 'testField', type: FieldMetadataType.ADDRESS, - isCustom: true, }; expect(() => validateCanCreateUniqueIndex(field)).toThrow( diff --git a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/validate-can-create-unique-index.util.ts b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/validate-can-create-unique-index.util.ts index 35569211f3d..01628373ce6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/validate-can-create-unique-index.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/index-metadata/utils/validate-can-create-unique-index.util.ts @@ -10,17 +10,8 @@ import { import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; export const validateCanCreateUniqueIndex = ( - field: Pick, + field: Pick, ) => { - if (field.isCustom === false) - throw new FieldMetadataException( - `Unique index cannot be created on standard field`, - FieldMetadataExceptionCode.INVALID_FIELD_INPUT, - { - userFriendlyMessage: t`Standard fields cannot be unique.`, - }, - ); - const isCompositeFieldWithNonIncludedUniqueConstraint = isCompositeFieldMetadataType(field.type) && !compositeTypeDefinitions