From 062fbe90ea5fd1be36f29a6d45ce36d13efe4905 Mon Sep 17 00:00:00 2001 From: Willy Douhard Date: Mon, 6 Oct 2025 13:51:46 +0200 Subject: [PATCH] Add 'Add a node' button to command menu for workflow node insertion (#14805) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related issue: https://github.com/twentyhq/core-team-issues/issues/1585 ## Summary Added a new "Add a node" button to the command menu that enables users to insert workflow nodes through the command interface. This enhancement improves the workflow creation experience by providing an additional, accessible way to add nodes to workflows. --------- Co-authored-by: Félix Malfait --- .../constants/WorkflowActionsConfig.tsx | 63 ++++++++++++------- .../AddNodeWorkflowSingleRecordAction.tsx | 21 +++++++ .../types/WorkflowSingleRecordActionsKeys.ts | 1 + 3 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/AddNodeWorkflowSingleRecordAction.tsx diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx index 4660a12823..20a2db8841 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx @@ -4,6 +4,7 @@ import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-action import { NoSelectionWorkflowRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/workflow-actions/types/NoSelectionWorkflowRecordActionKeys'; import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey'; import { ActivateWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/components/ActivateWorkflowSingleRecordAction'; +import { AddNodeWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/components/AddNodeWorkflowSingleRecordAction'; import { DeactivateWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/components/DeactivateWorkflowSingleRecordAction'; import { DiscardDraftWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/components/DiscardDraftWorkflowSingleRecordAction'; import { SeeActiveVersionWorkflowSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/workflow-actions/components/SeeActiveVersionWorkflowSingleRecordAction'; @@ -29,6 +30,7 @@ import { IconNoteOff, IconPlayerPause, IconPlayerPlay, + IconPlus, IconPower, IconVersions, } from 'twenty-ui/display'; @@ -192,6 +194,21 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({ ], component: , }, + [WorkflowSingleRecordActionKeys.ADD_NODE]: { + key: WorkflowSingleRecordActionKeys.ADD_NODE, + label: msg`Add a node`, + shortLabel: msg`Add a node`, + isPinned: false, + position: 8, + Icon: IconPlus, + type: ActionType.Standard, + scope: ActionScope.RecordSelection, + shouldBeRegistered: ({ selectedRecord, workflowWithCurrentVersion }) => + areWorkflowTriggerAndStepsDefined(workflowWithCurrentVersion) && + !isDefined(selectedRecord?.deletedAt), + availableOn: [ActionViewType.SHOW_PAGE], + component: , + }, [NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS]: { type: ActionType.Navigation, scope: ActionScope.Global, @@ -243,82 +260,82 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({ label: msg`Create new workflow`, }, [SingleRecordActionKeys.ADD_TO_FAVORITES]: { - position: 8, - }, - [SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: { position: 9, }, - [SingleRecordActionKeys.DELETE]: { + [SingleRecordActionKeys.REMOVE_FROM_FAVORITES]: { position: 10, + }, + [SingleRecordActionKeys.DELETE]: { + position: 11, label: msg`Delete workflow`, }, [MultipleRecordsActionKeys.DELETE]: { - position: 11, + position: 12, label: msg`Delete workflows`, }, [SingleRecordActionKeys.DESTROY]: { - position: 12, + position: 13, label: msg`Permanently destroy workflow`, }, [SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: { - position: 13, + position: 14, label: msg`Export workflow`, shouldBeRegistered: ({ selectedRecord }) => !isDefined(selectedRecord?.deletedAt), }, [SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: { - position: 14, + position: 15, label: msg`Export workflow`, }, [MultipleRecordsActionKeys.EXPORT]: { - position: 15, + position: 16, label: msg`Export workflows`, }, [NoSelectionRecordActionKeys.EXPORT_VIEW]: { - position: 15, + position: 16, label: msg`Export view`, }, [MultipleRecordsActionKeys.DESTROY]: { - position: 16, + position: 17, label: msg`Permanently destroy workflows`, }, [SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD]: { - position: 17, + position: 18, label: msg`Navigate to previous workflow`, }, [SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD]: { - position: 18, + position: 19, label: msg`Navigate to next workflow`, }, [NoSelectionRecordActionKeys.SEE_DELETED_RECORDS]: { - position: 19, + position: 20, label: msg`See deleted workflows`, }, [NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS]: { - position: 20, + position: 21, label: msg`Hide deleted workflows`, }, [NoSelectionRecordActionKeys.IMPORT_RECORDS]: { - position: 21, + position: 22, label: msg`Import workflows`, }, [NoSelectionRecordActionKeys.GO_TO_PEOPLE]: { - position: 22, - }, - [NoSelectionRecordActionKeys.GO_TO_COMPANIES]: { position: 23, }, - [NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: { + [NoSelectionRecordActionKeys.GO_TO_COMPANIES]: { position: 24, }, - [NoSelectionRecordActionKeys.GO_TO_SETTINGS]: { + [NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES]: { position: 25, }, - [NoSelectionRecordActionKeys.GO_TO_TASKS]: { + [NoSelectionRecordActionKeys.GO_TO_SETTINGS]: { position: 26, }, - [NoSelectionRecordActionKeys.GO_TO_NOTES]: { + [NoSelectionRecordActionKeys.GO_TO_TASKS]: { position: 27, }, + [NoSelectionRecordActionKeys.GO_TO_NOTES]: { + position: 28, + }, }, }); diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/AddNodeWorkflowSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/AddNodeWorkflowSingleRecordAction.tsx new file mode 100644 index 0000000000..df359e37f4 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/AddNodeWorkflowSingleRecordAction.tsx @@ -0,0 +1,21 @@ +import { Action } from '@/action-menu/actions/components/Action'; +import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow'; +import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu'; +import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; +import { isDefined } from 'twenty-shared/utils'; + +export const AddNodeWorkflowSingleRecordAction = () => { + const recordId = useSelectedRecordIdOrThrow(); + const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(recordId); + const { openWorkflowCreateStepInCommandMenu } = useWorkflowCommandMenu(); + + const onClick = () => { + if (!isDefined(workflowWithCurrentVersion)) { + return; + } + + openWorkflowCreateStepInCommandMenu(workflowWithCurrentVersion.id); + }; + + return ; +}; diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys.ts index 2464985343..25863b2e24 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys.ts +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/types/WorkflowSingleRecordActionsKeys.ts @@ -6,4 +6,5 @@ export enum WorkflowSingleRecordActionKeys { SEE_RUNS = 'see-runs-workflow-single-record', SEE_VERSIONS = 'see-versions-workflow-single-record', TEST = 'test-workflow-single-record', + ADD_NODE = 'add-node-workflow-single-record', }