Add fields to update in update record action (#9108)

- update backend action so it handles composite fields
- add fields to update multiselect
- generate form based on that field
- add icons
This commit is contained in:
Thomas Trompette
2024-12-18 14:32:21 +01:00
committed by GitHub
parent b6508cc615
commit 94676215ad
9 changed files with 191 additions and 15 deletions

View File

@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { v4 } from 'uuid';
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
@ -20,7 +21,6 @@ import {
WorkflowActionType,
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import { isDefined } from 'src/utils/is-defined';
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
const TRIGGER_STEP_ID = 'trigger';
@ -152,6 +152,7 @@ export class WorkflowVersionStepWorkspaceService {
objectName: activeObjectMetadataItem?.nameSingular || '',
objectRecord: {},
objectRecordId: '',
fieldsToUpdate: [],
},
},
};

View File

@ -14,6 +14,7 @@ export type WorkflowUpdateRecordActionInput = {
objectName: string;
objectRecord: ObjectRecord;
objectRecordId: string;
fieldsToUpdate: string[];
};
export type WorkflowDeleteRecordActionInput = {

View File

@ -2,7 +2,11 @@ import { Injectable } from '@nestjs/common';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { formatData } from 'src/engine/twenty-orm/utils/format-data.util';
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
import {
RecordCRUDActionException,
RecordCRUDActionExceptionCode,
@ -12,7 +16,11 @@ import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/wor
@Injectable()
export class UpdateRecordWorkflowAction implements WorkflowAction {
constructor(private readonly twentyORMManager: TwentyORMManager) {}
constructor(
private readonly twentyORMManager: TwentyORMManager,
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
) {}
async execute(
workflowActionInput: WorkflowUpdateRecordActionInput,
@ -34,14 +42,85 @@ export class UpdateRecordWorkflowAction implements WorkflowAction {
);
}
const workspaceId = this.scopedWorkspaceContextFactory.create().workspaceId;
if (!workspaceId) {
throw new RecordCRUDActionException(
'Failed to read: Workspace ID is required',
RecordCRUDActionExceptionCode.INVALID_REQUEST,
);
}
const currentCacheVersion =
await this.workspaceCacheStorageService.getMetadataVersion(workspaceId);
if (currentCacheVersion === undefined) {
throw new RecordCRUDActionException(
'Failed to read: Metadata cache version not found',
RecordCRUDActionExceptionCode.INVALID_REQUEST,
);
}
const objectMetadataMaps =
await this.workspaceCacheStorageService.getObjectMetadataMaps(
workspaceId,
currentCacheVersion,
);
if (!objectMetadataMaps) {
throw new RecordCRUDActionException(
'Failed to read: Object metadata collection not found',
RecordCRUDActionExceptionCode.INVALID_REQUEST,
);
}
const objectMetadataItemWithFieldsMaps =
getObjectMetadataMapItemByNameSingular(
objectMetadataMaps,
workflowActionInput.objectName,
);
if (!objectMetadataItemWithFieldsMaps) {
throw new RecordCRUDActionException(
`Failed to read: Object ${workflowActionInput.objectName} not found`,
RecordCRUDActionExceptionCode.INVALID_REQUEST,
);
}
if (workflowActionInput.fieldsToUpdate.length === 0) {
return {
result: {
...objectRecord,
},
};
}
const objectRecordWithFilteredFields = Object.keys(
workflowActionInput.objectRecord,
).reduce((acc, key) => {
if (workflowActionInput.fieldsToUpdate.includes(key)) {
return {
...acc,
[key]: workflowActionInput.objectRecord[key],
};
}
return acc;
}, {});
const objectRecordFormatted = formatData(
objectRecordWithFilteredFields,
objectMetadataItemWithFieldsMaps,
);
await repository.update(workflowActionInput.objectRecordId, {
...workflowActionInput.objectRecord,
...objectRecordFormatted,
});
return {
result: {
...objectRecord,
...workflowActionInput.objectRecord,
...objectRecordWithFilteredFields,
},
};
}