From 9a77386917971acccb03d48f3ae5b800d8b176ea Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Thu, 10 Oct 2024 15:36:33 +0200 Subject: [PATCH] Fix workflow statuses (#7555) Event was not emitted after first version insertion. So initial status was not set. Also adding workflow related objects to timeline activities. --- .../constants/standard-field-ids.ts | 10 +++ .../favorite.workspace-entity.ts | 44 ++++++++++++ .../timeline-activity.workspace-entity.ts | 68 +++++++++++++++++++ .../workflow-create-many.post-query.hook.ts | 53 ++++++++++++--- .../workflow-create-one.post-query.hook.ts | 41 ++++++++++- .../query-hooks/workflow-query-hook.module.ts | 8 +++ ...orkflow-event-listener.workspace-entity.ts | 1 - .../workflow-run.workspace-entity.ts | 35 +++++++++- .../workflow-version.workspace-entity.ts | 38 ++++++++--- .../workflow.workspace-entity.ts | 23 +++++-- 10 files changed, 291 insertions(+), 30 deletions(-) diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index 624504052c..764c48237f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -191,6 +191,9 @@ export const TIMELINE_ACTIVITY_STANDARD_FIELD_IDS = { opportunity: '20202020-7664-4a35-a3df-580d389fd527', task: '20202020-b2f5-415c-9135-a31dfe49501b', note: '20202020-ec55-4135-8da5-3a20badc0156', + workflow: '20202020-616c-4ad3-a2e9-c477c341e295', + workflowVersion: '20202020-74f1-4711-a129-e14ca0ecd744', + workflowRun: '20202020-96f0-401b-9186-a3a0759225ac', custom: '20202020-4a71-41b0-9f83-9cdcca3f8b14', linkedRecordCachedName: '20202020-cfdb-4bef-bbce-a29f41230934', linkedRecordId: '20202020-2e0e-48c0-b445-ee6c1e61687d', @@ -204,6 +207,8 @@ export const FAVORITE_STANDARD_FIELD_IDS = { company: '20202020-cff5-4682-8bf9-069169e08279', opportunity: '20202020-dabc-48e1-8318-2781a2b32aa2', workflow: '20202020-b11b-4dc8-999a-6bd0a947b463', + workflowVersion: '20202020-e1b8-4caf-b55a-3ab4d4cbcd21', + workflowRun: '20202020-db5a-4fe4-9a13-9afa22b1e762', task: '20202020-1b1b-4b3b-8b1b-7f8d6a1d7d5c', note: '20202020-1f25-43fe-8b00-af212fdde824', view: '20202020-5a93-4fa9-acce-e73481a0bbdf', @@ -411,6 +416,7 @@ export const WORKFLOW_STANDARD_FIELD_IDS = { runs: '20202020-759b-4340-b58b-e73595c4df4f', eventListeners: '20202020-0229-4c66-832e-035c67579a38', favorites: '20202020-c554-4c41-be7a-cf9cd4b0d512', + timelineActivities: '20202020-906e-486a-a798-131a5f081faf', }; export const WORKFLOW_RUN_STANDARD_FIELD_IDS = { @@ -423,6 +429,8 @@ export const WORKFLOW_RUN_STANDARD_FIELD_IDS = { position: '20202020-7802-4c40-ae89-1f506fe3365c', createdBy: '20202020-6007-401a-8aa5-e6f38581a6f3', output: '20202020-7be4-4db2-8ac6-3ff0d740843d', + favorites: '20202020-4baf-4604-b899-2f7fcfbbf90d', + timelineActivities: '20202020-af4d-4eb0-babc-eb960a45b356', }; export const WORKFLOW_VERSION_STANDARD_FIELD_IDS = { @@ -433,6 +441,8 @@ export const WORKFLOW_VERSION_STANDARD_FIELD_IDS = { position: '20202020-791d-4950-ab28-0e704767ae1c', runs: '20202020-1d08-46df-901a-85045f18099a', steps: '20202020-5988-4a64-b94a-1f9b7b989039', + favorites: '20202020-b8e0-4e57-928d-b51671cc71f2', + timelineActivities: '20202020-fcb0-4695-b17e-3b43a421c633', }; export const WORKSPACE_MEMBER_STANDARD_FIELD_IDS = { diff --git a/packages/twenty-server/src/modules/favorite/standard-objects/favorite.workspace-entity.ts b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.workspace-entity.ts index 0aa6b7d3ae..db425cda4e 100644 --- a/packages/twenty-server/src/modules/favorite/standard-objects/favorite.workspace-entity.ts +++ b/packages/twenty-server/src/modules/favorite/standard-objects/favorite.workspace-entity.ts @@ -22,6 +22,8 @@ import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-obj import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity'; +import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; +import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @@ -128,6 +130,48 @@ export class FavoriteWorkspaceEntity extends BaseWorkspaceEntity { }) workflowId: string; + @WorkspaceRelation({ + standardId: FAVORITE_STANDARD_FIELD_IDS.workflowVersion, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Workflow', + description: 'Favorite workflow version', + icon: 'IconSettingsAutomation', + inverseSideTarget: () => WorkflowVersionWorkspaceEntity, + inverseSideFieldKey: 'favorites', + }) + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + @WorkspaceIsNullable() + workflowVersion: Relation | null; + + @WorkspaceJoinColumn('workflowVersion') + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + workflowVersionId: string; + + @WorkspaceRelation({ + standardId: FAVORITE_STANDARD_FIELD_IDS.workflowRun, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Workflow', + description: 'Favorite workflow run', + icon: 'IconSettingsAutomation', + inverseSideTarget: () => WorkflowRunWorkspaceEntity, + inverseSideFieldKey: 'favorites', + }) + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + @WorkspaceIsNullable() + workflowRun: Relation | null; + + @WorkspaceJoinColumn('workflowRun') + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + workflowRunId: string; + @WorkspaceRelation({ standardId: FAVORITE_STANDARD_FIELD_IDS.task, type: RelationMetadataType.MANY_TO_ONE, diff --git a/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts b/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts index d683c1c1f0..8d0eff81ac 100644 --- a/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts +++ b/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts @@ -1,5 +1,6 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; +import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; @@ -7,6 +8,7 @@ import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-en import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator'; import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; +import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator'; import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator'; import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; @@ -19,6 +21,9 @@ import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.work import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; +import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; +import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; +import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @WorkspaceEntity({ @@ -182,6 +187,69 @@ export class TimelineActivityWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceJoinColumn('task') taskId: string | null; + @WorkspaceRelation({ + standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflow, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Workflow', + description: 'Event workflow', + icon: 'IconTargetArrow', + inverseSideTarget: () => WorkflowWorkspaceEntity, + inverseSideFieldKey: 'timelineActivities', + }) + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + @WorkspaceIsNullable() + workflow: Relation | null; + + @WorkspaceJoinColumn('workflow') + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + workflowId: string | null; + + @WorkspaceRelation({ + standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflowVersion, + type: RelationMetadataType.MANY_TO_ONE, + label: 'WorkflowVersion', + description: 'Event workflow version', + icon: 'IconTargetArrow', + inverseSideTarget: () => WorkflowVersionWorkspaceEntity, + inverseSideFieldKey: 'timelineActivities', + }) + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + @WorkspaceIsNullable() + workflowVersion: Relation | null; + + @WorkspaceJoinColumn('workflowVersion') + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + workflowVersionId: string | null; + + @WorkspaceRelation({ + standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflowRun, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Workflow Run', + description: 'Event workflow run', + icon: 'IconTargetArrow', + inverseSideTarget: () => WorkflowRunWorkspaceEntity, + inverseSideFieldKey: 'timelineActivities', + }) + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + @WorkspaceIsNullable() + workflowRun: Relation | null; + + @WorkspaceJoinColumn('workflowRun') + @WorkspaceGate({ + featureFlag: FeatureFlagKey.IsWorkflowEnabled, + }) + workflowRunId: string | null; + @WorkspaceDynamicRelation({ type: RelationMetadataType.MANY_TO_ONE, argsFactory: (oppositeObjectMetadata) => ({ diff --git a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook.ts b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook.ts index 6d163d03c2..d59b593d21 100644 --- a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook.ts +++ b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook.ts @@ -1,9 +1,16 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; + import { WorkspaceQueryPostHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; +import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; import { WorkflowVersionStatus, WorkflowVersionWorkspaceEntity, @@ -17,10 +24,15 @@ import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-ob export class WorkflowCreateManyPostQueryHook implements WorkspaceQueryPostHookInstance { - constructor(private readonly twentyORMManager: TwentyORMManager) {} + constructor( + private readonly twentyORMManager: TwentyORMManager, + private readonly workspaceEventEmitter: WorkspaceEventEmitter, + @InjectRepository(ObjectMetadataEntity, 'metadata') + private readonly objectMetadataRepository: Repository, + ) {} async execute( - _authContext: AuthContext, + authContext: AuthContext, _objectName: string, payload: WorkflowWorkspaceEntity[], ): Promise { @@ -29,14 +41,39 @@ export class WorkflowCreateManyPostQueryHook 'workflowVersion', ); + const workflowVersionsToCreate = payload.map((workflow) => { + return workflowVersionRepository.create({ + workflowId: workflow.id, + status: WorkflowVersionStatus.DRAFT, + name: 'v1', + }); + }); + await Promise.all( - payload.map((workflow) => { - return workflowVersionRepository.insert({ - workflowId: workflow.id, - status: WorkflowVersionStatus.DRAFT, - name: 'v1', - }); + workflowVersionsToCreate.map((workflowVersion) => { + return workflowVersionRepository.save(workflowVersion); }), ); + + const objectMetadata = await this.objectMetadataRepository.findOneOrFail({ + where: { + nameSingular: 'workflowVersion', + }, + }); + + this.workspaceEventEmitter.emit( + `workflowVersion.created`, + workflowVersionsToCreate.map((workflowVersionToCreate) => { + return { + userId: authContext.user?.id, + recordId: workflowVersionToCreate.id, + objectMetadata, + properties: { + after: workflowVersionToCreate, + }, + } satisfies ObjectRecordCreateEvent; + }), + authContext.workspace.id, + ); } } diff --git a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook.ts b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook.ts index 78f7f98123..b9447a0619 100644 --- a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook.ts +++ b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook.ts @@ -1,9 +1,16 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; + import { WorkspaceQueryPostHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; +import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; import { WorkflowVersionStatus, WorkflowVersionWorkspaceEntity, @@ -17,10 +24,15 @@ import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-ob export class WorkflowCreateOnePostQueryHook implements WorkspaceQueryPostHookInstance { - constructor(private readonly twentyORMManager: TwentyORMManager) {} + constructor( + private readonly twentyORMManager: TwentyORMManager, + private readonly workspaceEventEmitter: WorkspaceEventEmitter, + @InjectRepository(ObjectMetadataEntity, 'metadata') + private readonly objectMetadataRepository: Repository, + ) {} async execute( - _authContext: AuthContext, + authContext: AuthContext, _objectName: string, payload: WorkflowWorkspaceEntity[], ): Promise { @@ -31,10 +43,33 @@ export class WorkflowCreateOnePostQueryHook 'workflowVersion', ); - await workflowVersionRepository.insert({ + const workflowVersionToCreate = await workflowVersionRepository.create({ workflowId: workflow.id, status: WorkflowVersionStatus.DRAFT, name: 'v1', }); + + await workflowVersionRepository.save(workflowVersionToCreate); + + const objectMetadata = await this.objectMetadataRepository.findOneOrFail({ + where: { + nameSingular: 'workflowVersion', + }, + }); + + this.workspaceEventEmitter.emit( + `workflowVersion.created`, + [ + { + userId: authContext.user?.id, + recordId: workflowVersionToCreate.id, + objectMetadata, + properties: { + after: workflowVersionToCreate, + }, + } satisfies ObjectRecordCreateEvent, + ], + authContext.workspace.id, + ); } } diff --git a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-query-hook.module.ts b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-query-hook.module.ts index bbcde310b9..870484d75b 100644 --- a/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-query-hook.module.ts +++ b/packages/twenty-server/src/modules/workflow/common/query-hooks/workflow-query-hook.module.ts @@ -1,7 +1,11 @@ import { Module } from '@nestjs/common'; +import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm'; + +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkflowCreateManyPostQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-many.post-query.hook'; import { WorkflowCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-many.pre-query.hook'; +import { WorkflowCreateOnePostQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.post-query.hook'; import { WorkflowCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.pre-query.hook'; import { WorkflowRunCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-many.pre-query.hook'; import { WorkflowRunCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-one.pre-query.hook'; @@ -17,6 +21,9 @@ import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/work import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-validation.workspace-service'; @Module({ + imports: [ + NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'), + ], providers: [ WorkflowCreateOnePreQueryHook, WorkflowCreateManyPreQueryHook, @@ -30,6 +37,7 @@ import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/ WorkflowVersionUpdateManyPreQueryHook, WorkflowVersionDeleteOnePreQueryHook, WorkflowVersionDeleteManyPreQueryHook, + WorkflowCreateOnePostQueryHook, WorkflowCreateManyPostQueryHook, WorkflowVersionValidationWorkspaceService, WorkflowCommonWorkspaceService, diff --git a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity.ts b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity.ts index 7994c56a34..402891c1d1 100644 --- a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity.ts @@ -34,7 +34,6 @@ export class WorkflowEventListenerWorkspaceEntity extends BaseWorkspaceEntity { type: FieldMetadataType.TEXT, label: 'Name', description: 'The workflow event listener name', - icon: 'IconPhoneCheck', }) eventName: string; diff --git a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts index 347536f57a..aa14605f74 100644 --- a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts @@ -6,7 +6,10 @@ import { FieldActorSource, } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { + RelationMetadataType, + RelationOnDeleteAction, +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; @@ -17,6 +20,8 @@ import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace- import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; import { WORKFLOW_RUN_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 { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; @@ -45,7 +50,7 @@ export type WorkflowRunOutput = { labelPlural: 'Workflow Runs', description: 'A workflow run', labelIdentifierStandardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.name, - icon: 'IconHistory', + icon: 'IconSettingsAutomation', }) @WorkspaceGate({ featureFlag: FeatureFlagKey.IsWorkflowEnabled, @@ -56,7 +61,7 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { type: FieldMetadataType.TEXT, label: 'Name', description: 'Name of the workflow run', - icon: 'IconText', + icon: 'IconSettingsAutomation', }) name: string; @@ -134,6 +139,7 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { type: FieldMetadataType.RAW_JSON, label: 'Output', description: 'Json object to provide output of the workflow run', + icon: 'IconText', }) @WorkspaceIsNullable() output: WorkflowRunOutput | null; @@ -177,4 +183,27 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceJoinColumn('workflow') workflowId: string; + + @WorkspaceRelation({ + standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.favorites, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Favorites', + description: 'Favorites linked to the workflow run', + icon: 'IconHeart', + inverseSideTarget: () => FavoriteWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsSystem() + favorites: Relation; + + @WorkspaceRelation({ + standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.timelineActivities, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Timeline Activities', + description: 'Timeline activities linked to the run', + inverseSideTarget: () => TimelineActivityWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsSystem() + timelineActivities: Relation; } diff --git a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts index 5ec2b4ade7..8e39c789ad 100644 --- a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow-version.workspace-entity.ts @@ -14,11 +14,10 @@ import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace- import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; -import { - WORKFLOW_RUN_STANDARD_FIELD_IDS, - WORKFLOW_VERSION_STANDARD_FIELD_IDS, -} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { WORKFLOW_VERSION_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 { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; import { WorkflowStep } from 'src/modules/workflow/workflow-executor/types/workflow-action.type'; @@ -64,7 +63,7 @@ const WorkflowVersionStatusOptions = [ labelSingular: 'Workflow Version', labelPlural: 'Workflow Versions', description: 'A workflow version', - icon: 'IconVersions', + icon: 'IconSettingsAutomation', labelIdentifierStandardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.name, }) @WorkspaceGate({ @@ -76,7 +75,7 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { type: FieldMetadataType.TEXT, label: 'Name', description: 'The workflow version name', - icon: 'IconVersions', + icon: 'IconSettingsAutomation', }) name: string; @@ -139,14 +138,37 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { workflowId: string; @WorkspaceRelation({ - standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.workflowVersion, + standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.runs, type: RelationMetadataType.ONE_TO_MANY, label: 'Runs', description: 'Workflow runs linked to the version.', - icon: 'IconVersions', + icon: 'IconRun', inverseSideTarget: () => WorkflowRunWorkspaceEntity, onDelete: RelationOnDeleteAction.SET_NULL, }) @WorkspaceIsNullable() runs: Relation; + + @WorkspaceRelation({ + standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.favorites, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Favorites', + description: 'Favorites linked to the workflow version', + icon: 'IconHeart', + inverseSideTarget: () => FavoriteWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsSystem() + favorites: Relation; + + @WorkspaceRelation({ + standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.timelineActivities, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Timeline Activities', + description: 'Timeline activities linked to the version', + inverseSideTarget: () => TimelineActivityWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsSystem() + timelineActivities: Relation; } diff --git a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts index 0a59d2bc83..0ff94c9340 100644 --- a/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workflow/common/standard-objects/workflow.workspace-entity.ts @@ -16,6 +16,7 @@ import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-re import { WORKFLOW_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 { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity'; import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; @@ -111,7 +112,6 @@ export class WorkflowWorkspaceEntity extends BaseWorkspaceEntity { inverseSideTarget: () => WorkflowVersionWorkspaceEntity, onDelete: RelationOnDeleteAction.CASCADE, }) - @WorkspaceIsNullable() versions: Relation; @WorkspaceRelation({ @@ -119,34 +119,43 @@ export class WorkflowWorkspaceEntity extends BaseWorkspaceEntity { type: RelationMetadataType.ONE_TO_MANY, label: 'Runs', description: 'Workflow runs linked to the workflow.', - icon: 'IconVersions', + icon: 'IconRun', inverseSideTarget: () => WorkflowRunWorkspaceEntity, onDelete: RelationOnDeleteAction.CASCADE, }) - @WorkspaceIsNullable() - runs: Relation; + runs: Relation; @WorkspaceRelation({ standardId: WORKFLOW_STANDARD_FIELD_IDS.eventListeners, type: RelationMetadataType.ONE_TO_MANY, label: 'Event Listeners', description: 'Workflow event listeners linked to the workflow.', - icon: 'IconVersions', inverseSideTarget: () => WorkflowEventListenerWorkspaceEntity, onDelete: RelationOnDeleteAction.CASCADE, }) - @WorkspaceIsNullable() + @WorkspaceIsSystem() eventListeners: Relation; @WorkspaceRelation({ standardId: WORKFLOW_STANDARD_FIELD_IDS.favorites, type: RelationMetadataType.ONE_TO_MANY, label: 'Favorites', - description: 'Favorites linked to the contact', + description: 'Favorites linked to the workflow', icon: 'IconHeart', inverseSideTarget: () => FavoriteWorkspaceEntity, onDelete: RelationOnDeleteAction.CASCADE, }) @WorkspaceIsSystem() favorites: Relation; + + @WorkspaceRelation({ + standardId: WORKFLOW_STANDARD_FIELD_IDS.timelineActivities, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Timeline Activities', + description: 'Timeline activities linked to the workflow', + inverseSideTarget: () => TimelineActivityWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsSystem() + timelineActivities: Relation; }