diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 64d5248023f6..7b49d1c42fcb 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -352,15 +352,12 @@ export enum FieldMetadataType { Currency = 'CURRENCY', Date = 'DATE', DateTime = 'DATE_TIME', - Email = 'EMAIL', Emails = 'EMAILS', FullName = 'FULL_NAME', - Link = 'LINK', Links = 'LINKS', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', Numeric = 'NUMERIC', - Phone = 'PHONE', Phones = 'PHONES', Position = 'POSITION', Rating = 'RATING', diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index a1d58b1d9dd3..9e930133b3fb 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -263,15 +263,12 @@ export enum FieldMetadataType { Currency = 'CURRENCY', Date = 'DATE', DateTime = 'DATE_TIME', - Email = 'EMAIL', Emails = 'EMAILS', FullName = 'FULL_NAME', - Link = 'LINK', Links = 'LINKS', MultiSelect = 'MULTI_SELECT', Number = 'NUMBER', Numeric = 'NUMERIC', - Phone = 'PHONE', Phones = 'PHONES', Position = 'POSITION', Rating = 'RATING', diff --git a/packages/twenty-front/src/modules/object-metadata/constants/SortableFieldMetadataTypes.ts b/packages/twenty-front/src/modules/object-metadata/constants/SortableFieldMetadataTypes.ts index 282710253650..f3599783cf7e 100644 --- a/packages/twenty-front/src/modules/object-metadata/constants/SortableFieldMetadataTypes.ts +++ b/packages/twenty-front/src/modules/object-metadata/constants/SortableFieldMetadataTypes.ts @@ -7,8 +7,6 @@ export const SORTABLE_FIELD_METADATA_TYPES = [ FieldMetadataType.Text, FieldMetadataType.Boolean, FieldMetadataType.Select, - FieldMetadataType.Phone, - FieldMetadataType.Email, FieldMetadataType.Emails, FieldMetadataType.FullName, FieldMetadataType.Rating, diff --git a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts index 7ebeb0afee26..a110acdceba4 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions.ts @@ -26,10 +26,8 @@ export const formatFieldMetadataItemsAsFilterDefinitions = ({ FieldMetadataType.DateTime, FieldMetadataType.Date, FieldMetadataType.Text, - FieldMetadataType.Email, FieldMetadataType.Emails, FieldMetadataType.Number, - FieldMetadataType.Link, FieldMetadataType.Links, FieldMetadataType.FullName, FieldMetadataType.Address, @@ -68,8 +66,6 @@ export const getFilterTypeFromFieldType = (fieldType: FieldMetadataType) => { return 'DATE_TIME'; case FieldMetadataType.Date: return 'DATE'; - case FieldMetadataType.Link: - return 'LINK'; case FieldMetadataType.Links: return 'LINKS'; case FieldMetadataType.FullName: @@ -78,12 +74,8 @@ export const getFilterTypeFromFieldType = (fieldType: FieldMetadataType) => { return 'NUMBER'; case FieldMetadataType.Currency: return 'CURRENCY'; - case FieldMetadataType.Email: - return 'EMAIL'; case FieldMetadataType.Emails: return 'EMAILS'; - case FieldMetadataType.Phone: - return 'PHONE'; case FieldMetadataType.Phones: return 'PHONES'; case FieldMetadataType.Relation: diff --git a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts index d379313a0496..bf29d99ee1f9 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts @@ -26,10 +26,8 @@ export const mapFieldMetadataToGraphQLQuery = ({ const fieldIsSimpleValue = [ FieldMetadataType.Uuid, FieldMetadataType.Text, - FieldMetadataType.Phone, FieldMetadataType.DateTime, FieldMetadataType.Date, - FieldMetadataType.Email, FieldMetadataType.Number, FieldMetadataType.Boolean, FieldMetadataType.Rating, @@ -97,14 +95,6 @@ ${mapObjectMetadataToGraphQLQuery({ }`; } - if (fieldType === FieldMetadataType.Link) { - return `${field.name} -{ - label - url -}`; - } - if (fieldType === FieldMetadataType.Links) { return `${field.name} { diff --git a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordNodeFromRecord.ts b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordNodeFromRecord.ts index 2ab3b25344fa..21db7bcf49f4 100644 --- a/packages/twenty-front/src/modules/object-record/cache/utils/getRecordNodeFromRecord.ts +++ b/packages/twenty-front/src/modules/object-record/cache/utils/getRecordNodeFromRecord.ts @@ -131,7 +131,6 @@ export const getRecordNodeFromRecord = ({ }, ]; } - case FieldMetadataType.Link: case FieldMetadataType.Links: case FieldMetadataType.Address: case FieldMetadataType.FullName: diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx index b97deda7b578..2c43f6a5aa5e 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx @@ -36,7 +36,7 @@ const meta: Meta = { fieldMetadataId: '2', iconName: 'Icon123', label: 'Email', - type: FieldMetadataType.Email, + type: FieldMetadataType.Emails, }, { fieldMetadataId: '3', diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/types/FilterableFieldType.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/types/FilterableFieldType.ts index 833ebbd3a24f..0624fe937ef7 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/types/FilterableFieldType.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/types/FilterableFieldType.ts @@ -4,16 +4,13 @@ import { PickLiteral } from '~/types/PickLiteral'; export type FilterableFieldType = PickLiteral< FieldType, | 'TEXT' - | 'PHONE' | 'PHONES' - | 'EMAIL' | 'EMAILS' | 'DATE_TIME' | 'DATE' | 'NUMBER' | 'CURRENCY' | 'FULL_NAME' - | 'LINK' | 'LINKS' | 'RELATION' | 'ADDRESS' diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx index 66ea29aa06cc..023a229edeca 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx @@ -1,7 +1,7 @@ import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; -import { FilterableFieldType } from '@/object-record/object-filter-dropdown/types/FilterableFieldType'; import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; +import { FilterableFieldType } from '@/object-record/object-filter-dropdown/types/FilterableFieldType'; import { getOperandsForFilterDefinition } from '../getOperandsForFilterType'; describe('getOperandsForFilterType', () => { @@ -34,10 +34,8 @@ describe('getOperandsForFilterType', () => { const testCases = [ ['TEXT', [...containsOperands, ...emptyOperands]], - ['EMAIL', [...containsOperands, ...emptyOperands]], ['FULL_NAME', [...containsOperands, ...emptyOperands]], ['ADDRESS', [...containsOperands, ...emptyOperands]], - ['LINK', [...containsOperands, ...emptyOperands]], ['LINKS', [...containsOperands, ...emptyOperands]], ['ACTOR', [...containsOperands, ...emptyOperands]], ['CURRENCY', [...numberOperands, ...emptyOperands]], diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts index ba263c173c4c..688aa02b6c79 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts @@ -14,12 +14,9 @@ export const getOperandsForFilterDefinition = ( switch (filterDefinition.type) { case 'TEXT': - case 'EMAIL': case 'EMAILS': case 'FULL_NAME': case 'ADDRESS': - case 'PHONE': - case 'LINK': case 'LINKS': case 'ARRAY': case 'PHONES': diff --git a/packages/twenty-front/src/modules/object-record/record-field/__mocks__/fieldDefinitions.ts b/packages/twenty-front/src/modules/object-record/record-field/__mocks__/fieldDefinitions.ts index 90cd7f176e26..07cb30704498 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/__mocks__/fieldDefinitions.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/__mocks__/fieldDefinitions.ts @@ -3,7 +3,6 @@ import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinit import { FieldActorMetadata, FieldFullNameMetadata, - FieldLinkMetadata, FieldRatingMetadata, FieldSelectMetadata, FieldTextMetadata @@ -67,18 +66,6 @@ export const fullNameFieldDefinition: FieldDefinition = { }, }; -export const linkFieldDefinition: FieldDefinition = { - fieldMetadataId, - label: 'LinkedIn URL', - iconName: 'url', - type: FieldMetadataType.Link, - defaultValue: { url: '', label: '' }, - metadata: { - fieldName: 'linkedInURL', - placeHolder: 'https://linkedin.com/user', - }, -}; - const phonesFieldMetadataItem = mockedPersonObjectMetadataItem.fields?.find( ({ name }) => name === 'phones', ); diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx index 781ac98a650f..41740a1a4191 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx @@ -13,7 +13,6 @@ import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-type import { isFieldActor } from '@/object-record/record-field/types/guards/isFieldActor'; import { isFieldArray } from '@/object-record/record-field/types/guards/isFieldArray'; import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean'; -import { isFieldDisplayedAsPhone } from '@/object-record/record-field/types/guards/isFieldDisplayedAsPhone'; import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails'; import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones'; @@ -27,13 +26,10 @@ import { ChipFieldDisplay } from '../meta-types/display/components/ChipFieldDisp import { CurrencyFieldDisplay } from '../meta-types/display/components/CurrencyFieldDisplay'; import { DateFieldDisplay } from '../meta-types/display/components/DateFieldDisplay'; import { DateTimeFieldDisplay } from '../meta-types/display/components/DateTimeFieldDisplay'; -import { EmailFieldDisplay } from '../meta-types/display/components/EmailFieldDisplay'; import { FullNameFieldDisplay } from '../meta-types/display/components/FullNameFieldDisplay'; import { JsonFieldDisplay } from '../meta-types/display/components/JsonFieldDisplay'; -import { LinkFieldDisplay } from '../meta-types/display/components/LinkFieldDisplay'; import { MultiSelectFieldDisplay } from '../meta-types/display/components/MultiSelectFieldDisplay'; import { NumberFieldDisplay } from '../meta-types/display/components/NumberFieldDisplay'; -import { PhoneFieldDisplay } from '../meta-types/display/components/PhoneFieldDisplay'; import { RelationToOneFieldDisplay } from '../meta-types/display/components/RelationToOneFieldDisplay'; import { SelectFieldDisplay } from '../meta-types/display/components/SelectFieldDisplay'; import { TextFieldDisplay } from '../meta-types/display/components/TextFieldDisplay'; @@ -42,12 +38,9 @@ import { isFieldAddress } from '../types/guards/isFieldAddress'; import { isFieldCurrency } from '../types/guards/isFieldCurrency'; import { isFieldDate } from '../types/guards/isFieldDate'; import { isFieldDateTime } from '../types/guards/isFieldDateTime'; -import { isFieldEmail } from '../types/guards/isFieldEmail'; import { isFieldFullName } from '../types/guards/isFieldFullName'; -import { isFieldLink } from '../types/guards/isFieldLink'; import { isFieldMultiSelect } from '../types/guards/isFieldMultiSelect'; import { isFieldNumber } from '../types/guards/isFieldNumber'; -import { isFieldPhone } from '../types/guards/isFieldPhone'; import { isFieldRawJson } from '../types/guards/isFieldRawJson'; import { isFieldSelect } from '../types/guards/isFieldSelect'; import { isFieldText } from '../types/guards/isFieldText'; @@ -67,23 +60,16 @@ export const FieldDisplay = () => { ) : isFieldRelationFromManyObjects(fieldDefinition) ? ( - ) : isFieldPhone(fieldDefinition) || - isFieldDisplayedAsPhone(fieldDefinition) ? ( - ) : isFieldText(fieldDefinition) ? ( ) : isFieldUuid(fieldDefinition) ? ( - ) : isFieldEmail(fieldDefinition) ? ( - ) : isFieldDateTime(fieldDefinition) ? ( ) : isFieldDate(fieldDefinition) ? ( ) : isFieldNumber(fieldDefinition) ? ( - ) : isFieldLink(fieldDefinition) ? ( - ) : isFieldLinks(fieldDefinition) ? ( ) : isFieldCurrency(fieldDefinition) ? ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx index 144a24a8b8b0..1f36c34548d8 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx @@ -11,44 +11,37 @@ import { RawJsonFieldInput } from '@/object-record/record-field/meta-types/input import { RelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/components/RelationFromManyFieldInput'; import { SelectFieldInput } from '@/object-record/record-field/meta-types/input/components/SelectFieldInput'; import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope'; -import { isFieldDate } from '@/object-record/record-field/types/guards/isFieldDate'; -import { isFieldDisplayedAsPhone } from '@/object-record/record-field/types/guards/isFieldDisplayedAsPhone'; -import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails'; -import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; -import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; -import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/isFieldMultiSelect'; import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones'; -import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson'; import { isFieldRelationFromManyObjects } from '@/object-record/record-field/types/guards/isFieldRelationFromManyObjects'; import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject'; -import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { ArrayFieldInput } from '@/object-record/record-field/meta-types/input/components/ArrayFieldInput'; import { RichTextFieldInput } from '@/object-record/record-field/meta-types/input/components/RichTextFieldInput'; +import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; import { isFieldArray } from '@/object-record/record-field/types/guards/isFieldArray'; +import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean'; +import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency'; +import { isFieldDate } from '@/object-record/record-field/types/guards/isFieldDate'; +import { isFieldDateTime } from '@/object-record/record-field/types/guards/isFieldDateTime'; +import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails'; +import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; +import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; +import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/isFieldMultiSelect'; +import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; +import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating'; +import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson'; import { isFieldRichText } from '@/object-record/record-field/types/guards/isFieldRichText'; +import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { FieldContext } from '../contexts/FieldContext'; import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput'; import { CurrencyFieldInput } from '../meta-types/input/components/CurrencyFieldInput'; import { DateTimeFieldInput } from '../meta-types/input/components/DateTimeFieldInput'; -import { EmailFieldInput } from '../meta-types/input/components/EmailFieldInput'; -import { LinkFieldInput } from '../meta-types/input/components/LinkFieldInput'; import { NumberFieldInput } from '../meta-types/input/components/NumberFieldInput'; -import { PhoneFieldInput } from '../meta-types/input/components/PhoneFieldInput'; import { RatingFieldInput } from '../meta-types/input/components/RatingFieldInput'; import { RelationToOneFieldInput } from '../meta-types/input/components/RelationToOneFieldInput'; import { TextFieldInput } from '../meta-types/input/components/TextFieldInput'; import { FieldInputEvent } from '../types/FieldInputEvent'; -import { isFieldAddress } from '../types/guards/isFieldAddress'; -import { isFieldBoolean } from '../types/guards/isFieldBoolean'; -import { isFieldCurrency } from '../types/guards/isFieldCurrency'; -import { isFieldDateTime } from '../types/guards/isFieldDateTime'; -import { isFieldEmail } from '../types/guards/isFieldEmail'; -import { isFieldLink } from '../types/guards/isFieldLink'; -import { isFieldNumber } from '../types/guards/isFieldNumber'; -import { isFieldPhone } from '../types/guards/isFieldPhone'; -import { isFieldRating } from '../types/guards/isFieldRating'; import { isFieldText } from '../types/guards/isFieldText'; type FieldInputProps = { @@ -84,15 +77,6 @@ export const FieldInput = ({ ) : isFieldRelationFromManyObjects(fieldDefinition) ? ( - ) : isFieldPhone(fieldDefinition) || - isFieldDisplayedAsPhone(fieldDefinition) ? ( - ) : isFieldPhones(fieldDefinition) ? ( ) : isFieldText(fieldDefinition) ? ( @@ -103,14 +87,6 @@ export const FieldInput = ({ onTab={onTab} onShiftTab={onShiftTab} /> - ) : isFieldEmail(fieldDefinition) ? ( - ) : isFieldEmails(fieldDefinition) ? ( ) : isFieldFullName(fieldDefinition) ? ( @@ -145,14 +121,6 @@ export const FieldInput = ({ onTab={onTab} onShiftTab={onShiftTab} /> - ) : isFieldLink(fieldDefinition) ? ( - ) : isFieldLinks(fieldDefinition) ? ( ) : isFieldCurrency(fieldDefinition) ? ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/usePersistField.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/usePersistField.ts index 0aa155a868c9..d12e1b73bbb8 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/usePersistField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/usePersistField.ts @@ -35,14 +35,8 @@ import { isFieldCurrency } from '../types/guards/isFieldCurrency'; import { isFieldCurrencyValue } from '../types/guards/isFieldCurrencyValue'; import { isFieldDateTime } from '../types/guards/isFieldDateTime'; import { isFieldDateTimeValue } from '../types/guards/isFieldDateTimeValue'; -import { isFieldEmail } from '../types/guards/isFieldEmail'; -import { isFieldEmailValue } from '../types/guards/isFieldEmailValue'; -import { isFieldLink } from '../types/guards/isFieldLink'; -import { isFieldLinkValue } from '../types/guards/isFieldLinkValue'; import { isFieldNumber } from '../types/guards/isFieldNumber'; import { isFieldNumberValue } from '../types/guards/isFieldNumberValue'; -import { isFieldPhone } from '../types/guards/isFieldPhone'; -import { isFieldPhoneValue } from '../types/guards/isFieldPhoneValue'; import { isFieldRating } from '../types/guards/isFieldRating'; import { isFieldRatingValue } from '../types/guards/isFieldRatingValue'; import { isFieldText } from '../types/guards/isFieldText'; @@ -68,9 +62,6 @@ export const usePersistField = () => { const fieldIsText = isFieldText(fieldDefinition) && isFieldTextValue(valueToPersist); - const fieldIsEmail = - isFieldEmail(fieldDefinition) && isFieldEmailValue(valueToPersist); - const fieldIsEmails = isFieldEmails(fieldDefinition) && isFieldEmailsValue(valueToPersist); @@ -81,9 +72,6 @@ export const usePersistField = () => { const fieldIsDate = isFieldDate(fieldDefinition) && isFieldDateValue(valueToPersist); - const fieldIsLink = - isFieldLink(fieldDefinition) && isFieldLinkValue(valueToPersist); - const fieldIsLinks = isFieldLinks(fieldDefinition) && isFieldLinksValue(valueToPersist); @@ -105,9 +93,6 @@ export const usePersistField = () => { isFieldFullName(fieldDefinition) && isFieldFullNameValue(valueToPersist); - const fieldIsPhone = - isFieldPhone(fieldDefinition) && isFieldPhoneValue(valueToPersist); - const fieldIsPhones = isFieldPhones(fieldDefinition) && isFieldPhonesValue(valueToPersist); @@ -133,15 +118,12 @@ export const usePersistField = () => { fieldIsRelationToOneObject || fieldIsText || fieldIsBoolean || - fieldIsEmail || fieldIsEmails || fieldIsRating || fieldIsNumber || fieldIsDateTime || fieldIsDate || - fieldIsPhone || fieldIsPhones || - fieldIsLink || fieldIsLinks || fieldIsCurrency || fieldIsFullName || diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/EmailFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/EmailFieldDisplay.tsx deleted file mode 100644 index 60a7caa6e32a..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/EmailFieldDisplay.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { useEmailFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useEmailFieldDisplay'; -import { EmailDisplay } from '@/ui/field/display/components/EmailDisplay'; - -export const EmailFieldDisplay = () => { - const { fieldValue } = useEmailFieldDisplay(); - - return ; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/LinkFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/LinkFieldDisplay.tsx deleted file mode 100644 index bb1989852f4c..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/LinkFieldDisplay.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { useLinkFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useLinkFieldDisplay'; -import { LinkDisplay } from '@/ui/field/display/components/LinkDisplay'; - -export const LinkFieldDisplay = () => { - const { fieldValue } = useLinkFieldDisplay(); - - return ; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/PhoneFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/PhoneFieldDisplay.tsx deleted file mode 100644 index acfd141a3240..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/PhoneFieldDisplay.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { usePhoneFieldDisplay } from '@/object-record/record-field/meta-types/hooks/usePhoneFieldDisplay'; -import { PhoneDisplay } from '@/ui/field/display/components/PhoneDisplay'; - -export const PhoneFieldDisplay = () => { - const { fieldValue } = usePhoneFieldDisplay(); - - return ; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailField.ts deleted file mode 100644 index a12e4a54f609..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailField.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useContext } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; - -import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput'; -import { FieldEmailValue } from '@/object-record/record-field/types/FieldMetadata'; -import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldContext } from '../../contexts/FieldContext'; -import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; -import { isFieldEmail } from '../../types/guards/isFieldEmail'; - -export const useEmailField = () => { - const { recordId, fieldDefinition, hotkeyScope } = useContext(FieldContext); - - assertFieldMetadata(FieldMetadataType.Email, isFieldEmail, fieldDefinition); - - const fieldName = fieldDefinition.metadata.fieldName; - - const [fieldValue, setFieldValue] = useRecoilState( - recordStoreFamilySelector({ - recordId, - fieldName: fieldName, - }), - ); - - const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); - - const draftValue = useRecoilValue(getDraftValueSelector()); - - return { - fieldDefinition, - draftValue, - setDraftValue, - fieldValue, - setFieldValue, - hotkeyScope, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailFieldDisplay.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailFieldDisplay.ts deleted file mode 100644 index cb7684a4f493..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailFieldDisplay.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useContext } from 'react'; - -import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; - -import { FieldContext } from '../../contexts/FieldContext'; - -export const useEmailFieldDisplay = () => { - const { recordId, fieldDefinition, hotkeyScope } = useContext(FieldContext); - - const fieldName = fieldDefinition.metadata.fieldName; - - const fieldValue = useRecordFieldValue(recordId, fieldName); - - return { - fieldDefinition, - fieldValue, - hotkeyScope, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkField.ts deleted file mode 100644 index f1b5ed7e6a30..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkField.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { useContext } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; - -import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput'; -import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldContext } from '../../contexts/FieldContext'; -import { usePersistField } from '../../hooks/usePersistField'; -import { FieldLinkValue } from '../../types/FieldMetadata'; -import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; -import { isFieldLink } from '../../types/guards/isFieldLink'; -import { isFieldLinkValue } from '../../types/guards/isFieldLinkValue'; - -export const useLinkField = () => { - const { recordId, fieldDefinition, hotkeyScope } = useContext(FieldContext); - - assertFieldMetadata(FieldMetadataType.Link, isFieldLink, fieldDefinition); - - const fieldName = fieldDefinition.metadata.fieldName; - - const [fieldValue, setFieldValue] = useRecoilState( - recordStoreFamilySelector({ - recordId, - fieldName: fieldName, - }), - ); - - const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); - - const draftValue = useRecoilValue(getDraftValueSelector()); - - const persistField = usePersistField(); - - const persistLinkField = (newValue: FieldLinkValue) => { - if (!isFieldLinkValue(newValue)) { - return; - } - - persistField(newValue); - }; - - return { - fieldDefinition, - fieldValue, - draftValue, - setDraftValue, - setFieldValue, - hotkeyScope, - persistLinkField, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkFieldDisplay.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkFieldDisplay.ts deleted file mode 100644 index 570857ffae10..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinkFieldDisplay.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useContext } from 'react'; - -import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; - -import { FieldContext } from '../../contexts/FieldContext'; -import { FieldLinkValue } from '../../types/FieldMetadata'; - -export const useLinkFieldDisplay = () => { - const { recordId, fieldDefinition } = useContext(FieldContext); - - const fieldName = fieldDefinition.metadata.fieldName; - const fieldValue = useRecordFieldValue( - recordId, - fieldName, - ); - - return { - fieldDefinition, - fieldValue, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneField.ts deleted file mode 100644 index 2e20254c82b7..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneField.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { useContext } from 'react'; -import { isPossiblePhoneNumber } from 'libphonenumber-js'; -import { useRecoilState, useRecoilValue } from 'recoil'; - -import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput'; -import { FieldPhoneValue } from '@/object-record/record-field/types/FieldMetadata'; -import { isFieldDisplayedAsPhone } from '@/object-record/record-field/types/guards/isFieldDisplayedAsPhone'; -import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldContext } from '../../contexts/FieldContext'; -import { usePersistField } from '../../hooks/usePersistField'; -import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; -import { isFieldPhone } from '../../types/guards/isFieldPhone'; - -export const usePhoneField = () => { - const { recordId, fieldDefinition, hotkeyScope } = useContext(FieldContext); - - try { - // TODO: temporary - remove when 'Phone' field in 'Person' object - // is migrated to use FieldMetadataType.Phone as type. - assertFieldMetadata( - FieldMetadataType.Text, - isFieldDisplayedAsPhone, - fieldDefinition, - ); - } catch { - assertFieldMetadata(FieldMetadataType.Phone, isFieldPhone, fieldDefinition); - } - - const fieldName = fieldDefinition.metadata.fieldName; - - const [fieldValue, setFieldValue] = useRecoilState( - recordStoreFamilySelector({ - recordId, - fieldName: fieldName, - }), - ); - - const persistField = usePersistField(); - - const persistPhoneField = (newPhoneValue: string) => { - if (!isPossiblePhoneNumber(newPhoneValue) && newPhoneValue !== '') return; - - persistField(newPhoneValue); - }; - const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); - - const draftValue = useRecoilValue(getDraftValueSelector()); - - return { - fieldDefinition, - fieldValue, - setFieldValue, - draftValue, - setDraftValue, - hotkeyScope, - persistPhoneField, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneFieldDisplay.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneFieldDisplay.ts deleted file mode 100644 index 3ba7d4f1b25c..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhoneFieldDisplay.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useContext } from 'react'; - -import { useRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; - -import { FieldContext } from '../../contexts/FieldContext'; - -export const usePhoneFieldDisplay = () => { - const { recordId, fieldDefinition, hotkeyScope } = useContext(FieldContext); - - const fieldName = fieldDefinition.metadata.fieldName; - - const fieldValue = useRecordFieldValue(recordId, fieldName); - - return { - fieldDefinition, - fieldValue, - hotkeyScope, - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/EmailFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/EmailFieldInput.tsx deleted file mode 100644 index 29ed4b2f15c6..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/EmailFieldInput.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { TextInput } from '@/ui/field/input/components/TextInput'; - -import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay'; -import { usePersistField } from '../../../hooks/usePersistField'; -import { useEmailField } from '../../hooks/useEmailField'; - -import { FieldInputEvent } from './DateTimeFieldInput'; - -export type EmailFieldInputProps = { - onClickOutside?: FieldInputEvent; - onEnter?: FieldInputEvent; - onEscape?: FieldInputEvent; - onTab?: FieldInputEvent; - onShiftTab?: FieldInputEvent; -}; - -export const EmailFieldInput = ({ - onEnter, - onEscape, - onClickOutside, - onTab, - onShiftTab, -}: EmailFieldInputProps) => { - const { fieldDefinition, draftValue, setDraftValue, hotkeyScope } = - useEmailField(); - - const persistField = usePersistField(); - - const handleEnter = (newText: string) => { - onEnter?.(() => persistField(newText)); - }; - - const handleEscape = (newText: string) => { - onEscape?.(() => persistField(newText)); - }; - - const handleClickOutside = ( - event: MouseEvent | TouchEvent, - newText: string, - ) => { - onClickOutside?.(() => persistField(newText)); - }; - - const handleTab = (newText: string) => { - onTab?.(() => persistField(newText)); - }; - - const handleShiftTab = (newText: string) => { - onShiftTab?.(() => persistField(newText)); - }; - - const handleChange = (newText: string) => { - setDraftValue(newText); - }; - - return ( - - - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/LinkFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/LinkFieldInput.tsx deleted file mode 100644 index 758c95fb11a3..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/LinkFieldInput.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { TextInput } from '@/ui/field/input/components/TextInput'; - -import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay'; -import { useLinkField } from '../../hooks/useLinkField'; - -import { FieldInputEvent } from './DateTimeFieldInput'; - -type LinkFieldInputProps = { - onClickOutside?: FieldInputEvent; - onEnter?: FieldInputEvent; - onEscape?: FieldInputEvent; - onTab?: FieldInputEvent; - onShiftTab?: FieldInputEvent; -}; - -export const LinkFieldInput = ({ - onEnter, - onEscape, - onClickOutside, - onTab, - onShiftTab, -}: LinkFieldInputProps) => { - const { draftValue, setDraftValue, hotkeyScope, persistLinkField } = - useLinkField(); - - const handleEnter = (newURL: string) => { - onEnter?.(() => - persistLinkField({ - url: newURL, - label: '', - }), - ); - }; - - const handleEscape = (newURL: string) => { - onEscape?.(() => - persistLinkField({ - url: newURL, - label: '', - }), - ); - }; - - const handleClickOutside = ( - event: MouseEvent | TouchEvent, - newURL: string, - ) => { - onClickOutside?.(() => - persistLinkField({ - url: newURL, - label: '', - }), - ); - }; - - const handleTab = (newURL: string) => { - onTab?.(() => - persistLinkField({ - url: newURL, - label: '', - }), - ); - }; - - const handleShiftTab = (newURL: string) => { - onShiftTab?.(() => - persistLinkField({ - url: newURL, - label: '', - }), - ); - }; - - const handleChange = (newURL: string) => { - setDraftValue({ - url: newURL, - label: '', - }); - }; - - return ( - - - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhoneFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhoneFieldInput.tsx deleted file mode 100644 index 179455da6a0e..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/PhoneFieldInput.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { PhoneInput } from '@/ui/field/input/components/PhoneInput'; - -import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay'; -import { usePhoneField } from '../../hooks/usePhoneField'; - -import { FieldInputEvent } from './DateTimeFieldInput'; - -export type PhoneFieldInputProps = { - onClickOutside?: FieldInputEvent; - onEnter?: FieldInputEvent; - onEscape?: FieldInputEvent; - onTab?: FieldInputEvent; - onShiftTab?: FieldInputEvent; -}; - -export const PhoneFieldInput = ({ - onEnter, - onEscape, - onClickOutside, - onTab, - onShiftTab, -}: PhoneFieldInputProps) => { - const { - fieldDefinition, - draftValue, - setDraftValue, - hotkeyScope, - persistPhoneField, - } = usePhoneField(); - - const handleEnter = (newText: string) => { - onEnter?.(() => persistPhoneField(newText)); - }; - - const handleEscape = (newText: string) => { - onEscape?.(() => persistPhoneField(newText)); - }; - - const handleClickOutside = ( - event: MouseEvent | TouchEvent, - newText: string, - ) => { - onClickOutside?.(() => persistPhoneField(newText)); - }; - - const handleTab = (newText: string) => { - onTab?.(() => persistPhoneField(newText)); - }; - - const handleShiftTab = (newText: string) => { - onShiftTab?.(() => persistPhoneField(newText)); - }; - - const handleChange = (newText: string) => { - setDraftValue(newText); - }; - - return ( - - - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/EmailFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/EmailFieldInput.stories.tsx deleted file mode 100644 index b8154f0545de..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/EmailFieldInput.stories.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import { useEffect } from 'react'; -import { Decorator, Meta, StoryObj } from '@storybook/react'; -import { expect, fn, userEvent, waitFor, within } from '@storybook/test'; - -import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -import { FieldMetadataType } from '~/generated/graphql'; -import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; - -import { FieldContextProvider } from '../../../__stories__/FieldContextProvider'; -import { useEmailField } from '../../../hooks/useEmailField'; -import { EmailFieldInput, EmailFieldInputProps } from '../EmailFieldInput'; - -const EmailFieldValueSetterEffect = ({ value }: { value: string }) => { - const { setFieldValue } = useEmailField(); - - useEffect(() => { - setFieldValue(value); - }, [setFieldValue, value]); - - return <>; -}; - -type EmailFieldInputWithContextProps = EmailFieldInputProps & { - value: string; - recordId?: string; -}; - -const EmailFieldInputWithContext = ({ - recordId, - value, - onEnter, - onEscape, - onClickOutside, - onTab, - onShiftTab, -}: EmailFieldInputWithContextProps) => { - const setHotKeyScope = useSetHotkeyScope(); - - useEffect(() => { - setHotKeyScope('hotkey-scope'); - }, [setHotKeyScope]); - - return ( -
- - - - -
-
- ); -}; - -const enterJestFn = fn(); -const escapeJestfn = fn(); -const clickOutsideJestFn = fn(); -const tabJestFn = fn(); -const shiftTabJestFn = fn(); - -const clearMocksDecorator: Decorator = (Story, context) => { - if (context.parameters.clearMocks === true) { - enterJestFn.mockClear(); - escapeJestfn.mockClear(); - clickOutsideJestFn.mockClear(); - tabJestFn.mockClear(); - shiftTabJestFn.mockClear(); - } - return ; -}; - -const meta: Meta = { - title: 'UI/Data/Field/Input/EmailFieldInput', - component: EmailFieldInputWithContext, - args: { - value: 'username@email.com', - onEnter: enterJestFn, - onEscape: escapeJestfn, - onClickOutside: clickOutsideJestFn, - onTab: tabJestFn, - onShiftTab: shiftTabJestFn, - }, - argTypes: { - onEnter: { control: false }, - onEscape: { control: false }, - onClickOutside: { control: false }, - onTab: { control: false }, - onShiftTab: { control: false }, - }, - decorators: [clearMocksDecorator, SnackBarDecorator], - parameters: { - clearMocks: true, - }, -}; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = {}; - -export const Enter: Story = { - play: async () => { - expect(enterJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{enter}'); - expect(enterJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const Escape: Story = { - play: async () => { - expect(escapeJestfn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{esc}'); - expect(escapeJestfn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const ClickOutside: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - - expect(clickOutsideJestFn).toHaveBeenCalledTimes(0); - - const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div'); - - await waitFor(() => { - userEvent.click(emptyDiv); - expect(clickOutsideJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const Tab: Story = { - play: async () => { - expect(tabJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{tab}'); - expect(tabJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const ShiftTab: Story = { - play: async () => { - expect(shiftTabJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{shift>}{tab}'); - expect(shiftTabJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/PhoneFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/PhoneFieldInput.stories.tsx deleted file mode 100644 index 6300d789bdf6..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/PhoneFieldInput.stories.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { useEffect } from 'react'; -import { Decorator, Meta, StoryObj } from '@storybook/react'; -import { expect, fn, userEvent, waitFor, within } from '@storybook/test'; - -import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -import { FieldMetadataType } from '~/generated/graphql'; -import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; - -import { FieldContextProvider } from '../../../__stories__/FieldContextProvider'; -import { usePhoneField } from '../../../hooks/usePhoneField'; -import { PhoneFieldInput, PhoneFieldInputProps } from '../PhoneFieldInput'; - -const PhoneFieldValueSetterEffect = ({ value }: { value: string }) => { - const { setFieldValue } = usePhoneField(); - - useEffect(() => { - setFieldValue(value); - }, [setFieldValue, value]); - - return <>; -}; - -type PhoneFieldInputWithContextProps = PhoneFieldInputProps & { - value: string; - recordId?: string; -}; - -const PhoneFieldInputWithContext = ({ - recordId, - value, - onEnter, - onEscape, - onClickOutside, - onTab, - onShiftTab, -}: PhoneFieldInputWithContextProps) => { - const setHotKeyScope = useSetHotkeyScope(); - - useEffect(() => { - setHotKeyScope('hotkey-scope'); - }, [setHotKeyScope]); - - return ( -
- - - - -
-
- ); -}; - -const enterJestFn = fn(); -const escapeJestfn = fn(); -const clickOutsideJestFn = fn(); -const tabJestFn = fn(); -const shiftTabJestFn = fn(); - -const clearMocksDecorator: Decorator = (Story, context) => { - if (context.parameters.clearMocks === true) { - enterJestFn.mockClear(); - escapeJestfn.mockClear(); - clickOutsideJestFn.mockClear(); - tabJestFn.mockClear(); - shiftTabJestFn.mockClear(); - } - return ; -}; - -const meta: Meta = { - title: 'UI/Data/Field/Input/PhoneFieldInput', - component: PhoneFieldInputWithContext, - args: { - value: '+1-12-123-456', - isPositive: true, - onEnter: enterJestFn, - onEscape: escapeJestfn, - onClickOutside: clickOutsideJestFn, - onTab: tabJestFn, - onShiftTab: shiftTabJestFn, - }, - argTypes: { - onEnter: { control: false }, - onEscape: { control: false }, - onClickOutside: { control: false }, - onTab: { control: false }, - onShiftTab: { control: false }, - }, - decorators: [clearMocksDecorator, SnackBarDecorator], - parameters: { - clearMocks: true, - }, -}; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = {}; - -export const Enter: Story = { - play: async () => { - expect(enterJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{enter}'); - expect(enterJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const Escape: Story = { - play: async () => { - expect(escapeJestfn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{esc}'); - expect(escapeJestfn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const ClickOutside: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - - expect(clickOutsideJestFn).toHaveBeenCalledTimes(0); - - const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div'); - - await waitFor(() => { - userEvent.click(emptyDiv); - expect(clickOutsideJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const Tab: Story = { - play: async () => { - expect(tabJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{tab}'); - expect(tabJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; - -export const ShiftTab: Story = { - play: async () => { - expect(shiftTabJestFn).toHaveBeenCalledTimes(0); - - await waitFor(() => { - userEvent.keyboard('{shift>}{tab}'); - expect(shiftTabJestFn).toHaveBeenCalledTimes(1); - }); - }, -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldInputDraftValue.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldInputDraftValue.ts index 9ab99492f651..6bd2ee66810b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldInputDraftValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldInputDraftValue.ts @@ -6,15 +6,12 @@ import { FieldCurrencyValue, FieldDateTimeValue, FieldEmailsValue, - FieldEmailValue, FieldFullNameValue, FieldJsonValue, FieldLinksValue, - FieldLinkValue, FieldMultiSelectValue, FieldNumberValue, FieldPhonesValue, - FieldPhoneValue, FieldRatingValue, FieldRelationFromManyValue, FieldRelationToOneValue, @@ -27,13 +24,11 @@ import { export type FieldTextDraftValue = string; export type FieldNumberDraftValue = number; export type FieldDateTimeDraftValue = string; -export type FieldPhoneDraftValue = string; export type FieldPhonesDraftValue = { primaryPhoneNumber: string; primaryPhoneCountryCode: string; additionalPhones?: PhoneRecord[] | null; }; -export type FieldEmailDraftValue = string; export type FieldEmailsDraftValue = { primaryEmail: string; additionalEmails: string[] | null; @@ -42,7 +37,6 @@ export type FieldSelectDraftValue = string; export type FieldMultiSelectDraftValue = string[]; export type FieldRelationDraftValue = string; export type FieldRelationManyDraftValue = string[]; -export type FieldLinkDraftValue = { url: string; label: string }; export type FieldLinksDraftValue = { primaryLinkLabel: string; primaryLinkUrl: string; @@ -80,36 +74,30 @@ export type FieldInputDraftValue = FieldValue extends FieldTextValue ? FieldNumberDraftValue : FieldValue extends FieldBooleanValue ? FieldBooleanValue - : FieldValue extends FieldPhoneValue - ? FieldPhoneDraftValue - : FieldValue extends FieldPhonesValue - ? FieldPhonesDraftValue - : FieldValue extends FieldEmailValue - ? FieldEmailDraftValue - : FieldValue extends FieldEmailsValue - ? FieldEmailsDraftValue - : FieldValue extends FieldLinkValue - ? FieldLinkDraftValue - : FieldValue extends FieldLinksValue - ? FieldLinksDraftValue - : FieldValue extends FieldCurrencyValue - ? FieldCurrencyDraftValue - : FieldValue extends FieldFullNameValue - ? FieldFullNameDraftValue - : FieldValue extends FieldRatingValue - ? FieldRatingValue - : FieldValue extends FieldSelectValue - ? FieldSelectDraftValue - : FieldValue extends FieldMultiSelectValue - ? FieldMultiSelectDraftValue - : FieldValue extends FieldRelationToOneValue - ? FieldRelationDraftValue - : FieldValue extends FieldRelationFromManyValue - ? FieldRelationManyDraftValue - : FieldValue extends FieldAddressValue - ? FieldAddressDraftValue - : FieldValue extends FieldJsonValue - ? FieldJsonDraftValue - : FieldValue extends FieldActorValue - ? FieldActorDraftValue - : never; + : FieldValue extends FieldPhonesValue + ? FieldPhonesDraftValue + : FieldValue extends FieldEmailsValue + ? FieldEmailsDraftValue + : FieldValue extends FieldLinksValue + ? FieldLinksDraftValue + : FieldValue extends FieldCurrencyValue + ? FieldCurrencyDraftValue + : FieldValue extends FieldFullNameValue + ? FieldFullNameDraftValue + : FieldValue extends FieldRatingValue + ? FieldRatingValue + : FieldValue extends FieldSelectValue + ? FieldSelectDraftValue + : FieldValue extends FieldMultiSelectValue + ? FieldMultiSelectDraftValue + : FieldValue extends FieldRelationToOneValue + ? FieldRelationDraftValue + : FieldValue extends FieldRelationFromManyValue + ? FieldRelationManyDraftValue + : FieldValue extends FieldAddressValue + ? FieldAddressDraftValue + : FieldValue extends FieldJsonValue + ? FieldJsonDraftValue + : FieldValue extends FieldActorValue + ? FieldActorDraftValue + : never; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts index c6994db5a5f8..8c924c6ab123 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts @@ -183,13 +183,10 @@ export type FieldDateValue = string | null; export type FieldNumberValue = number | null; export type FieldBooleanValue = boolean; -export type FieldPhoneValue = string; -export type FieldEmailValue = string; export type FieldEmailsValue = { primaryEmail: string; additionalEmails: string[] | null; }; -export type FieldLinkValue = { url: string; label: string }; export type FieldLinksValue = { primaryLinkLabel: string; primaryLinkUrl: string; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmail.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmail.ts deleted file mode 100644 index 676cca39bdfd..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmail.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldDefinition } from '../FieldDefinition'; -import { FieldEmailMetadata, FieldMetadata } from '../FieldMetadata'; - -export const isFieldEmail = ( - field: Pick, 'type'>, -): field is FieldDefinition => - field.type === FieldMetadataType.Email; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmailValue.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmailValue.ts deleted file mode 100644 index 2ce954057096..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldEmailValue.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { isString } from '@sniptt/guards'; - -import { FieldEmailValue } from '../FieldMetadata'; - -// TODO: add zod -export const isFieldEmailValue = ( - fieldValue: unknown, -): fieldValue is FieldEmailValue => isString(fieldValue); diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLink.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLink.ts deleted file mode 100644 index 6f98150d0149..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLink.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldDefinition } from '../FieldDefinition'; -import { FieldLinkMetadata, FieldMetadata } from '../FieldMetadata'; - -export const isFieldLink = ( - field: Pick, 'type'>, -): field is FieldDefinition => - field.type === FieldMetadataType.Link; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLinkValue.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLinkValue.ts deleted file mode 100644 index b075dc746f13..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldLinkValue.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { z } from 'zod'; - -import { FieldLinkValue } from '../FieldMetadata'; - -const linkSchema = z.object({ - url: z.string(), - label: z.string(), -}); - -export const isFieldLinkValue = ( - fieldValue: unknown, -): fieldValue is FieldLinkValue => linkSchema.safeParse(fieldValue).success; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhone.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhone.ts deleted file mode 100644 index 0de71e270863..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhone.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FieldMetadataType } from '~/generated-metadata/graphql'; - -import { FieldDefinition } from '../FieldDefinition'; -import { FieldMetadata, FieldPhoneMetadata } from '../FieldMetadata'; - -export const isFieldPhone = ( - field: Pick, 'type'>, -): field is FieldDefinition => - field.type === FieldMetadataType.Phone; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhoneValue.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhoneValue.ts deleted file mode 100644 index 4bb79a9e611a..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldPhoneValue.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { isString } from '@sniptt/guards'; - -import { FieldPhoneValue } from '../FieldMetadata'; - -// TODO: add zod -export const isFieldPhoneValue = ( - fieldValue: unknown, -): fieldValue is FieldPhoneValue => isString(fieldValue); diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/__tests__/isFieldValueEmpty.test.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/__tests__/isFieldValueEmpty.test.ts index 47fe783322c2..07761aef8822 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/__tests__/isFieldValueEmpty.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/__tests__/isFieldValueEmpty.test.ts @@ -2,7 +2,6 @@ import { booleanFieldDefinition, fieldMetadataId, fullNameFieldDefinition, - linkFieldDefinition, relationFieldDefinition, selectFieldDefinition, } from '@/object-record/record-field/__mocks__/fieldDefinitions'; @@ -101,19 +100,4 @@ describe('isFieldValueEmpty', () => { }), ).toBe(false); }); - - it('should return correct value for link field', () => { - expect( - isFieldValueEmpty({ - fieldDefinition: linkFieldDefinition, - fieldValue: { url: '', label: '' }, - }), - ).toBe(true); - expect( - isFieldValueEmpty({ - fieldDefinition: linkFieldDefinition, - fieldValue: { url: 'https://linkedin.com/user-slug', label: '' }, - }), - ).toBe(false); - }); }); diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/computeDraftValueFromString.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/computeDraftValueFromString.ts index c668801e33aa..06d16fdb8ffb 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/computeDraftValueFromString.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/computeDraftValueFromString.ts @@ -5,10 +5,8 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency'; import { isFieldDateTime } from '@/object-record/record-field/types/guards/isFieldDateTime'; -import { isFieldEmail } from '@/object-record/record-field/types/guards/isFieldEmail'; import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails'; import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; -import { isFieldLink } from '@/object-record/record-field/types/guards/isFieldLink'; import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones'; @@ -33,14 +31,10 @@ export const computeDraftValueFromString = ({ isFieldText(fieldDefinition) || isFieldDateTime(fieldDefinition) || isFieldNumber(fieldDefinition) || - isFieldEmail(fieldDefinition) || isFieldRelation(fieldDefinition) ) { return value as FieldInputDraftValue; } - if (isFieldLink(fieldDefinition)) { - return { url: value, label: value } as FieldInputDraftValue; - } if (isFieldCurrency(fieldDefinition)) { return { diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/computeEmptyDraftValue.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/computeEmptyDraftValue.ts index af950cf2041f..7433a30554e8 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/computeEmptyDraftValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/computeEmptyDraftValue.ts @@ -5,7 +5,6 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency'; import { isFieldDateTime } from '@/object-record/record-field/types/guards/isFieldDateTime'; -import { isFieldEmail } from '@/object-record/record-field/types/guards/isFieldEmail'; import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; @@ -27,7 +26,6 @@ export const computeEmptyDraftValue = ({ isFieldText(fieldDefinition) || isFieldDateTime(fieldDefinition) || isFieldNumber(fieldDefinition) || - isFieldEmail(fieldDefinition) || isFieldRelation(fieldDefinition) || isFieldRawJson(fieldDefinition) ) { diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/getFieldButtonIcon.tsx b/packages/twenty-front/src/modules/object-record/record-field/utils/getFieldButtonIcon.tsx index 5743a74cbb1a..afb99cda1334 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/getFieldButtonIcon.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/getFieldButtonIcon.tsx @@ -11,9 +11,6 @@ import { isFieldRelation } from '@/object-record/record-field/types/guards/isFie import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { isFieldArray } from '@/object-record/record-field/types/guards/isFieldArray'; -import { isFieldEmail } from '../types/guards/isFieldEmail'; -import { isFieldLink } from '../types/guards/isFieldLink'; -import { isFieldPhone } from '../types/guards/isFieldPhone'; export const getFieldButtonIcon = ( fieldDefinition: @@ -24,9 +21,6 @@ export const getFieldButtonIcon = ( if (isUndefinedOrNull(fieldDefinition)) return undefined; if ( - isFieldLink(fieldDefinition) || - isFieldEmail(fieldDefinition) || - isFieldPhone(fieldDefinition) || isFieldDisplayedAsPhone(fieldDefinition) || isFieldMultiSelect(fieldDefinition) || (isFieldRelation(fieldDefinition) && diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts index 0323ef19e099..4f7d2fe2b570 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts @@ -13,19 +13,15 @@ import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFie import { isFieldCurrencyValue } from '@/object-record/record-field/types/guards/isFieldCurrencyValue'; import { isFieldDate } from '@/object-record/record-field/types/guards/isFieldDate'; import { isFieldDateTime } from '@/object-record/record-field/types/guards/isFieldDateTime'; -import { isFieldEmail } from '@/object-record/record-field/types/guards/isFieldEmail'; import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails'; import { isFieldEmailsValue } from '@/object-record/record-field/types/guards/isFieldEmailsValue'; import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; import { isFieldFullNameValue } from '@/object-record/record-field/types/guards/isFieldFullNameValue'; -import { isFieldLink } from '@/object-record/record-field/types/guards/isFieldLink'; -import { isFieldLinkValue } from '@/object-record/record-field/types/guards/isFieldLinkValue'; import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; import { isFieldLinksValue } from '@/object-record/record-field/types/guards/isFieldLinksValue'; import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/isFieldMultiSelect'; import { isFieldMultiSelectValue } from '@/object-record/record-field/types/guards/isFieldMultiSelectValue'; import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; -import { isFieldPhone } from '@/object-record/record-field/types/guards/isFieldPhone'; import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones'; import { isFieldPhonesValue } from '@/object-record/record-field/types/guards/isFieldPhonesValue'; import { isFieldPosition } from '@/object-record/record-field/types/guards/isFieldPosition'; @@ -60,12 +56,10 @@ export const isFieldValueEmpty = ({ isFieldDate(fieldDefinition) || isFieldNumber(fieldDefinition) || isFieldRating(fieldDefinition) || - isFieldEmail(fieldDefinition) || isFieldBoolean(fieldDefinition) || isFieldRelation(fieldDefinition) || isFieldRawJson(fieldDefinition) || isFieldRichText(fieldDefinition) || - isFieldPhone(fieldDefinition) || isFieldPosition(fieldDefinition) ) { return isValueEmpty(fieldValue); @@ -101,10 +95,6 @@ export const isFieldValueEmpty = ({ ); } - if (isFieldLink(fieldDefinition)) { - return !isFieldLinkValue(fieldValue) || isValueEmpty(fieldValue?.url); - } - if (isFieldAddress(fieldDefinition)) { return ( !isFieldAddressValue(fieldValue) || diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/applyEmptyFilters.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/applyEmptyFilters.ts index 5d4890f42e8f..e004288ceba0 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/applyEmptyFilters.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/applyEmptyFilters.ts @@ -32,8 +32,6 @@ export const applyEmptyFilters = ( switch (definition.type) { case 'TEXT': - case 'EMAIL': - case 'PHONE': emptyRecordFilter = { or: [ { [correspondingField.name]: { ilike: '' } as StringFilter }, @@ -113,16 +111,6 @@ export const applyEmptyFilters = ( } break; } - case 'LINK': - emptyRecordFilter = { - or: [ - { [correspondingField.name]: { url: { ilike: '' } } as URLFilter }, - { - [correspondingField.name]: { url: { is: 'NULL' } } as URLFilter, - }, - ], - }; - break; case 'LINKS': { if (!isCompositeField) { const linksFilters = generateILikeFiltersForCompositeFields( diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts index f83c82d0e865..2ddb31f0b12d 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts @@ -17,7 +17,6 @@ import { PhonesFilter, RecordGqlOperationFilter, StringFilter, - URLFilter, UUIDFilter, } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { isMatchingBooleanFilter } from '@/object-record/record-filter/utils/isMatchingBooleanFilter'; @@ -144,8 +143,6 @@ export const isRecordMatchingFilter = ({ } switch (objectMetadataField.type) { - case FieldMetadataType.Email: - case FieldMetadataType.Phone: case FieldMetadataType.Select: case FieldMetadataType.Rating: case FieldMetadataType.MultiSelect: @@ -155,22 +152,6 @@ export const isRecordMatchingFilter = ({ value: record[filterKey], }); } - case FieldMetadataType.Link: { - const urlFilter = filterValue as URLFilter; - - return ( - (urlFilter.url === undefined || - isMatchingStringFilter({ - stringFilter: urlFilter.url, - value: record[filterKey].url, - })) && - (urlFilter.label === undefined || - isMatchingStringFilter({ - stringFilter: urlFilter.label, - value: record[filterKey].label, - })) - ); - } case FieldMetadataType.FullName: { const fullNameFilter = filterValue as FullNameFilter; diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts index ea849199cdda..476818a56684 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts @@ -10,7 +10,6 @@ import { RecordGqlOperationFilter, RelationFilter, StringFilter, - URLFilter, UUIDFilter, } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables'; @@ -388,43 +387,6 @@ export const turnObjectDropdownFilterIntoQueryFilter = ( ); } break; - case 'LINK': - switch (rawUIFilter.operand) { - case ViewFilterOperand.Contains: - objectRecordFilters.push({ - [correspondingField.name]: { - url: { - ilike: `%${rawUIFilter.value}%`, - }, - } as URLFilter, - }); - break; - case ViewFilterOperand.DoesNotContain: - objectRecordFilters.push({ - not: { - [correspondingField.name]: { - url: { - ilike: `%${rawUIFilter.value}%`, - }, - } as URLFilter, - }, - }); - break; - case ViewFilterOperand.IsEmpty: - case ViewFilterOperand.IsNotEmpty: - applyEmptyFilters( - rawUIFilter.operand, - correspondingField, - objectRecordFilters, - rawUIFilter.definition, - ); - break; - default: - throw new Error( - `Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.type} filter`, - ); - } - break; case 'LINKS': { const linksFilters = generateILikeFiltersForCompositeFields( rawUIFilter.value, diff --git a/packages/twenty-front/src/modules/object-record/spreadsheet-import/util/getSpreadSheetFieldValidationDefinitions.ts b/packages/twenty-front/src/modules/object-record/spreadsheet-import/util/getSpreadSheetFieldValidationDefinitions.ts index ad08de8936f5..b32f814a7300 100644 --- a/packages/twenty-front/src/modules/object-record/spreadsheet-import/util/getSpreadSheetFieldValidationDefinitions.ts +++ b/packages/twenty-front/src/modules/object-record/spreadsheet-import/util/getSpreadSheetFieldValidationDefinitions.ts @@ -1,5 +1,3 @@ -import { isValidPhoneNumber } from 'libphonenumber-js'; - import { FieldValidationDefinition } from '@/spreadsheet-import/types'; import { isDefined } from 'twenty-ui'; import { FieldMetadataType } from '~/generated-metadata/graphql'; @@ -41,15 +39,6 @@ export const getSpreadSheetFieldValidationDefinitions = ( level: 'error', }, ]; - case FieldMetadataType.Phone: - return [ - { - rule: 'function', - isValid: (value: string) => isValidPhoneNumber(value), - errorMessage: fieldName + ' is not valid', - level: 'error', - }, - ]; case FieldMetadataType.Relation: return [ { diff --git a/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts b/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts index a0a69349fc35..b936f09833df 100644 --- a/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts +++ b/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts @@ -8,20 +8,12 @@ export const generateEmptyFieldValue = ( fieldMetadataItem: Pick, ) => { switch (fieldMetadataItem.type) { - case FieldMetadataType.Email: - case FieldMetadataType.Phone: case FieldMetadataType.Text: { return ''; } case FieldMetadataType.Emails: { return { primaryEmail: '', additionalEmails: null }; } - case FieldMetadataType.Link: { - return { - label: '', - url: '', - }; - } case FieldMetadataType.Links: { return { primaryLinkUrl: '', primaryLinkLabel: '', secondaryLinks: null }; } diff --git a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts index 4181fd65e807..b2fb02c29f62 100644 --- a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts +++ b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsCompositeFieldTypeConfigs.ts @@ -6,7 +6,6 @@ import { FieldEmailsValue, FieldFullNameValue, FieldLinksValue, - FieldLinkValue, FieldPhonesValue, } from '@/object-record/record-field/types/FieldMetadata'; import { SettingsFieldTypeConfig } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs'; @@ -38,8 +37,8 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { [FieldMetadataType.Currency]: { label: 'Currency', Icon: IllustrationIconCurrency, - subFields: ['amountMicros', 'currencyCode'], - filterableSubFields: ['amountMicros', 'currencyCode'], + subFields: ['amountMicros'], + filterableSubFields: ['amountMicros'], labelBySubField: { amountMicros: 'Amount', currencyCode: 'Currency', @@ -69,18 +68,6 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { }, category: 'Basic', } as const satisfies SettingsCompositeFieldTypeConfig, - [FieldMetadataType.Link]: { - label: 'Link', - Icon: IllustrationIconLink, - exampleValue: { url: 'www.twenty.com', label: '' }, - category: 'Basic', - subFields: ['url', 'label'], - filterableSubFields: ['url', 'label'], - labelBySubField: { - url: 'URL', - label: 'Label', - }, - } as const satisfies SettingsCompositeFieldTypeConfig, [FieldMetadataType.Links]: { label: 'Links', Icon: IllustrationIconLink, @@ -178,8 +165,8 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = { label: 'Actor', Icon: IllustrationIconSetting, category: 'Basic', - subFields: ['source', 'name', 'workspaceMemberId'], - filterableSubFields: ['source', 'name', 'workspaceMemberId'], + subFields: ['source'], + filterableSubFields: ['source'], labelBySubField: { source: 'Source', name: 'Name', diff --git a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts index 42f291b60eff..1039646c47ee 100644 --- a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts +++ b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs.ts @@ -4,10 +4,8 @@ import { IllustrationIconCalendarEvent, IllustrationIconCalendarTime, IllustrationIconJson, - IllustrationIconMail, IllustrationIconNumbers, IllustrationIconOneToMany, - IllustrationIconPhone, IllustrationIconSetting, IllustrationIconStar, IllustrationIconTag, @@ -22,11 +20,9 @@ import { FieldBooleanValue, FieldDateTimeValue, FieldDateValue, - FieldEmailValue, FieldJsonValue, FieldMultiSelectValue, FieldNumberValue, - FieldPhoneValue, FieldRatingValue, FieldRelationValue, FieldRichTextValue, @@ -114,17 +110,6 @@ export const SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS: SettingsNonCompositeFiel Icon: IllustrationIconOneToMany, category: 'Relation', } as const satisfies SettingsFieldTypeConfig>, - [FieldMetadataType.Email]: { - label: 'Email', - Icon: IllustrationIconMail, - category: 'Basic', - } as const satisfies SettingsFieldTypeConfig, - [FieldMetadataType.Phone]: { - label: 'Phone', - Icon: IllustrationIconPhone, - exampleValue: '+1234-567-890', - category: 'Basic', - } as const satisfies SettingsFieldTypeConfig, [FieldMetadataType.Rating]: { label: 'Rating', Icon: IllustrationIconStar, 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 882b57f7d1c1..9b50515b10b9 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 @@ -113,11 +113,9 @@ const previewableTypes = [ FieldMetadataType.DateTime, FieldMetadataType.Emails, FieldMetadataType.FullName, - FieldMetadataType.Link, FieldMetadataType.Links, FieldMetadataType.MultiSelect, FieldMetadataType.Number, - FieldMetadataType.Phone, FieldMetadataType.Phones, FieldMetadataType.Rating, FieldMetadataType.RawJson, diff --git a/packages/twenty-front/src/modules/settings/data-model/types/CompositeFieldType.ts b/packages/twenty-front/src/modules/settings/data-model/types/CompositeFieldType.ts index f1186c6d1047..ddf7b0d579e0 100644 --- a/packages/twenty-front/src/modules/settings/data-model/types/CompositeFieldType.ts +++ b/packages/twenty-front/src/modules/settings/data-model/types/CompositeFieldType.ts @@ -5,7 +5,6 @@ import { PickLiteral } from '~/types/PickLiteral'; export const COMPOSITE_FIELD_TYPES = [ 'CURRENCY', 'EMAILS', - 'LINK', 'LINKS', 'ADDRESS', 'PHONES', diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockFilterDefinitions.ts b/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockFilterDefinitions.ts index f3d24ae7a95c..92040bbb8aae 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockFilterDefinitions.ts +++ b/packages/twenty-front/src/modules/sign-in-background-mock/constants/SignInBackgroundMockFilterDefinitions.ts @@ -43,13 +43,13 @@ export const SIGN_IN_BACKGROUND_MOCK_FILTER_DEFINITIONS = [ fieldMetadataId: '20202020-a61d-4b78-b998-3fd88b4f73a1', label: 'Linkedin', iconName: 'IconBrandLinkedin', - type: 'LINK', + type: 'LINKS', }, { fieldMetadataId: '20202020-46e3-479a-b8f4-77137c74daa6', label: 'X', iconName: 'IconBrandX', - type: 'LINK', + type: 'LINKS', }, { fieldMetadataId: '20202020-4a5a-466f-92d9-c3870d9502a9', diff --git a/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx index 9e2e2b48ef95..963887f11e0d 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/LinkDisplay.tsx @@ -1,6 +1,5 @@ import { isNonEmptyString } from '@sniptt/guards'; -import { FieldLinkValue } from '@/object-record/record-field/types/FieldMetadata'; import { RoundedLink } from '@/ui/navigation/link/components/RoundedLink'; import { LinkType, @@ -8,7 +7,7 @@ import { } from '@/ui/navigation/link/components/SocialLink'; type LinkDisplayProps = { - value?: FieldLinkValue; + value?: { url: string; label?: string }; }; export const LinkDisplay = ({ value }: LinkDisplayProps) => { diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldSelect.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldSelect.tsx index 8c3f77e08b35..cfc683510006 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldSelect.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldSelect.tsx @@ -43,12 +43,9 @@ export const SettingsObjectNewFieldSelect = () => { }); const excludedFieldTypes: SettingsFieldType[] = ( [ - FieldMetadataType.Link, FieldMetadataType.Numeric, FieldMetadataType.RichText, FieldMetadataType.Actor, - FieldMetadataType.Email, - FieldMetadataType.Phone, ] as const ).filter(isDefined); diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index 9d98d33abd75..ec6414db9b94 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -7,7 +7,6 @@ import { DataSeedDemoWorkspaceCommand } from 'src/database/commands/data-seed-de import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module'; import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command'; import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; -import { UpgradeTo0_30CommandModule } from 'src/database/commands/upgrade-version/0-30/0-30-upgrade-version.module'; import { UpgradeTo0_31CommandModule } from 'src/database/commands/upgrade-version/0-31/0-31-upgrade-version.module'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; @@ -47,7 +46,6 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp DataSeedDemoWorkspaceModule, WorkspaceCacheStorageModule, WorkspaceMetadataVersionModule, - UpgradeTo0_30CommandModule, UpgradeTo0_31CommandModule, FeatureFlagModule, ], diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command.ts deleted file mode 100644 index 9356d7d920c1..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { InjectRepository } from '@nestjs/typeorm'; - -import chalk from 'chalk'; -import { isDefined } from 'class-validator'; -import { Command } from 'nest-commander'; -import { Repository } from 'typeorm'; - -import { - ActiveWorkspacesCommandOptions, - ActiveWorkspacesCommandRunner, -} from 'src/database/commands/active-workspaces.command'; -import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; -import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { ViewService } from 'src/modules/view/services/view.service'; -@Command({ - name: 'upgrade-0.30:fix-email-field-migration', - description: - 'Fix migration - delete deprecated email fields and add emails to person views', -}) -export class FixEmailFieldsToEmailsCommand extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - @InjectRepository(FieldMetadataEntity, 'metadata') - private readonly fieldMetadataRepository: Repository, - private readonly fieldMetadataService: FieldMetadataService, - private readonly typeORMService: TypeORMService, - private readonly dataSourceService: DataSourceService, - private readonly viewService: ViewService, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - _passedParam: string[], - _options: ActiveWorkspacesCommandOptions, - workspaceIds: string[], - ): Promise { - this.logger.log('Running command to fix migration'); - - for (const workspaceId of workspaceIds) { - let dataSourceMetadata; - - this.logger.log(`Running command for workspace ${workspaceId}`); - try { - dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( - workspaceId, - ); - - if (!dataSourceMetadata) { - throw new Error( - `Could not find dataSourceMetadata for workspace ${workspaceId}`, - ); - } - - const workspaceDataSource = - await this.typeORMService.connectToDataSource(dataSourceMetadata); - - if (!workspaceDataSource) { - throw new Error( - `Could not connect to dataSource for workspace ${workspaceId}`, - ); - } - } catch (error) { - this.logger.log( - chalk.red( - `Could not connect to workspace data source for workspace ${workspaceId}`, - ), - ); - continue; - } - - try { - const deprecatedPersonEmailFieldsMetadata = - await this.fieldMetadataRepository.findBy({ - standardId: PERSON_STANDARD_FIELD_IDS.email, - workspaceId: workspaceId, - }); - - const migratedEmailFieldMetadata = await this.fieldMetadataRepository - .findBy({ - standardId: PERSON_STANDARD_FIELD_IDS.emails, - workspaceId: workspaceId, - }) - .then((fields) => fields[0]); - - const personEmailFieldWasMigratedButHasDuplicate = - deprecatedPersonEmailFieldsMetadata.length > 0 && - isDefined(migratedEmailFieldMetadata); - - if (!personEmailFieldWasMigratedButHasDuplicate) { - this.logger.log( - chalk.yellow('No fields to migrate for workspace ' + workspaceId), - ); - continue; - } - - for (const deprecatedEmailFieldMetadata of deprecatedPersonEmailFieldsMetadata) { - await this.fieldMetadataService.deleteOneField( - { id: deprecatedEmailFieldMetadata.id }, - workspaceId, - ); - this.logger.log( - chalk.green(`Deleted email field for workspace ${workspaceId}.`), - ); - } - - const personObjectMetadaIdForWorkspace = - migratedEmailFieldMetadata.objectMetadataId; - - if (!isDefined(personObjectMetadaIdForWorkspace)) { - this.logger.log( - chalk.red( - `Could not find person object for workspace ${workspaceId}. Could not add emails to person view`, - ), - ); - continue; - } - - const personViewsIds = - await this.viewService.getViewsIdsForObjectMetadataId({ - workspaceId, - objectMetadataId: personObjectMetadaIdForWorkspace as string, - }); - - await this.viewService.addFieldToViews({ - workspaceId: workspaceId, - fieldId: migratedEmailFieldMetadata.id, - viewsIds: personViewsIds, - positions: personViewsIds.reduce((acc, personView) => { - if (!personView.id) { - return acc; - } - acc[personView.id] = 4; - - return acc; - }, []), - }); - this.logger.log(chalk.green(`Added emails to view ${workspaceId}.`)); - } catch (error) { - this.logger.log( - chalk.red( - `Running command on workspace ${workspaceId} failed with error: ${error}`, - ), - ); - continue; - } finally { - this.logger.log( - chalk.green(`Finished running command for workspace ${workspaceId}.`), - ); - } - - this.logger.log(chalk.green(`Command completed!`)); - } - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-view-filter-operand-for-date-time.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-view-filter-operand-for-date-time.command.ts deleted file mode 100644 index f2e98d6600a7..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-fix-view-filter-operand-for-date-time.command.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { InjectRepository } from '@nestjs/typeorm'; - -import chalk from 'chalk'; -import { Command } from 'nest-commander'; -import { Any, Repository } from 'typeorm'; - -import { - ActiveWorkspacesCommandOptions, - ActiveWorkspacesCommandRunner, -} from 'src/database/commands/active-workspaces.command'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { - FieldMetadataEntity, - FieldMetadataType, -} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; -import { ViewFilterWorkspaceEntity } from 'src/modules/view/standard-objects/view-filter.workspace-entity'; - -@Command({ - name: 'upgrade-0.30:fix-view-filter-operand-for-date-time', - description: 'Fix the view filter operand for date time fields', -}) -export class FixViewFilterOperandForDateTimeCommand extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - @InjectRepository(FieldMetadataEntity, 'metadata') - private readonly fieldMetadataRepository: Repository, - private readonly dataSourceService: DataSourceService, - private readonly twentyORMGlobalManager: TwentyORMGlobalManager, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - _passedParam: string[], - _options: ActiveWorkspacesCommandOptions, - workspaceIds: string[], - ): Promise { - for (const workspaceId of workspaceIds) { - try { - const dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( - workspaceId, - ); - - if (!dataSourceMetadata) { - throw new Error( - `Could not find dataSourceMetadata for workspace ${workspaceId}`, - ); - } - - const viewFilterRepository = - await this.twentyORMGlobalManager.getRepositoryForWorkspace( - workspaceId, - 'viewFilter', - ); - - const dateTimeFieldMetadata = await this.fieldMetadataRepository.find({ - where: { - workspaceId, - type: FieldMetadataType.DATE_TIME, - }, - }); - - const dateTimeFieldMetadataIds = dateTimeFieldMetadata.map( - (fieldMetadata) => fieldMetadata.id, - ); - - const lessThanUpdatedResult = await viewFilterRepository.update( - { - operand: 'lessThan', - fieldMetadataId: Any(dateTimeFieldMetadataIds), - }, - { - operand: 'isBefore', - }, - ); - - const greaterThanUpdatedResult = await viewFilterRepository.update( - { - operand: 'greaterThan', - fieldMetadataId: Any(dateTimeFieldMetadataIds), - }, - { - operand: 'isAfter', - }, - ); - - this.logger.log( - `Updated ${(lessThanUpdatedResult.affected ?? 0) + (greaterThanUpdatedResult.affected ?? 0)} view filters for workspace ${workspaceId}`, - ); - } catch (error) { - this.logger.log( - chalk.red( - `Error running command for workspace ${workspaceId}: ${error}`, - ), - ); - continue; - } finally { - this.logger.log( - chalk.green(`Finished running command for workspace ${workspaceId}.`), - ); - } - - this.logger.log(chalk.green(`Command completed!`)); - } - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command.ts deleted file mode 100644 index 2e4969297a6b..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command.ts +++ /dev/null @@ -1,360 +0,0 @@ -import { InjectRepository } from '@nestjs/typeorm'; - -import chalk from 'chalk'; -import { Command } from 'nest-commander'; -import { QueryRunner, Repository } from 'typeorm'; - -import { - ActiveWorkspacesCommandOptions, - ActiveWorkspacesCommandRunner, -} from 'src/database/commands/active-workspaces.command'; -import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; -import { - FieldMetadataEntity, - FieldMetadataType, -} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; -import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { ViewService } from 'src/modules/view/services/view.service'; -import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity'; -@Command({ - name: 'upgrade-0.30:migrate-email-fields-to-emails', - description: 'Migrating fields of deprecated type EMAIL to type EMAILS', -}) -export class MigrateEmailFieldsToEmailsCommand extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - @InjectRepository(FieldMetadataEntity, 'metadata') - private readonly fieldMetadataRepository: Repository, - @InjectRepository(ObjectMetadataEntity, 'metadata') - private readonly objectMetadataRepository: Repository, - private readonly fieldMetadataService: FieldMetadataService, - private readonly twentyORMGlobalManager: TwentyORMGlobalManager, - private readonly typeORMService: TypeORMService, - private readonly dataSourceService: DataSourceService, - private readonly viewService: ViewService, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - _passedParam: string[], - _options: ActiveWorkspacesCommandOptions, - workspaceIds: string[], - ): Promise { - this.logger.log( - 'Running command to migrate email type fields to emails type', - ); - - for (const workspaceId of workspaceIds) { - let dataSourceMetadata; - let workspaceQueryRunner; - - this.logger.log(`Running command for workspace ${workspaceId}`); - try { - dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( - workspaceId, - ); - - if (!dataSourceMetadata) { - throw new Error( - `Could not find dataSourceMetadata for workspace ${workspaceId}`, - ); - } - - const workspaceDataSource = - await this.typeORMService.connectToDataSource(dataSourceMetadata); - - if (!workspaceDataSource) { - throw new Error( - `Could not connect to dataSource for workspace ${workspaceId}`, - ); - } - - workspaceQueryRunner = workspaceDataSource.createQueryRunner(); - - await workspaceQueryRunner.connect(); - } catch (error) { - this.logger.log( - chalk.red( - `Could not connect to workspace data source for workspace ${workspaceId}`, - ), - ); - continue; - } - - try { - await this.migratePersonEmailFieldToEmailsField( - workspaceId, - workspaceQueryRunner, - dataSourceMetadata, - ); - - const customFieldsWithEmailType = - await this.fieldMetadataRepository.find({ - where: { - workspaceId, - type: FieldMetadataType.EMAIL, - isCustom: true, - }, - }); - - for (const customFieldWithEmailType of customFieldsWithEmailType) { - const objectMetadata = await this.objectMetadataRepository.findOne({ - where: { id: customFieldWithEmailType.objectMetadataId }, - }); - - if (!objectMetadata) { - throw new Error( - `Could not find objectMetadata for field ${customFieldWithEmailType.name}`, - ); - } - - this.logger.log( - `Attempting to migrate custom field ${customFieldWithEmailType.name} on ${objectMetadata.nameSingular}.`, - ); - - const fieldName = customFieldWithEmailType.name; - const { id: _id, ...fieldWithEmailTypeWithoutId } = - customFieldWithEmailType; - - const emailDefaultValue = fieldWithEmailTypeWithoutId.defaultValue; - - const defaultValueForEmailsField = { - primaryEmail: emailDefaultValue, - additionalEmails: null, - }; - - try { - const tmpNewEmailsField = await this.fieldMetadataService.createOne( - { - ...fieldWithEmailTypeWithoutId, - type: FieldMetadataType.EMAILS, - defaultValue: defaultValueForEmailsField, - name: `${fieldName}Tmp`, - } satisfies CreateFieldInput, - ); - - const tableName = computeTableName( - objectMetadata.nameSingular, - objectMetadata.isCustom, - ); - - // Migrate data from email to emails.primaryEmail - await this.migrateDataWithinTable({ - sourceColumnName: `${customFieldWithEmailType.name}`, - targetColumnName: `${tmpNewEmailsField.name}PrimaryEmail`, - tableName, - workspaceQueryRunner, - dataSourceMetadata, - }); - - // Duplicate email field's views behaviour for new emails field - await this.viewService.removeFieldFromViews({ - workspaceId: workspaceId, - fieldId: tmpNewEmailsField.id, - }); - - const viewFieldRepository = - await this.twentyORMGlobalManager.getRepositoryForWorkspace( - workspaceId, - 'viewField', - ); - const viewFieldsWithDeprecatedField = - await viewFieldRepository.find({ - where: { - fieldMetadataId: customFieldWithEmailType.id, - isVisible: true, - }, - }); - - await this.viewService.addFieldToViews({ - workspaceId: workspaceId, - fieldId: tmpNewEmailsField.id, - viewsIds: viewFieldsWithDeprecatedField - .filter((viewField) => viewField.viewId !== null) - .map((viewField) => viewField.viewId as string), - positions: viewFieldsWithDeprecatedField.reduce( - (acc, viewField) => { - if (!viewField.viewId) { - return acc; - } - acc[viewField.viewId] = viewField.position; - - return acc; - }, - [], - ), - }); - - // Delete email field - await this.fieldMetadataService.deleteOneField( - { id: customFieldWithEmailType.id }, - workspaceId, - ); - - // Rename temporary emails field - await this.fieldMetadataService.updateOne(tmpNewEmailsField.id, { - id: tmpNewEmailsField.id, - workspaceId: tmpNewEmailsField.workspaceId, - name: `${fieldName}`, - isCustom: false, - }); - - this.logger.log( - `Migration of ${customFieldWithEmailType.name} on ${objectMetadata.nameSingular} done!`, - ); - } catch (error) { - this.logger.log( - `Failed to migrate field ${customFieldWithEmailType.name} on ${objectMetadata.nameSingular}, rolling back.`, - ); - - // Re-create initial field if it was deleted - const initialField = - await this.fieldMetadataService.findOneWithinWorkspace( - workspaceId, - { - where: { - name: `${customFieldWithEmailType.name}`, - objectMetadataId: customFieldWithEmailType.objectMetadataId, - }, - }, - ); - - const tmpNewEmailsField = - await this.fieldMetadataService.findOneWithinWorkspace( - workspaceId, - { - where: { - name: `${customFieldWithEmailType.name}Tmp`, - objectMetadataId: customFieldWithEmailType.objectMetadataId, - }, - }, - ); - - if (!initialField) { - this.logger.log( - `Re-creating initial Email field ${customFieldWithEmailType.name} but of type emails`, // Cannot create email fields anymore - ); - const restoredField = await this.fieldMetadataService.createOne({ - ...customFieldWithEmailType, - defaultValue: defaultValueForEmailsField, - type: FieldMetadataType.EMAILS, - }); - const tableName = computeTableName( - objectMetadata.nameSingular, - objectMetadata.isCustom, - ); - - if (tmpNewEmailsField) { - this.logger.log( - `Restoring data in field ${customFieldWithEmailType.name}`, - ); - await this.migrateDataWithinTable({ - sourceColumnName: `${tmpNewEmailsField.name}PrimaryEmail`, - targetColumnName: `${restoredField.name}PrimaryEmail`, - tableName, - workspaceQueryRunner, - dataSourceMetadata, - }); - } else { - this.logger.log( - `Failed to restore data in link field ${customFieldWithEmailType.name}`, - ); - } - } - - if (tmpNewEmailsField) { - await this.fieldMetadataService.deleteOneField( - { id: tmpNewEmailsField.id }, - workspaceId, - ); - } - } - } - } catch (error) { - await workspaceQueryRunner.release(); - - this.logger.log( - chalk.red( - `Running command on workspace ${workspaceId} failed with error: ${error}`, - ), - ); - continue; - } finally { - await workspaceQueryRunner.release(); - } - - this.logger.log(chalk.green(`Command completed!`)); - } - } - - private async migratePersonEmailFieldToEmailsField( - workspaceId: string, - workspaceQueryRunner: any, - dataSourceMetadata: any, - ) { - this.logger.log(`Migrating person email field of type EMAIL to EMAILS`); - - const personEmailFieldMetadata = await this.fieldMetadataRepository.findOne( - { - where: { - workspaceId, - standardId: PERSON_STANDARD_FIELD_IDS.email, - }, - }, - ); - - if (!personEmailFieldMetadata) { - this.logger.log( - `Could not find person email field with standardId ${PERSON_STANDARD_FIELD_IDS.email}, skipping migration`, - ); - - return; - } - - await this.migrateDataWithinTable({ - sourceColumnName: 'email', - targetColumnName: 'emailsPrimaryEmail', - tableName: 'person', - workspaceQueryRunner, - dataSourceMetadata, - }); - - if (personEmailFieldMetadata) { - await this.fieldMetadataService.deleteOneField( - { - id: personEmailFieldMetadata.id, - }, - workspaceId, - ); - } - } - - private async migrateDataWithinTable({ - sourceColumnName, - targetColumnName, - tableName, - workspaceQueryRunner, - dataSourceMetadata, - }: { - sourceColumnName: string; - targetColumnName: string; - tableName: string; - workspaceQueryRunner: QueryRunner; - dataSourceMetadata: DataSourceEntity; - }) { - await workspaceQueryRunner.query( - `UPDATE "${dataSourceMetadata.schema}"."${tableName}" SET "${targetColumnName}" = "${sourceColumnName}"`, - ); - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-phone-fields-to-phones.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-phone-fields-to-phones.command.ts deleted file mode 100644 index 6560bb9625dc..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-migrate-phone-fields-to-phones.command.ts +++ /dev/null @@ -1,366 +0,0 @@ -import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; - -import chalk from 'chalk'; -import { isDefined, isEmpty } from 'class-validator'; -import { parsePhoneNumber } from 'libphonenumber-js'; -import { Command } from 'nest-commander'; -import { DataSource, QueryRunner, Repository } from 'typeorm'; - -import { - ActiveWorkspacesCommandOptions, - ActiveWorkspacesCommandRunner, -} from 'src/database/commands/active-workspaces.command'; -import { TypeORMService } from 'src/database/typeorm/typeorm.service'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; -import { - FieldMetadataEntity, - FieldMetadataType, -} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; -import { computeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; -import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { ViewService } from 'src/modules/view/services/view.service'; -import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity'; - -type MigratePhoneFieldsToPhonesCommandOptions = ActiveWorkspacesCommandOptions; -@Command({ - name: 'upgrade-0.30:migrate-phone-fields-to-phones', - description: 'Migrating fields of deprecated type PHONE to type PHONES', -}) -export class MigratePhoneFieldsToPhonesCommand extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - @InjectRepository(FieldMetadataEntity, 'metadata') - private readonly fieldMetadataRepository: Repository, - @InjectRepository(ObjectMetadataEntity, 'metadata') - private readonly objectMetadataRepository: Repository, - @InjectDataSource('metadata') - private readonly metadataDataSource: DataSource, - private readonly fieldMetadataService: FieldMetadataService, - private readonly twentyORMGlobalManager: TwentyORMGlobalManager, - private readonly typeORMService: TypeORMService, - private readonly dataSourceService: DataSourceService, - private readonly viewService: ViewService, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - _passedParam: string[], - _options: MigratePhoneFieldsToPhonesCommandOptions, - workspaceIds: string[], - ): Promise { - this.logger.log( - 'Running command to migrate phone type fields to phones type', - ); - for (const workspaceId of workspaceIds) { - this.logger.log(`Running command for workspace ${workspaceId}`); - try { - const dataSourceMetadata = - await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceId( - workspaceId, - ); - - if (!dataSourceMetadata) { - throw new Error( - `Could not find dataSourceMetadata for workspace ${workspaceId}`, - ); - } - const workspaceDataSource = - await this.typeORMService.connectToDataSource(dataSourceMetadata); - - if (!workspaceDataSource) { - throw new Error( - `Could not connect to dataSource for workspace ${workspaceId}`, - ); - } - const standardPersonPhoneFieldWithTextType = - await this.fieldMetadataRepository.findOneBy({ - workspaceId, - standardId: PERSON_STANDARD_FIELD_IDS.phone, - }); - - if (!standardPersonPhoneFieldWithTextType) { - throw new Error( - `Could not find standard phone field on person for workspace ${workspaceId}`, - ); - } - - await this.migrateStandardPersonPhoneField({ - standardPersonPhoneField: standardPersonPhoneFieldWithTextType, - workspaceDataSource, - workspaceSchemaName: dataSourceMetadata.schema, - }); - - const fieldsWithPhoneType = await this.fieldMetadataRepository.find({ - where: { - workspaceId, - type: FieldMetadataType.PHONE, - }, - }); - - for (const deprecatedPhoneField of fieldsWithPhoneType) { - await this.migrateCustomPhoneField({ - phoneField: deprecatedPhoneField, - workspaceDataSource, - workspaceSchemaName: dataSourceMetadata.schema, - }); - } - } catch (error) { - this.logger.log( - chalk.red( - `Field migration on workspace ${workspaceId} failed with error: ${error}`, - ), - ); - continue; - } - this.logger.log(chalk.green(`Command completed!`)); - } - } - - private async migrateStandardPersonPhoneField({ - standardPersonPhoneField, - workspaceDataSource, - workspaceSchemaName, - }: { - standardPersonPhoneField: FieldMetadataEntity; - workspaceDataSource: DataSource; - workspaceSchemaName: string; - }) { - const personObjectMetadata = await this.objectMetadataRepository.findOne({ - where: { id: standardPersonPhoneField.objectMetadataId }, - }); - - if (!personObjectMetadata) { - throw new Error( - `Could not find Person objectMetadata (id ${standardPersonPhoneField.objectMetadataId})`, - ); - } - - this.logger.log(`Attempting to migrate standard person phone field.`); - const workspaceQueryRunner = workspaceDataSource.createQueryRunner(); - - await workspaceQueryRunner.connect(); - const { id: _id, ...deprecatedPhoneFieldWithoutId } = - standardPersonPhoneField; - - const workspaceId = standardPersonPhoneField.workspaceId; - - try { - let standardPersonPhonesField = - await this.fieldMetadataRepository.findOneBy({ - workspaceId, - standardId: PERSON_STANDARD_FIELD_IDS.phones, - }); - - if (!standardPersonPhonesField) { - standardPersonPhonesField = await this.fieldMetadataService.createOne({ - ...deprecatedPhoneFieldWithoutId, - label: 'Phones', - type: FieldMetadataType.PHONES, - defaultValue: null, - name: 'phones', - } satisfies CreateFieldInput); - - // StandardId and isCustom are not exposed in CreateFieldInput - await this.metadataDataSource.query( - `UPDATE "metadata"."fieldMetadata" SET "standardId" = $1, "isCustom" = $2 where "id"=$3`, - [ - PERSON_STANDARD_FIELD_IDS.phones, - 'false', - standardPersonPhonesField.id, - ], - ); - - await this.viewService.removeFieldFromViews({ - workspaceId: workspaceId, - fieldId: standardPersonPhonesField.id, - }); - } - - // Copy phone data from Text type to Phones type - await this.copyAndParseDeprecatedPhoneFieldDataIntoNewPhonesField({ - workspaceQueryRunner, - workspaceSchemaName, - }); - - // Add (deprecated) to Phone field label - await this.metadataDataSource.query( - `UPDATE "metadata"."fieldMetadata" SET "label" = $1 where "id"=$2`, - ['Phone (deprecated)', standardPersonPhoneField.id], - ); - - // Add new phones field to views and hide deprecated phone field - const viewFieldRepository = - await this.twentyORMGlobalManager.getRepositoryForWorkspace( - workspaceId, - 'viewField', - ); - const viewFieldsWithDeprecatedPhoneField = await viewFieldRepository.find( - { - where: { - fieldMetadataId: standardPersonPhoneField.id, - isVisible: true, - }, - }, - ); - - await this.viewService.addFieldToViews({ - workspaceId: workspaceId, - fieldId: standardPersonPhonesField.id, - viewsIds: viewFieldsWithDeprecatedPhoneField - .filter((viewField) => viewField.viewId !== null) - .map((viewField) => viewField.viewId as string), - positions: viewFieldsWithDeprecatedPhoneField.reduce( - (acc, viewField) => { - if (!viewField.viewId) { - return acc; - } - acc[viewField.viewId] = viewField.position; - - return acc; - }, - [], - ), - size: 150, - }); - - await this.viewService.removeFieldFromViews({ - workspaceId: workspaceId, - fieldId: standardPersonPhoneField.id, - }); - - this.logger.log( - `Migration of standard person phone field to phones is done!`, - ); - } catch (error) { - this.logger.log( - chalk.red( - `Failed to migrate field standard person phone field to phones, rolling back. (Error: ${error})`, - ), - ); - - // Delete new phones field if it was created - const newPhonesField = - await this.fieldMetadataService.findOneWithinWorkspace(workspaceId, { - where: { - name: 'phones', - objectMetadataId: standardPersonPhoneField.objectMetadataId, - }, - }); - - if (newPhonesField) { - this.logger.log( - `Deleting phones field of type Phone as part of rolling back.`, - ); - await this.fieldMetadataService.deleteOneField( - { id: newPhonesField.id }, - workspaceId, - ); - } - - // Revert Phone field label (remove (deprecated)) - await this.metadataDataSource.query( - `UPDATE "metadata"."fieldMetadata" SET "label" = $1 where "id"=$2`, - ['Phone', standardPersonPhoneField.id], - ); - } finally { - await workspaceQueryRunner.release(); - } - } - - private async migrateCustomPhoneField({ - phoneField, - workspaceDataSource, - workspaceSchemaName, - }: { - phoneField: FieldMetadataEntity; - workspaceDataSource: DataSource; - workspaceSchemaName: string; - }) { - if (!phoneField) return; - const objectMetadata = await this.objectMetadataRepository.findOne({ - where: { id: phoneField.objectMetadataId }, - }); - - if (!objectMetadata) { - throw new Error( - `Could not find objectMetadata for field ${phoneField.name}`, - ); - } - this.logger.log( - `Attempting to migrate field ${phoneField.name} on ${objectMetadata.nameSingular} from Phone to Text.`, - ); - const workspaceQueryRunner = workspaceDataSource.createQueryRunner(); - - await workspaceQueryRunner.connect(); - - try { - await this.metadataDataSource.query( - `UPDATE "metadata"."fieldMetadata" SET "type" = $1 where "id"=$2`, - [FieldMetadataType.TEXT, phoneField.id], - ); - - await workspaceQueryRunner.query( - `ALTER TABLE "${workspaceSchemaName}"."${computeTableName(objectMetadata.nameSingular, objectMetadata.isCustom)}" ALTER COLUMN "${computeColumnName(phoneField.name)}" TYPE TEXT`, - ); - } catch (error) { - this.logger.log( - chalk.red( - `Failed to migrate field ${phoneField.name} on ${objectMetadata.nameSingular} from Phone to Text.`, - ), - ); - } finally { - await workspaceQueryRunner.release(); - } - } - - private async copyAndParseDeprecatedPhoneFieldDataIntoNewPhonesField({ - workspaceQueryRunner, - workspaceSchemaName, - }: { - workspaceQueryRunner: QueryRunner; - workspaceSchemaName: string; - }) { - const deprecatedPhoneFieldRows = await workspaceQueryRunner.query( - `SELECT id, phone FROM "${workspaceSchemaName}"."person" WHERE - phone IS NOT null`, - ); - - for (const row of deprecatedPhoneFieldRows) { - const phoneColumnValue = row['phone']; - - if (isDefined(phoneColumnValue) && !isEmpty(phoneColumnValue)) { - const query = `UPDATE "${workspaceSchemaName}"."person" SET "phonesPrimaryPhoneCountryCode" = $1,"phonesPrimaryPhoneNumber" = $2 where "id"=$3 AND ("phonesPrimaryPhoneCountryCode" IS NULL OR "phonesPrimaryPhoneCountryCode" = '');`; - - try { - const parsedPhoneColumnValue = parsePhoneNumber(phoneColumnValue); - - await workspaceQueryRunner.query(query, [ - `+${parsedPhoneColumnValue.countryCallingCode}`, - parsedPhoneColumnValue.nationalNumber, - row.id, - ]); - } catch (error) { - this.logger.log( - chalk.red( - `Could not save phone number ${phoneColumnValue}, will try again storing value as is without parsing, with default country code.`, - ), - ); - // Store the invalid string for invalid phone numbers - await workspaceQueryRunner.query(query, [ - '', - phoneColumnValue, - row.id, - ]); - } - } - } - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending.ts deleted file mode 100644 index 3d1744910f48..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { InjectRepository } from '@nestjs/typeorm'; - -import chalk from 'chalk'; -import { Command } from 'nest-commander'; -import { IsNull, Repository } from 'typeorm'; - -import { - ActiveWorkspacesCommandOptions, - ActiveWorkspacesCommandRunner, -} from 'src/database/commands/active-workspaces.command'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; -import { - MessageChannelSyncStage, - MessageChannelWorkspaceEntity, -} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; -@Command({ - name: 'upgrade-0.30:set-stale-message-sync-back-to-pending', - description: 'Set stale message sync back to pending', -}) -export class SetStaleMessageSyncBackToPendingCommand extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - private readonly twentyORMGlobalManager: TwentyORMGlobalManager, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - _passedParam: string[], - _options: ActiveWorkspacesCommandOptions, - workspaceIds: string[], - ): Promise { - this.logger.log( - 'Running command to set stale message sync back to pending', - ); - - for (const workspaceId of workspaceIds) { - this.logger.log(`Running command for workspace ${workspaceId}`); - - try { - const dataSource = - await this.twentyORMGlobalManager.getDataSourceForWorkspace( - workspaceId, - ); - - const messageChannelRepository = - await this.twentyORMGlobalManager.getRepositoryForWorkspace( - workspaceId, - 'messageChannel', - ); - - dataSource.transaction(async (entityManager) => { - await messageChannelRepository.update( - { - syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING, - syncStageStartedAt: IsNull(), - }, - { - syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_PENDING, - }, - entityManager, - ); - - await messageChannelRepository.update( - { - syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_ONGOING, - syncStageStartedAt: IsNull(), - }, - { - syncStage: - MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING, - }, - entityManager, - ); - }); - } catch (error) { - this.logger.log( - chalk.red( - `Running command on workspace ${workspaceId} failed with error: ${error}`, - ), - ); - continue; - } - - this.logger.log(chalk.green(`Command completed!`)); - } - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.command.ts deleted file mode 100644 index 25ff077ca5e1..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.command.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { InjectRepository } from '@nestjs/typeorm'; - -import { Command } from 'nest-commander'; -import { Repository } from 'typeorm'; - -import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command'; -import { FixEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command'; -import { FixViewFilterOperandForDateTimeCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-view-filter-operand-for-date-time.command'; -import { MigrateEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command'; -import { MigratePhoneFieldsToPhonesCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-phone-fields-to-phones.command'; -import { SetStaleMessageSyncBackToPendingCommand } from 'src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command'; - -interface UpdateTo0_30CommandOptions { - workspaceId?: string; -} - -@Command({ - name: 'upgrade-0.30', - description: 'Upgrade to 0.30', -}) -export class UpgradeTo0_30Command extends ActiveWorkspacesCommandRunner { - constructor( - @InjectRepository(Workspace, 'core') - protected readonly workspaceRepository: Repository, - private readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand, - private readonly migrateEmailFieldsToEmails: MigrateEmailFieldsToEmailsCommand, - private readonly setStaleMessageSyncBackToPendingCommand: SetStaleMessageSyncBackToPendingCommand, - private readonly fixEmailFieldsToEmailsCommand: FixEmailFieldsToEmailsCommand, - private readonly migratePhoneFieldsToPhones: MigratePhoneFieldsToPhonesCommand, - private readonly fixViewFilterOperandForDateTimeCommand: FixViewFilterOperandForDateTimeCommand, - ) { - super(workspaceRepository); - } - - async executeActiveWorkspacesCommand( - passedParam: string[], - options: UpdateTo0_30CommandOptions, - workspaceIds: string[], - ): Promise { - await this.syncWorkspaceMetadataCommand.executeActiveWorkspacesCommand( - passedParam, - { - ...options, - force: true, - }, - workspaceIds, - ); - await this.migrateEmailFieldsToEmails.executeActiveWorkspacesCommand( - passedParam, - options, - workspaceIds, - ); - await this.setStaleMessageSyncBackToPendingCommand.executeActiveWorkspacesCommand( - passedParam, - options, - workspaceIds, - ); - await this.fixEmailFieldsToEmailsCommand.executeActiveWorkspacesCommand( - passedParam, - options, - workspaceIds, - ); - await this.migratePhoneFieldsToPhones.executeActiveWorkspacesCommand( - passedParam, - options, - workspaceIds, - ); - await this.fixViewFilterOperandForDateTimeCommand.executeActiveWorkspacesCommand( - passedParam, - options, - workspaceIds, - ); - } -} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.module.ts deleted file mode 100644 index 191bad9352cb..000000000000 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-30/0-30-upgrade-version.module.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -import { FixEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-email-field-migration.command'; -import { FixViewFilterOperandForDateTimeCommand } from 'src/database/commands/upgrade-version/0-30/0-30-fix-view-filter-operand-for-date-time.command'; -import { MigrateEmailFieldsToEmailsCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-email-fields-to-emails.command'; -import { MigratePhoneFieldsToPhonesCommand } from 'src/database/commands/upgrade-version/0-30/0-30-migrate-phone-fields-to-phones.command'; -import { SetStaleMessageSyncBackToPendingCommand } from 'src/database/commands/upgrade-version/0-30/0-30-set-stale-message-sync-back-to-pending'; -import { UpgradeTo0_30Command } from 'src/database/commands/upgrade-version/0-30/0-30-upgrade-version.command'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; -import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; -import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module'; -import { WorkspaceSyncMetadataCommandsModule } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module'; -import { ViewModule } from 'src/modules/view/view.module'; - -@Module({ - imports: [ - TypeOrmModule.forFeature([Workspace], 'core'), - WorkspaceSyncMetadataCommandsModule, - DataSourceModule, - WorkspaceMetadataVersionModule, - FieldMetadataModule, - TypeOrmModule.forFeature( - [FieldMetadataEntity, ObjectMetadataEntity], - 'metadata', - ), - TypeORMModule, - ViewModule, - ], - providers: [ - UpgradeTo0_30Command, - MigrateEmailFieldsToEmailsCommand, - SetStaleMessageSyncBackToPendingCommand, - FixEmailFieldsToEmailsCommand, - MigratePhoneFieldsToPhonesCommand, - FixViewFilterOperandForDateTimeCommand, - ], -}) -export class UpgradeTo0_30CommandModule {} diff --git a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index 337cdda3e2ae..cc23b7e26a99 100644 --- a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -104,20 +104,6 @@ const fieldUuidMock = { defaultValue: null, }; -const fieldPhoneMock = { - name: 'fieldPhone', - type: FieldMetadataType.PHONE, - isNullable: true, - defaultValue: null, -}; - -const fieldEmailMock = { - name: 'fieldEmail', - type: FieldMetadataType.EMAIL, - isNullable: true, - defaultValue: null, -}; - const fieldDateTimeMock = { name: 'fieldDateTime', type: FieldMetadataType.DATE_TIME, @@ -253,9 +239,7 @@ const fieldPhonesMock = { export const fields = [ fieldUuidMock, fieldTextMock, - fieldPhoneMock, fieldPhonesMock, - fieldEmailMock, fieldEmailsMock, fieldDateTimeMock, fieldDateMock, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index fb6597e19be9..dc2fbbfd2a21 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -61,8 +61,6 @@ export class TypeMapperService { const typeScalarMapping = new Map([ [FieldMetadataType.UUID, UUIDScalarType], [FieldMetadataType.TEXT, GraphQLString], - [FieldMetadataType.PHONE, GraphQLString], - [FieldMetadataType.EMAIL, GraphQLString], [FieldMetadataType.DATE_TIME, GraphQLISODateTime], [FieldMetadataType.DATE, GraphQLISODateTime], [FieldMetadataType.BOOLEAN, GraphQLBoolean], @@ -101,8 +99,6 @@ export class TypeMapperService { >([ [FieldMetadataType.UUID, IDFilterType], [FieldMetadataType.TEXT, StringFilterType], - [FieldMetadataType.PHONE, StringFilterType], - [FieldMetadataType.EMAIL, StringFilterType], [FieldMetadataType.DATE_TIME, DateFilterType], [FieldMetadataType.DATE, DateFilterType], [FieldMetadataType.BOOLEAN, BooleanFilterType], @@ -129,8 +125,6 @@ export class TypeMapperService { const typeOrderByMapping = new Map([ [FieldMetadataType.UUID, OrderByDirectionType], [FieldMetadataType.TEXT, OrderByDirectionType], - [FieldMetadataType.PHONE, OrderByDirectionType], - [FieldMetadataType.EMAIL, OrderByDirectionType], [FieldMetadataType.DATE_TIME, OrderByDirectionType], [FieldMetadataType.DATE, OrderByDirectionType], [FieldMetadataType.BOOLEAN, OrderByDirectionType], diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts index 6976586f5a18..4b2dd84f1e5f 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts @@ -18,8 +18,6 @@ export const mapFieldMetadataToGraphqlQuery = ( const fieldIsSimpleValue = [ FieldMetadataType.UUID, FieldMetadataType.TEXT, - FieldMetadataType.PHONE, - FieldMetadataType.EMAIL, FieldMetadataType.DATE_TIME, FieldMetadataType.DATE, FieldMetadataType.BOOLEAN, @@ -89,14 +87,6 @@ export const mapFieldMetadataToGraphqlQuery = ( } } }`; - } else if (fieldType === FieldMetadataType.LINK) { - return ` - ${field.name} - { - label - url - } - `; } else if (fieldType === FieldMetadataType.LINKS) { return ` ${field.name} diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts index 5f10e3be0d75..bde4e50992fa 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts @@ -1,20 +1,8 @@ -import { - fields, - objectMetadataItemMock, -} from 'src/engine/api/__mocks__/object-metadata-item.mock'; +import { objectMetadataItemMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; import { computeSchemaComponents } from 'src/engine/core-modules/open-api/utils/components.utils'; -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; describe('computeSchemaComponents', () => { - it('should test all non-deprecated field types', () => { - expect(fields.map((field) => field.type)).toEqual( - Object.keys(FieldMetadataType).filter( - (key) => - key !== FieldMetadataType.LINK && key !== FieldMetadataType.TS_VECTOR, - ), - ); - }); it('should compute schema components', () => { expect( computeSchemaComponents([ @@ -32,9 +20,6 @@ describe('computeSchemaComponents', () => { fieldText: { type: 'string', }, - fieldPhone: { - type: 'string', - }, fieldPhones: { properties: { additionalPhones: { @@ -49,10 +34,6 @@ describe('computeSchemaComponents', () => { }, type: 'object', }, - fieldEmail: { - type: 'string', - format: 'email', - }, fieldEmails: { type: 'object', properties: { @@ -216,9 +197,6 @@ describe('computeSchemaComponents', () => { fieldText: { type: 'string', }, - fieldPhone: { - type: 'string', - }, fieldPhones: { properties: { additionalPhones: { @@ -233,10 +211,6 @@ describe('computeSchemaComponents', () => { }, type: 'object', }, - fieldEmail: { - type: 'string', - format: 'email', - }, fieldEmails: { type: 'object', properties: { @@ -399,9 +373,6 @@ describe('computeSchemaComponents', () => { fieldText: { type: 'string', }, - fieldPhone: { - type: 'string', - }, fieldPhones: { properties: { additionalPhones: { @@ -416,10 +387,6 @@ describe('computeSchemaComponents', () => { }, type: 'object', }, - fieldEmail: { - type: 'string', - format: 'email', - }, fieldEmails: { type: 'object', properties: { diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index 4b1910e1c08a..07ad4770c782 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -56,11 +56,8 @@ const getFieldProperties = ( case FieldMetadataType.UUID: return { type: 'string', format: 'uuid' }; case FieldMetadataType.TEXT: - case FieldMetadataType.PHONE: case FieldMetadataType.RICH_TEXT: return { type: 'string' }; - case FieldMetadataType.EMAIL: - return { type: 'string', format: 'email' }; case FieldMetadataType.DATE_TIME: return { type: 'string', format: 'date-time' }; case FieldMetadataType.DATE: @@ -139,7 +136,6 @@ const getSchemaComponentsProperties = ({ enum: field.options.map((option: { value: string }) => option.value), }; break; - case FieldMetadataType.LINK: case FieldMetadataType.LINKS: case FieldMetadataType.CURRENCY: case FieldMetadataType.FULL_NAME: diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts index de361576a7bb..fbc999d49e70 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts @@ -5,7 +5,6 @@ import { addressCompositeType } from 'src/engine/metadata-modules/field-metadata import { currencyCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type'; import { emailsCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/emails.composite-type'; import { fullNameCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; -import { linkCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/link.composite-type'; import { linksCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/links.composite-type'; import { phonesCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/phones.composite-type'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; @@ -14,7 +13,6 @@ export const compositeTypeDefinitions = new Map< FieldMetadataType, CompositeType >([ - [FieldMetadataType.LINK, linkCompositeType], [FieldMetadataType.LINKS, linksCompositeType], [FieldMetadataType.CURRENCY, currencyCompositeType], [FieldMetadataType.FULL_NAME, fullNameCompositeType], diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts deleted file mode 100644 index 4037a5d5c9f8..000000000000 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/link.composite-type.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CompositeType } from 'src/engine/metadata-modules/field-metadata/interfaces/composite-type.interface'; - -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; - -export const linkCompositeType: CompositeType = { - type: FieldMetadataType.LINK, - properties: [ - { - name: 'label', - type: FieldMetadataType.TEXT, - hidden: false, - isRequired: false, - }, - { - name: 'url', - type: FieldMetadataType.TEXT, - hidden: false, - isRequired: false, - }, - ], -}; - -export type LinkMetadata = { - label: string; - url: string; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts index a617f8ad971e..42d98b4d6e55 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts @@ -71,16 +71,6 @@ export class FieldMetadataDefaultValueDate { value: Date | null; } -export class FieldMetadataDefaultValueLink { - @ValidateIf((object, value) => value !== null) - @IsQuotedString() - label: string | null; - - @ValidateIf((object, value) => value !== null) - @IsQuotedString() - url: string | null; -} - export class FieldMetadataDefaultValueCurrency { @ValidateIf((object, value) => value !== null) @IsNumberString() diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts index 5035fd3ed760..5ab017f17b12 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts @@ -24,16 +24,13 @@ import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-met export enum FieldMetadataType { UUID = 'UUID', TEXT = 'TEXT', - PHONE = 'PHONE', PHONES = 'PHONES', - EMAIL = 'EMAIL', EMAILS = 'EMAILS', DATE_TIME = 'DATE_TIME', DATE = 'DATE', BOOLEAN = 'BOOLEAN', NUMBER = 'NUMBER', NUMERIC = 'NUMERIC', - LINK = 'LINK', LINKS = 'LINKS', CURRENCY = 'CURRENCY', FULL_NAME = 'FULL_NAME', diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts index ae56a6d3ab60..d38872cf4c5c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts @@ -145,20 +145,6 @@ export class FieldMetadataService extends TypeOrmQueryService { it('should generate a nullable value false for TEXT, EMAIL, PHONE no matter what the input is', () => { expect(generateNullable(FieldMetadataType.TEXT, false)).toEqual(false); - expect(generateNullable(FieldMetadataType.PHONE, false)).toEqual(false); - expect(generateNullable(FieldMetadataType.EMAIL, false)).toEqual(false); expect(generateNullable(FieldMetadataType.TEXT, true)).toEqual(false); - expect(generateNullable(FieldMetadataType.PHONE, true)).toEqual(false); - expect(generateNullable(FieldMetadataType.EMAIL, true)).toEqual(false); expect(generateNullable(FieldMetadataType.TEXT)).toEqual(false); - expect(generateNullable(FieldMetadataType.PHONE)).toEqual(false); - expect(generateNullable(FieldMetadataType.EMAIL)).toEqual(false); }); it('should should return true if no input is given', () => { diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts index 3695a072ec9c..60e4b04261c3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/__tests__/validate-default-value-based-on-type.spec.ts @@ -40,32 +40,6 @@ describe('validateDefaultValueForType', () => { ).toBe(false); }); - it('should validate string default value for PHONE type', () => { - expect( - validateDefaultValueForType(FieldMetadataType.PHONE, "'+123456789'") - .isValid, - ).toBe(true); - }); - - it('should return false for invalid string default value for PHONE type', () => { - expect( - validateDefaultValueForType(FieldMetadataType.PHONE, 123).isValid, - ).toBe(false); - }); - - it('should validate string default value for EMAIL type', () => { - expect( - validateDefaultValueForType(FieldMetadataType.EMAIL, "'test@example.com'") - .isValid, - ).toBe(true); - }); - - it('should return false for invalid string default value for EMAIL type', () => { - expect( - validateDefaultValueForType(FieldMetadataType.EMAIL, 123).isValid, - ).toBe(false); - }); - it('should validate number default value for NUMBER type', () => { expect( validateDefaultValueForType(FieldMetadataType.NUMBER, 100).isValid, @@ -90,27 +64,6 @@ describe('validateDefaultValueForType', () => { ).toBe(false); }); - // LINK type - it('should validate LINK default value', () => { - expect( - validateDefaultValueForType(FieldMetadataType.LINK, { - label: "'http://example.com'", - url: "'Example'", - }).isValid, - ).toBe(true); - }); - - it('should return false for invalid LINK default value', () => { - expect( - validateDefaultValueForType( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error Just for testing purposes - { label: 123, url: {} }, - FieldMetadataType.LINK, - ).isValid, - ).toBe(false); - }); - // CURRENCY type it('should validate CURRENCY default value', () => { expect( diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts index 958ff0e3212b..3d9f8bcf368a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-default-value.ts @@ -7,8 +7,6 @@ export function generateDefaultValue( ): FieldMetadataDefaultValue { switch (type) { case FieldMetadataType.TEXT: - case FieldMetadataType.PHONE: - case FieldMetadataType.EMAIL: return "''"; case FieldMetadataType.EMAILS: return { @@ -31,11 +29,6 @@ export function generateDefaultValue( addressLat: null, addressLng: null, }; - case FieldMetadataType.LINK: - return { - url: "''", - label: "''", - }; case FieldMetadataType.CURRENCY: return { amountMicros: null, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts index 5724314847b0..759012070ffc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/generate-nullable.ts @@ -11,8 +11,6 @@ export function generateNullable( switch (type) { case FieldMetadataType.TEXT: - case FieldMetadataType.PHONE: - case FieldMetadataType.EMAIL: return false; default: return inputNullableValue ?? true; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts index 110673bd1cf6..911162c9ae39 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util.ts @@ -3,7 +3,6 @@ import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/fi export const isCompositeFieldMetadataType = ( type: FieldMetadataType, ): type is - | FieldMetadataType.LINK | FieldMetadataType.CURRENCY | FieldMetadataType.FULL_NAME | FieldMetadataType.ADDRESS @@ -12,7 +11,6 @@ export const isCompositeFieldMetadataType = ( | FieldMetadataType.EMAILS | FieldMetadataType.PHONES => { return [ - FieldMetadataType.LINK, FieldMetadataType.CURRENCY, FieldMetadataType.FULL_NAME, FieldMetadataType.ADDRESS, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts index 06303046259d..a5cea6d00482 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts @@ -15,7 +15,6 @@ import { FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueEmails, FieldMetadataDefaultValueFullName, - FieldMetadataDefaultValueLink, FieldMetadataDefaultValueLinks, FieldMetadataDefaultValueNowFunction, FieldMetadataDefaultValueNumber, @@ -34,8 +33,6 @@ export const defaultValueValidatorsMap = { FieldMetadataDefaultValueUuidFunction, ], [FieldMetadataType.TEXT]: [FieldMetadataDefaultValueString], - [FieldMetadataType.PHONE]: [FieldMetadataDefaultValueString], - [FieldMetadataType.EMAIL]: [FieldMetadataDefaultValueString], [FieldMetadataType.DATE_TIME]: [ FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueNowFunction, @@ -44,7 +41,6 @@ export const defaultValueValidatorsMap = { [FieldMetadataType.BOOLEAN]: [FieldMetadataDefaultValueBoolean], [FieldMetadataType.NUMBER]: [FieldMetadataDefaultValueNumber], [FieldMetadataType.NUMERIC]: [FieldMetadataDefaultValueString], - [FieldMetadataType.LINK]: [FieldMetadataDefaultValueLink], [FieldMetadataType.CURRENCY]: [FieldMetadataDefaultValueCurrency], [FieldMetadataType.FULL_NAME]: [FieldMetadataDefaultValueFullName], [FieldMetadataType.RATING]: [FieldMetadataDefaultValueString], diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts index 643819ddcb7d..7cf5edb0e39d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts @@ -21,8 +21,6 @@ import { export type BasicFieldMetadataType = | FieldMetadataType.UUID | FieldMetadataType.TEXT - | FieldMetadataType.PHONE - | FieldMetadataType.EMAIL | FieldMetadataType.NUMERIC | FieldMetadataType.NUMBER | FieldMetadataType.BOOLEAN diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts index 41c133621e7e..31738c0225d9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts @@ -23,7 +23,6 @@ export type CompositeFieldMetadataType = | FieldMetadataType.ADDRESS | FieldMetadataType.CURRENCY | FieldMetadataType.FULL_NAME - | FieldMetadataType.LINK | FieldMetadataType.LINKS | FieldMetadataType.EMAILS | FieldMetadataType.PHONES; diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts index 67955d0bb411..46ec14ad3fc1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts @@ -18,9 +18,6 @@ export const fieldMetadataTypeToColumnType = ( case FieldMetadataType.RICH_TEXT: case FieldMetadataType.ARRAY: return 'text'; - case FieldMetadataType.PHONE: - case FieldMetadataType.EMAIL: - return 'varchar'; case FieldMetadataType.NUMERIC: return 'numeric'; case FieldMetadataType.NUMBER: diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts index 53aa564e4f82..5df5da052f2b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts @@ -52,24 +52,6 @@ export class WorkspaceMigrationFactory { }, }, ], - [ - FieldMetadataType.PHONE, - { - factory: this.basicColumnActionFactory, - options: { - defaultValue: '', - }, - }, - ], - [ - FieldMetadataType.EMAIL, - { - factory: this.basicColumnActionFactory, - options: { - defaultValue: '', - }, - }, - ], [FieldMetadataType.NUMERIC, { factory: this.basicColumnActionFactory }], [FieldMetadataType.NUMBER, { factory: this.basicColumnActionFactory }], [FieldMetadataType.POSITION, { factory: this.basicColumnActionFactory }], @@ -84,7 +66,6 @@ export class WorkspaceMigrationFactory { FieldMetadataType.MULTI_SELECT, { factory: this.enumColumnActionFactory }, ], - [FieldMetadataType.LINK, { factory: this.compositeColumnActionFactory }], [ FieldMetadataType.CURRENCY, { factory: this.compositeColumnActionFactory }, diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts b/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts index e2124ab2a9e6..0bbd2cf5a074 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts @@ -32,10 +32,7 @@ export class CalendarEventParticipantPersonListener { >, ) { for (const eventPayload of payload.events) { - if ( - eventPayload.properties.after.emails?.primaryEmail === null && - eventPayload.properties.after.email === null - ) { + if (eventPayload.properties.after.emails?.primaryEmail === null) { continue; } @@ -44,9 +41,7 @@ export class CalendarEventParticipantPersonListener { CalendarEventParticipantMatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.after.emails?.primaryEmail ?? - eventPayload.properties.after.email, // TODO + email: eventPayload.properties.after.emails?.primaryEmail, personId: eventPayload.recordId, }, ); @@ -64,16 +59,14 @@ export class CalendarEventParticipantPersonListener { objectRecordUpdateEventChangedProperties( eventPayload.properties.before, eventPayload.properties.after, - ).includes('email') + ).includes('emails') ) { // TODO: modify this job to take an array of participants to match await this.messageQueueService.add( CalendarEventParticipantUnmatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.before.emails?.primaryEmail ?? - eventPayload.properties.before.email, + email: eventPayload.properties.before.emails?.primaryEmail, personId: eventPayload.recordId, }, ); @@ -82,9 +75,7 @@ export class CalendarEventParticipantPersonListener { CalendarEventParticipantMatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.after.emails?.primaryEmail ?? - eventPayload.properties.after.email, + email: eventPayload.properties.after.emails?.primaryEmail, personId: eventPayload.recordId, }, ); diff --git a/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts b/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts index 7b4447b40584..d9fd73740494 100644 --- a/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts +++ b/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { isDefined } from 'class-validator'; import chunk from 'lodash.chunk'; import compact from 'lodash.compact'; import { Any, EntityManager, Repository } from 'typeorm'; @@ -13,7 +12,6 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; -import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; import { CONTACTS_CREATION_BATCH_SIZE } from 'src/modules/contact-creation-manager/constants/contacts-creation-batch-size.constant'; @@ -54,13 +52,6 @@ export class CreateCompanyAndContactService { return []; } - const emailsFieldMetadata = await this.fieldMetadataRepository.findOne({ - where: { - workspaceId: workspaceId, - standardId: PERSON_STANDARD_FIELD_IDS.emails, - }, - }); - const personRepository = await this.twentyORMGlobalManager.getRepositoryForWorkspace( workspaceId, @@ -89,16 +80,14 @@ export class CreateCompanyAndContactService { } const alreadyCreatedContacts = await personRepository.find({ - where: isDefined(emailsFieldMetadata) - ? { - emails: { primaryEmail: Any(uniqueHandles) }, - } - : { email: Any(uniqueHandles) }, + where: { + emails: { primaryEmail: Any(uniqueHandles) }, + }, }); - const alreadyCreatedContactEmails: string[] = isDefined(emailsFieldMetadata) - ? alreadyCreatedContacts?.map(({ emails }) => emails?.primaryEmail) - : alreadyCreatedContacts?.map(({ email }) => email); + const alreadyCreatedContactEmails: string[] = alreadyCreatedContacts?.map( + ({ emails }) => emails?.primaryEmail, + ); const filteredContactsToCreate = uniqueContacts.filter( (participant) => diff --git a/packages/twenty-server/src/modules/match-participant/match-participant.service.ts b/packages/twenty-server/src/modules/match-participant/match-participant.service.ts index 195a88ea4e3c..e0dc0dd6e2d3 100644 --- a/packages/twenty-server/src/modules/match-participant/match-participant.service.ts +++ b/packages/twenty-server/src/modules/match-participant/match-participant.service.ts @@ -7,7 +7,6 @@ import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/ import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; -import { PERSON_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity'; import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; @@ -60,35 +59,19 @@ export class MatchParticipantService< ...new Set(participants.map((participant) => participant.handle)), ]; - const emailsFieldMetadata = await this.fieldMetadataRepository.findOne({ - where: { - workspaceId: workspaceId, - standardId: PERSON_STANDARD_FIELD_IDS.emails, - }, - }); - const personRepository = await this.twentyORMManager.getRepository( 'person', ); - const people = emailsFieldMetadata - ? await personRepository.find( - { - where: { - emails: Any(uniqueParticipantsHandles), - }, - }, - transactionManager, - ) - : await personRepository.find( - { - where: { - email: Any(uniqueParticipantsHandles), - }, - }, - transactionManager, - ); + const people = await personRepository.find( + { + where: { + emails: Any(uniqueParticipantsHandles), + }, + }, + transactionManager, + ); const workspaceMemberRepository = await this.twentyORMManager.getRepository( @@ -105,10 +88,8 @@ export class MatchParticipantService< ); for (const handle of uniqueParticipantsHandles) { - const person = people.find((person) => - emailsFieldMetadata - ? person.emails?.primaryEmail === handle - : person.email === handle, + const person = people.find( + (person) => person.emails?.primaryEmail === handle, ); const workspaceMember = workspaceMembers.find( diff --git a/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts b/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts index 1d4a0c6c38aa..53bf3329a2eb 100644 --- a/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts +++ b/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts @@ -32,10 +32,7 @@ export class MessageParticipantPersonListener { >, ) { for (const eventPayload of payload.events) { - if ( - !eventPayload.properties.after.emails?.primaryEmail && - !eventPayload.properties.after.email - ) { + if (!eventPayload.properties.after.emails?.primaryEmail) { continue; } @@ -43,9 +40,7 @@ export class MessageParticipantPersonListener { MessageParticipantMatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.after.emails?.primaryEmail ?? - eventPayload.properties.after.email, + email: eventPayload.properties.after.emails?.primaryEmail, personId: eventPayload.recordId, }, ); @@ -60,10 +55,6 @@ export class MessageParticipantPersonListener { ) { for (const eventPayload of payload.events) { if ( - objectRecordUpdateEventChangedProperties( - eventPayload.properties.before, - eventPayload.properties.after, - ).includes('email') || objectRecordUpdateEventChangedProperties( eventPayload.properties.before, eventPayload.properties.after, @@ -73,9 +64,7 @@ export class MessageParticipantPersonListener { MessageParticipantUnmatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.before.emails?.primaryEmail ?? - eventPayload.properties.before.email, + email: eventPayload.properties.before.emails?.primaryEmail, personId: eventPayload.recordId, }, ); @@ -84,9 +73,7 @@ export class MessageParticipantPersonListener { MessageParticipantMatchParticipantJob.name, { workspaceId: payload.workspaceId, - email: - eventPayload.properties.after.emails?.primaryEmail ?? - eventPayload.properties.after.email, + email: eventPayload.properties.after.emails?.primaryEmail, personId: eventPayload.recordId, }, ); diff --git a/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts b/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts index d2cccd1d9edd..39fcead68cb7 100644 --- a/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts +++ b/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts @@ -63,16 +63,6 @@ export class PersonWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceIsNullable() [NAME_FIELD_NAME]: FullNameMetadata | null; - @WorkspaceField({ - standardId: PERSON_STANDARD_FIELD_IDS.email, - type: FieldMetadataType.EMAIL, - label: 'Email', - description: 'Contact’s Email', - icon: 'IconMail', - }) - @WorkspaceIsDeprecated() - email: string; - @WorkspaceField({ standardId: PERSON_STANDARD_FIELD_IDS.emails, type: FieldMetadataType.EMAILS,