From f3c9854be3372fd325909e0007dba3c8cb91af4b Mon Sep 17 00:00:00 2001 From: Weiko Date: Wed, 17 Jan 2024 15:03:11 +0100 Subject: [PATCH] Add select type to field metadata decorator (#3471) * Add select type to field metadata decorator * add option id generation for new field --- .../decorators/field-metadata.decorator.ts | 3 +- .../reflect-field-metadata.interface.ts | 5 ++- .../reflective-metadata.factory.ts | 1 - .../message-participant.object-metadata.ts | 9 +++- .../workspace-sync.metadata.service.ts | 41 ++++++++++++++++--- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts index 430e0604b..a2fc29f60 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts @@ -42,6 +42,7 @@ export function FieldMetadata( label: `${restParams.label} id (foreign key)`, description: `${restParams.description} id foreign key`, defaultValue: null, + options: undefined, }, joinColumn, isNullable, @@ -73,7 +74,7 @@ function generateFieldMetadata( isNullable: params.type === FieldMetadataType.RELATION ? true : isNullable, isSystem, isCustom: false, - // TODO: handle options + stringify for the diff. + options: params.options ? JSON.stringify(params.options) : null, description: params.description, icon: params.icon, defaultValue: defaultValue ? JSON.stringify(defaultValue) : null, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts index 48fad391c..6d4c66ca2 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-field-metadata.interface.ts @@ -1,5 +1,6 @@ import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface'; import { GateDecoratorParams } from 'src/workspace/workspace-sync-metadata/interfaces/gate-decorator.interface'; +import { FieldMetadataOptions } from 'src/metadata/field-metadata/interfaces/field-metadata-options.interface'; import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; @@ -12,12 +13,13 @@ export interface FieldMetadataDecoratorParams< icon?: string; defaultValue?: FieldMetadataDefaultValue; joinColumn?: string; + options?: FieldMetadataOptions; } export interface ReflectFieldMetadata { [key: string]: Omit< FieldMetadataDecoratorParams<'default'>, - 'defaultValue' | 'type' + 'defaultValue' | 'type' | 'options' > & { name: string; type: FieldMetadataType; @@ -28,5 +30,6 @@ export interface ReflectFieldMetadata { description?: string; defaultValue: string | null; gate?: GateDecoratorParams; + options?: string | null; }; } diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts index 88da5a509..ab10138f3 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/reflective-metadata.factory.ts @@ -43,7 +43,6 @@ export class ReflectiveMetadataFactory { ...field, workspaceId, isSystem: objectMetadata.isSystem || field.isSystem, - defaultValue: field.defaultValue, })), }; } diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/message-participant.object-metadata.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/message-participant.object-metadata.ts index 00e27c5e4..410c3bed4 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/message-participant.object-metadata.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/message-participant.object-metadata.ts @@ -31,11 +31,16 @@ export class MessageParticipantObjectMetadata extends BaseObjectMetadata { message: MessageObjectMetadata; @FieldMetadata({ - // this will be a type select: from, to, cc, bcc - type: FieldMetadataType.TEXT, + type: FieldMetadataType.SELECT, label: 'Role', description: 'Role', icon: 'IconAt', + options: [ + { value: 'from', label: 'From', position: 0, color: 'green' }, + { value: 'to', label: 'To', position: 1, color: 'blue' }, + { value: 'cc', label: 'Cc', position: 2, color: 'orange' }, + { value: 'bcc', label: 'Bcc', position: 3, color: 'red' }, + ], defaultValue: { value: 'from' }, }) role: string; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts index 89ca0d935..14c96d38b 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts @@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import diff from 'microdiff'; import { In, Repository } from 'typeorm'; import camelCase from 'lodash.camelcase'; +import { v4 as uuidV4 } from 'uuid'; import { PartialFieldMetadata } from 'src/workspace/workspace-sync-metadata/interfaces/partial-field-metadata.interface'; import { PartialObjectMetadata } from 'src/workspace/workspace-sync-metadata/interfaces/partial-object-metadata.interface'; @@ -23,8 +24,8 @@ import { } from 'src/metadata/relation-metadata/relation-metadata.entity'; import { filterIgnoredProperties, - convertStringifiedFieldsToJSON, mapObjectMetadataByUniqueIdentifier, + convertStringifiedFieldsToJSON, } from 'src/workspace/workspace-sync-metadata/utils/sync-metadata.util'; import { standardObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects'; import { @@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerService } from 'src/workspace/workspace-migrati import { ReflectiveMetadataFactory } from 'src/workspace/workspace-sync-metadata/reflective-metadata.factory'; import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity'; import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util'; +import { FieldMetadataComplexOptions } from 'src/metadata/field-metadata/dtos/options.input'; @Injectable() export class WorkspaceSyncMetadataService { @@ -227,10 +229,9 @@ export class WorkspaceSyncMetadataService { objectsToCreate.map((object) => ({ ...object, isActive: true, - fields: Object.values(object.fields).map((field) => ({ - ...convertStringifiedFieldsToJSON(field), - isActive: true, - })), + fields: Object.values(object.fields).map((field) => + this.prepareFieldMetadataForCreation(field), + ), })), ); const identifiers = createdObjectMetadataCollection.map( @@ -254,7 +255,9 @@ export class WorkspaceSyncMetadataService { // CREATE FIELDS const createdFields = await this.fieldMetadataRepository.save( - fieldsToCreate.map((field) => convertStringifiedFieldsToJSON(field)), + fieldsToCreate.map((field) => + this.prepareFieldMetadataForCreation(field), + ), ); // UPDATE FIELDS @@ -302,6 +305,32 @@ export class WorkspaceSyncMetadataService { } } + private prepareFieldMetadataForCreation(field: PartialFieldMetadata) { + const convertedField = convertStringifiedFieldsToJSON(field); + + return { + ...convertedField, + ...(convertedField.type === FieldMetadataType.SELECT && + convertedField.options + ? { + options: this.generateUUIDForNewSelectFieldOptions( + convertedField.options as FieldMetadataComplexOptions[], + ), + } + : {}), + isActive: true, + }; + } + + private generateUUIDForNewSelectFieldOptions( + options: FieldMetadataComplexOptions[], + ): FieldMetadataComplexOptions[] { + return options.map((option) => ({ + ...option, + id: uuidV4(), + })); + } + private async syncRelationMetadata( workspaceId: string, dataSourceId: string,