Add select type to field metadata decorator (#3471)

* Add select type to field metadata decorator

* add option id generation for new field
This commit is contained in:
Weiko
2024-01-17 15:03:11 +01:00
committed by GitHub
parent 5d4e226aad
commit f3c9854be3
5 changed files with 48 additions and 11 deletions

View File

@ -42,6 +42,7 @@ export function FieldMetadata<T extends FieldMetadataType>(
label: `${restParams.label} id (foreign key)`, label: `${restParams.label} id (foreign key)`,
description: `${restParams.description} id foreign key`, description: `${restParams.description} id foreign key`,
defaultValue: null, defaultValue: null,
options: undefined,
}, },
joinColumn, joinColumn,
isNullable, isNullable,
@ -73,7 +74,7 @@ function generateFieldMetadata<T extends FieldMetadataType>(
isNullable: params.type === FieldMetadataType.RELATION ? true : isNullable, isNullable: params.type === FieldMetadataType.RELATION ? true : isNullable,
isSystem, isSystem,
isCustom: false, isCustom: false,
// TODO: handle options + stringify for the diff. options: params.options ? JSON.stringify(params.options) : null,
description: params.description, description: params.description,
icon: params.icon, icon: params.icon,
defaultValue: defaultValue ? JSON.stringify(defaultValue) : null, defaultValue: defaultValue ? JSON.stringify(defaultValue) : null,

View File

@ -1,5 +1,6 @@
import { FieldMetadataDefaultValue } from 'src/metadata/field-metadata/interfaces/field-metadata-default-value.interface'; 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 { 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'; import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
@ -12,12 +13,13 @@ export interface FieldMetadataDecoratorParams<
icon?: string; icon?: string;
defaultValue?: FieldMetadataDefaultValue<T>; defaultValue?: FieldMetadataDefaultValue<T>;
joinColumn?: string; joinColumn?: string;
options?: FieldMetadataOptions<T>;
} }
export interface ReflectFieldMetadata { export interface ReflectFieldMetadata {
[key: string]: Omit< [key: string]: Omit<
FieldMetadataDecoratorParams<'default'>, FieldMetadataDecoratorParams<'default'>,
'defaultValue' | 'type' 'defaultValue' | 'type' | 'options'
> & { > & {
name: string; name: string;
type: FieldMetadataType; type: FieldMetadataType;
@ -28,5 +30,6 @@ export interface ReflectFieldMetadata {
description?: string; description?: string;
defaultValue: string | null; defaultValue: string | null;
gate?: GateDecoratorParams; gate?: GateDecoratorParams;
options?: string | null;
}; };
} }

View File

@ -43,7 +43,6 @@ export class ReflectiveMetadataFactory {
...field, ...field,
workspaceId, workspaceId,
isSystem: objectMetadata.isSystem || field.isSystem, isSystem: objectMetadata.isSystem || field.isSystem,
defaultValue: field.defaultValue,
})), })),
}; };
} }

View File

@ -31,11 +31,16 @@ export class MessageParticipantObjectMetadata extends BaseObjectMetadata {
message: MessageObjectMetadata; message: MessageObjectMetadata;
@FieldMetadata({ @FieldMetadata({
// this will be a type select: from, to, cc, bcc type: FieldMetadataType.SELECT,
type: FieldMetadataType.TEXT,
label: 'Role', label: 'Role',
description: 'Role', description: 'Role',
icon: 'IconAt', 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' }, defaultValue: { value: 'from' },
}) })
role: string; role: string;

View File

@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import diff from 'microdiff'; import diff from 'microdiff';
import { In, Repository } from 'typeorm'; import { In, Repository } from 'typeorm';
import camelCase from 'lodash.camelcase'; 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 { 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'; 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'; } from 'src/metadata/relation-metadata/relation-metadata.entity';
import { import {
filterIgnoredProperties, filterIgnoredProperties,
convertStringifiedFieldsToJSON,
mapObjectMetadataByUniqueIdentifier, mapObjectMetadataByUniqueIdentifier,
convertStringifiedFieldsToJSON,
} from 'src/workspace/workspace-sync-metadata/utils/sync-metadata.util'; } from 'src/workspace/workspace-sync-metadata/utils/sync-metadata.util';
import { standardObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects'; import { standardObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects';
import { import {
@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerService } from 'src/workspace/workspace-migrati
import { ReflectiveMetadataFactory } from 'src/workspace/workspace-sync-metadata/reflective-metadata.factory'; import { ReflectiveMetadataFactory } from 'src/workspace/workspace-sync-metadata/reflective-metadata.factory';
import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity'; import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity';
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util'; import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
import { FieldMetadataComplexOptions } from 'src/metadata/field-metadata/dtos/options.input';
@Injectable() @Injectable()
export class WorkspaceSyncMetadataService { export class WorkspaceSyncMetadataService {
@ -227,10 +229,9 @@ export class WorkspaceSyncMetadataService {
objectsToCreate.map((object) => ({ objectsToCreate.map((object) => ({
...object, ...object,
isActive: true, isActive: true,
fields: Object.values(object.fields).map((field) => ({ fields: Object.values(object.fields).map((field) =>
...convertStringifiedFieldsToJSON(field), this.prepareFieldMetadataForCreation(field),
isActive: true, ),
})),
})), })),
); );
const identifiers = createdObjectMetadataCollection.map( const identifiers = createdObjectMetadataCollection.map(
@ -254,7 +255,9 @@ export class WorkspaceSyncMetadataService {
// CREATE FIELDS // CREATE FIELDS
const createdFields = await this.fieldMetadataRepository.save( const createdFields = await this.fieldMetadataRepository.save(
fieldsToCreate.map((field) => convertStringifiedFieldsToJSON(field)), fieldsToCreate.map((field) =>
this.prepareFieldMetadataForCreation(field),
),
); );
// UPDATE FIELDS // 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( private async syncRelationMetadata(
workspaceId: string, workspaceId: string,
dataSourceId: string, dataSourceId: string,