Update next step ids on step update (#11605)
When inserting a new step between step 1 et step 2, then step 1 should have the new step as next step id, add stop having step 2. When deleting a step, we link the parent and next steps together. It may change in the future
This commit is contained in:
@ -411,6 +411,10 @@ export type CreateServerlessFunctionInput = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type CreateWorkflowVersionStepInput = {
|
export type CreateWorkflowVersionStepInput = {
|
||||||
|
/** Next step ID */
|
||||||
|
nextStepId?: InputMaybe<Scalars['String']>;
|
||||||
|
/** Parent step ID */
|
||||||
|
parentStepId?: InputMaybe<Scalars['String']>;
|
||||||
/** New step type */
|
/** New step type */
|
||||||
stepType: Scalars['String'];
|
stepType: Scalars['String'];
|
||||||
/** Workflow version ID */
|
/** Workflow version ID */
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import {
|
|||||||
import { getWorkflowDiagramTriggerNode } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramTriggerNode';
|
import { getWorkflowDiagramTriggerNode } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramTriggerNode';
|
||||||
|
|
||||||
import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId';
|
import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId';
|
||||||
import { v4 } from 'uuid';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
export const generateWorkflowDiagram = ({
|
export const generateWorkflowDiagram = ({
|
||||||
trigger,
|
trigger,
|
||||||
|
|||||||
@ -38,6 +38,8 @@ export const useCreateStep = ({
|
|||||||
await createWorkflowVersionStep({
|
await createWorkflowVersionStep({
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
stepType: newStepType,
|
stepType: newStepType,
|
||||||
|
parentStepId: workflowCreateStepFromParentStepId,
|
||||||
|
nextStepId: undefined,
|
||||||
})
|
})
|
||||||
)?.data?.createWorkflowVersionStep;
|
)?.data?.createWorkflowVersionStep;
|
||||||
|
|
||||||
|
|||||||
@ -15,4 +15,16 @@ export class CreateWorkflowVersionStepInput {
|
|||||||
nullable: false,
|
nullable: false,
|
||||||
})
|
})
|
||||||
stepType: WorkflowActionType;
|
stepType: WorkflowActionType;
|
||||||
|
|
||||||
|
@Field(() => String, {
|
||||||
|
description: 'Parent step ID',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
parentStepId?: string;
|
||||||
|
|
||||||
|
@Field(() => String, {
|
||||||
|
description: 'Next step ID',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
nextStepId?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,12 +26,11 @@ export class WorkflowStepResolver {
|
|||||||
async createWorkflowVersionStep(
|
async createWorkflowVersionStep(
|
||||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
@Args('input')
|
@Args('input')
|
||||||
{ stepType, workflowVersionId }: CreateWorkflowVersionStepInput,
|
input: CreateWorkflowVersionStepInput,
|
||||||
): Promise<WorkflowActionDTO> {
|
): Promise<WorkflowActionDTO> {
|
||||||
return this.workflowVersionStepWorkspaceService.createWorkflowVersionStep({
|
return this.workflowVersionStepWorkspaceService.createWorkflowVersionStep({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
input,
|
||||||
stepType,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ export class WorkflowStepResolver {
|
|||||||
return this.workflowVersionStepWorkspaceService.deleteWorkflowVersionStep({
|
return this.workflowVersionStepWorkspaceService.deleteWorkflowVersionStep({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
stepId,
|
stepIdToDelete: stepId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,111 @@
|
|||||||
|
import { insertStep } from 'src/modules/workflow/workflow-builder/workflow-step/utils/insert-step';
|
||||||
|
import {
|
||||||
|
WorkflowAction,
|
||||||
|
WorkflowActionType,
|
||||||
|
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
|
describe('insertStep', () => {
|
||||||
|
const createMockAction = (
|
||||||
|
id: string,
|
||||||
|
nextStepIds?: string[],
|
||||||
|
): WorkflowAction => ({
|
||||||
|
id,
|
||||||
|
name: `Action ${id}`,
|
||||||
|
type: WorkflowActionType.CODE,
|
||||||
|
settings: {
|
||||||
|
input: {
|
||||||
|
serverlessFunctionId: 'test',
|
||||||
|
serverlessFunctionVersion: '1.0.0',
|
||||||
|
serverlessFunctionInput: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
errorHandlingOptions: {
|
||||||
|
retryOnFailure: { value: false },
|
||||||
|
continueOnFailure: { value: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
nextStepIds,
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert a step at the end of the array when no parent or next step is specified', () => {
|
||||||
|
const step1 = createMockAction('1');
|
||||||
|
const step2 = createMockAction('2');
|
||||||
|
const newStep = createMockAction('new');
|
||||||
|
|
||||||
|
const result = insertStep({
|
||||||
|
existingSteps: [step1, step2],
|
||||||
|
insertedStep: newStep,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([step1, step2, newStep]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update parent step nextStepIds when inserting a step between two steps', () => {
|
||||||
|
const step1 = createMockAction('1', ['2']);
|
||||||
|
const step2 = createMockAction('2');
|
||||||
|
const newStep = createMockAction('new');
|
||||||
|
|
||||||
|
const result = insertStep({
|
||||||
|
existingSteps: [step1, step2],
|
||||||
|
insertedStep: newStep,
|
||||||
|
parentStepId: '1',
|
||||||
|
nextStepId: '2',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ ...step1, nextStepIds: ['new'] },
|
||||||
|
step2,
|
||||||
|
{ ...newStep, nextStepIds: ['2'] },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle inserting a step at the beginning of the workflow', () => {
|
||||||
|
const step1 = createMockAction('1');
|
||||||
|
const newStep = createMockAction('new');
|
||||||
|
|
||||||
|
const result = insertStep({
|
||||||
|
existingSteps: [step1],
|
||||||
|
insertedStep: newStep,
|
||||||
|
parentStepId: undefined,
|
||||||
|
nextStepId: '1',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([step1, { ...newStep, nextStepIds: ['1'] }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle inserting a step at the end of the workflow', () => {
|
||||||
|
const step1 = createMockAction('1');
|
||||||
|
const newStep = createMockAction('new');
|
||||||
|
|
||||||
|
const result = insertStep({
|
||||||
|
existingSteps: [step1],
|
||||||
|
insertedStep: newStep,
|
||||||
|
parentStepId: '1',
|
||||||
|
nextStepId: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([{ ...step1, nextStepIds: ['new'] }, newStep]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle inserting a step between two steps with multiple nextStepIds', () => {
|
||||||
|
const step1 = createMockAction('1', ['2', '3']);
|
||||||
|
const step2 = createMockAction('2');
|
||||||
|
const step3 = createMockAction('3');
|
||||||
|
const newStep = createMockAction('new');
|
||||||
|
|
||||||
|
const result = insertStep({
|
||||||
|
existingSteps: [step1, step2, step3],
|
||||||
|
insertedStep: newStep,
|
||||||
|
parentStepId: '1',
|
||||||
|
nextStepId: '2',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ ...step1, nextStepIds: ['3', 'new'] },
|
||||||
|
step2,
|
||||||
|
step3,
|
||||||
|
{ ...newStep, nextStepIds: ['2'] },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
import { removeStep } from 'src/modules/workflow/workflow-builder/workflow-step/utils/remove-step';
|
||||||
|
import {
|
||||||
|
WorkflowAction,
|
||||||
|
WorkflowActionType,
|
||||||
|
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
|
describe('removeStep', () => {
|
||||||
|
const createMockAction = (
|
||||||
|
id: string,
|
||||||
|
nextStepIds?: string[],
|
||||||
|
): WorkflowAction => ({
|
||||||
|
id,
|
||||||
|
name: `Action ${id}`,
|
||||||
|
type: WorkflowActionType.CODE,
|
||||||
|
settings: {
|
||||||
|
input: {
|
||||||
|
serverlessFunctionId: 'test',
|
||||||
|
serverlessFunctionVersion: '1.0.0',
|
||||||
|
serverlessFunctionInput: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
errorHandlingOptions: {
|
||||||
|
retryOnFailure: { value: false },
|
||||||
|
continueOnFailure: { value: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
nextStepIds,
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove the specified step from the array', () => {
|
||||||
|
const step1 = createMockAction('1');
|
||||||
|
const step2 = createMockAction('2');
|
||||||
|
const step3 = createMockAction('3');
|
||||||
|
|
||||||
|
const result = removeStep({
|
||||||
|
existingSteps: [step1, step2, step3],
|
||||||
|
stepIdToDelete: '2',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([step1, step3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle removing a step that has no next steps', () => {
|
||||||
|
const step1 = createMockAction('1', ['2']);
|
||||||
|
const step2 = createMockAction('2');
|
||||||
|
const step3 = createMockAction('3');
|
||||||
|
|
||||||
|
const result = removeStep({
|
||||||
|
existingSteps: [step1, step2, step3],
|
||||||
|
stepIdToDelete: '2',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([{ ...step1, nextStepIds: [] }, step3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update nextStepIds of parent steps to include children of removed step', () => {
|
||||||
|
const step1 = createMockAction('1', ['2']);
|
||||||
|
const step2 = createMockAction('2', ['3']);
|
||||||
|
const step3 = createMockAction('3');
|
||||||
|
|
||||||
|
const result = removeStep({
|
||||||
|
existingSteps: [step1, step2, step3],
|
||||||
|
stepIdToDelete: '2',
|
||||||
|
stepToDeleteChildrenIds: ['3'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([{ ...step1, nextStepIds: ['3'] }, step3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle multiple parent steps pointing to the same step', () => {
|
||||||
|
const step1 = createMockAction('1', ['3']);
|
||||||
|
const step2 = createMockAction('2', ['3']);
|
||||||
|
const step3 = createMockAction('3', ['4']);
|
||||||
|
const step4 = createMockAction('4');
|
||||||
|
|
||||||
|
const result = removeStep({
|
||||||
|
existingSteps: [step1, step2, step3, step4],
|
||||||
|
stepIdToDelete: '3',
|
||||||
|
stepToDeleteChildrenIds: ['4'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ ...step1, nextStepIds: ['4'] },
|
||||||
|
{ ...step2, nextStepIds: ['4'] },
|
||||||
|
step4,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle removing a step with multiple children', () => {
|
||||||
|
const step1 = createMockAction('1', ['2']);
|
||||||
|
const step2 = createMockAction('2', ['3', '4']);
|
||||||
|
const step3 = createMockAction('3');
|
||||||
|
const step4 = createMockAction('4');
|
||||||
|
|
||||||
|
const result = removeStep({
|
||||||
|
existingSteps: [step1, step2, step3, step4],
|
||||||
|
stepIdToDelete: '2',
|
||||||
|
stepToDeleteChildrenIds: ['3', '4'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ ...step1, nextStepIds: ['3', '4'] },
|
||||||
|
step3,
|
||||||
|
step4,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
|
export const insertStep = ({
|
||||||
|
existingSteps,
|
||||||
|
insertedStep,
|
||||||
|
parentStepId,
|
||||||
|
nextStepId,
|
||||||
|
}: {
|
||||||
|
existingSteps: WorkflowAction[];
|
||||||
|
insertedStep: WorkflowAction;
|
||||||
|
parentStepId?: string;
|
||||||
|
nextStepId?: string;
|
||||||
|
}): WorkflowAction[] => {
|
||||||
|
const updatedExistingSteps = existingSteps.map((existingStep) => {
|
||||||
|
if (existingStep.id === parentStepId) {
|
||||||
|
return {
|
||||||
|
...existingStep,
|
||||||
|
nextStepIds: [
|
||||||
|
...new Set([
|
||||||
|
...(existingStep.nextStepIds?.filter((id) => id !== nextStepId) ||
|
||||||
|
[]),
|
||||||
|
insertedStep.id,
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingStep;
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
...updatedExistingSteps,
|
||||||
|
{
|
||||||
|
...insertedStep,
|
||||||
|
nextStepIds: nextStepId ? [nextStepId] : undefined,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
|
||||||
|
export const removeStep = ({
|
||||||
|
existingSteps,
|
||||||
|
stepIdToDelete,
|
||||||
|
stepToDeleteChildrenIds,
|
||||||
|
}: {
|
||||||
|
existingSteps: WorkflowAction[];
|
||||||
|
stepIdToDelete: string;
|
||||||
|
stepToDeleteChildrenIds?: string[];
|
||||||
|
}): WorkflowAction[] => {
|
||||||
|
return existingSteps
|
||||||
|
.filter((step) => step.id !== stepIdToDelete)
|
||||||
|
.map((step) => {
|
||||||
|
if (step.nextStepIds?.includes(stepIdToDelete)) {
|
||||||
|
return {
|
||||||
|
...step,
|
||||||
|
nextStepIds: [
|
||||||
|
...new Set([
|
||||||
|
...step.nextStepIds.filter((id) => id !== stepIdToDelete),
|
||||||
|
// We automatically link parent and child steps together
|
||||||
|
...(stepToDeleteChildrenIds || []),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return step;
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -7,6 +7,7 @@ import { Repository } from 'typeorm';
|
|||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
|
import { BASE_TYPESCRIPT_PROJECT_INPUT_SCHEMA } from 'src/engine/core-modules/serverless/drivers/constants/base-typescript-project-input-schema';
|
||||||
|
import { CreateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-step-input.dto';
|
||||||
import { WorkflowActionDTO } from 'src/engine/core-modules/workflow/dtos/workflow-step.dto';
|
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 { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
@ -18,6 +19,8 @@ import {
|
|||||||
import { StepOutput } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
import { StepOutput } 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 { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||||
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
|
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
|
||||||
|
import { insertStep } from 'src/modules/workflow/workflow-builder/workflow-step/utils/insert-step';
|
||||||
|
import { removeStep } from 'src/modules/workflow/workflow-builder/workflow-step/utils/remove-step';
|
||||||
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
|
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
|
||||||
import {
|
import {
|
||||||
WorkflowAction,
|
WorkflowAction,
|
||||||
@ -54,13 +57,13 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
|
|
||||||
async createWorkflowVersionStep({
|
async createWorkflowVersionStep({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
input,
|
||||||
stepType,
|
|
||||||
}: {
|
}: {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workflowVersionId: string;
|
input: CreateWorkflowVersionStepInput;
|
||||||
stepType: WorkflowActionType;
|
|
||||||
}): Promise<WorkflowActionDTO> {
|
}): Promise<WorkflowActionDTO> {
|
||||||
|
const { workflowVersionId, stepType, parentStepId, nextStepId } = input;
|
||||||
|
|
||||||
const newStep = await this.getStepDefaultDefinition({
|
const newStep = await this.getStepDefaultDefinition({
|
||||||
type: stepType,
|
type: stepType,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@ -87,8 +90,16 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingSteps = workflowVersion.steps || [];
|
||||||
|
const updatedSteps = insertStep({
|
||||||
|
existingSteps,
|
||||||
|
insertedStep: enrichedNewStep,
|
||||||
|
parentStepId,
|
||||||
|
nextStepId,
|
||||||
|
});
|
||||||
|
|
||||||
await workflowVersionRepository.update(workflowVersion.id, {
|
await workflowVersionRepository.update(workflowVersion.id, {
|
||||||
steps: [...(workflowVersion.steps || []), enrichedNewStep],
|
steps: updatedSteps,
|
||||||
});
|
});
|
||||||
|
|
||||||
return enrichedNewStep;
|
return enrichedNewStep;
|
||||||
@ -151,11 +162,11 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
async deleteWorkflowVersionStep({
|
async deleteWorkflowVersionStep({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
stepId,
|
stepIdToDelete,
|
||||||
}: {
|
}: {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workflowVersionId: string;
|
workflowVersionId: string;
|
||||||
stepId: string;
|
stepIdToDelete: string;
|
||||||
}): Promise<WorkflowActionDTO> {
|
}): Promise<WorkflowActionDTO> {
|
||||||
const workflowVersionRepository =
|
const workflowVersionRepository =
|
||||||
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||||
@ -182,9 +193,9 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const stepToDelete = workflowVersion.steps.filter(
|
const stepToDelete = workflowVersion.steps.find(
|
||||||
(step) => step.id === stepId,
|
(step) => step.id === stepIdToDelete,
|
||||||
)?.[0];
|
);
|
||||||
|
|
||||||
if (!isDefined(stepToDelete)) {
|
if (!isDefined(stepToDelete)) {
|
||||||
throw new WorkflowVersionStepException(
|
throw new WorkflowVersionStepException(
|
||||||
@ -194,9 +205,15 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const workflowVersionUpdates =
|
const workflowVersionUpdates =
|
||||||
stepId === TRIGGER_STEP_ID
|
stepIdToDelete === TRIGGER_STEP_ID
|
||||||
? { trigger: null }
|
? { trigger: null }
|
||||||
: { steps: workflowVersion.steps.filter((step) => step.id !== stepId) };
|
: {
|
||||||
|
steps: removeStep({
|
||||||
|
existingSteps: workflowVersion.steps,
|
||||||
|
stepIdToDelete,
|
||||||
|
stepToDeleteChildrenIds: stepToDelete.nextStepIds,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
await workflowVersionRepository.update(
|
await workflowVersionRepository.update(
|
||||||
workflowVersion.id,
|
workflowVersion.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user