Allow to stop running workflow (#15270)

https://github.com/user-attachments/assets/599154e4-8743-471b-b05a-721b635bcf4e

On stoppage:
- if no running steps, mark pending as failed and end the workflow
- if running steps, set as stopping and exit. Going to the next step, as
the workflow is not running anymore, it will naturally stop
This commit is contained in:
Thomas Trompette
2025-10-23 13:01:15 +00:00
committed by GitHub
parent 1cf442966d
commit 4effa5351c
23 changed files with 532 additions and 70 deletions
@@ -18,7 +18,10 @@ export class WorkflowRunUpdateOnePreQueryHook
_objectName: string,
payload: UpdateOneResolverArgs<WorkflowRunWorkspaceEntity>,
): Promise<UpdateOneResolverArgs<WorkflowRunWorkspaceEntity>> {
if (Object.keys(payload.data).length === 1 && payload.data.name) {
const allowedFields = ['name'];
const payloadKeys = Object.keys(payload.data);
if (payloadKeys.every((key) => allowedFields.includes(key))) {
return payload;
}
@@ -1,3 +1,5 @@
import { registerEnumType } from '@nestjs/graphql';
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared/types';
import { type WorkflowRunStepInfos } from 'twenty-shared/workflow';
@@ -40,8 +42,15 @@ export enum WorkflowRunStatus {
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
ENQUEUED = 'ENQUEUED',
STOPPING = 'STOPPING',
STOPPED = 'STOPPED',
}
registerEnumType(WorkflowRunStatus, {
name: 'WorkflowRunStatusEnum',
description: 'Status of the workflow run',
});
export type StepOutput = {
id: string;
output: WorkflowActionOutput;
@@ -159,6 +168,18 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity {
position: 4,
color: 'blue',
},
{
value: WorkflowRunStatus.STOPPING,
label: 'Stopping',
position: 5,
color: 'orange',
},
{
value: WorkflowRunStatus.STOPPED,
label: 'Stopped',
position: 6,
color: 'gray',
},
],
defaultValue: "'NOT_STARTED'",
})
@@ -0,0 +1,15 @@
import { StepStatus, type WorkflowRunStepInfos } from 'twenty-shared/workflow';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
export const workflowHasRunningSteps = ({
stepInfos,
steps,
}: {
stepInfos: WorkflowRunStepInfos;
steps: WorkflowAction[];
}) => {
return steps.some(
(step) => stepInfos[step.id]?.status === StepStatus.RUNNING,
);
};