feat(editor): Add ability to extract sub-workflows to canvas context menu (#15538)

This commit is contained in:
Charlie Kolb
2025-06-02 12:17:27 +02:00
committed by GitHub
parent 096806af15
commit 5985df6e51
23 changed files with 2070 additions and 373 deletions

View File

@@ -76,7 +76,13 @@ import {
EVALUATION_TRIGGER_NODE_TYPE,
EVALUATION_NODE_TYPE,
} from 'n8n-workflow';
import type { NodeConnectionType, IDataObject, ExecutionSummary, IConnection } from 'n8n-workflow';
import type {
NodeConnectionType,
IDataObject,
ExecutionSummary,
IConnection,
INodeParameters,
} from 'n8n-workflow';
import { useToast } from '@/composables/useToast';
import { useSettingsStore } from '@/stores/settings.store';
import { useCredentialsStore } from '@/stores/credentials.store';
@@ -123,6 +129,7 @@ import { useWorkflowSaving } from '@/composables/useWorkflowSaving';
import { useBuilderStore } from '@/stores/builder.store';
import { useFoldersStore } from '@/stores/folders.store';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import { useWorkflowExtraction } from '@/composables/useWorkflowExtraction';
import { useAgentRequestStore } from '@n8n/stores/useAgentRequestStore';
import { needsAgentInput } from '@/utils/nodes/nodeTransforms';
import { useLogsStore } from '@/stores/logs.store';
@@ -195,6 +202,7 @@ const {
revertUpdateNodePosition,
renameNode,
revertRenameNode,
revertReplaceNodeParameters,
setNodeActive,
setNodeSelected,
toggleNodesDisabled,
@@ -230,6 +238,7 @@ const {
lastClickPosition,
startChat,
} = useCanvasOperations({ router });
const { extractWorkflow } = useWorkflowExtraction();
const { applyExecutionData } = useExecutionDebugging();
useClipboard({ onPaste: onClipboardPaste });
@@ -635,6 +644,10 @@ function onTidyUp(event: CanvasLayoutEvent) {
tidyUp(event);
}
function onExtractWorkflow(nodeIds: string[]) {
void extractWorkflow(nodeIds);
}
function onUpdateNodesPosition(events: CanvasNodeMoveEvent[]) {
updateNodesPosition(events, { trackHistory: true });
}
@@ -891,6 +904,18 @@ async function onRevertRenameNode({
await revertRenameNode(currentName, newName);
}
async function onRevertReplaceNodeParameters({
nodeId,
currentProperties,
newProperties,
}: {
nodeId: string;
currentProperties: INodeParameters;
newProperties: INodeParameters;
}) {
await revertReplaceNodeParameters(nodeId, currentProperties, newProperties);
}
function onUpdateNodeParameters(id: string, parameters: Record<string, unknown>) {
setNodeParameters(id, parameters);
}
@@ -1400,6 +1425,7 @@ function addUndoRedoEventBindings() {
historyBus.on('revertAddConnection', onRevertCreateConnection);
historyBus.on('revertRemoveConnection', onRevertDeleteConnection);
historyBus.on('revertRenameNode', onRevertRenameNode);
historyBus.on('revertReplaceNodeParameters', onRevertReplaceNodeParameters);
historyBus.on('enableNodeToggle', onRevertToggleNodeDisabled);
}
@@ -1410,6 +1436,7 @@ function removeUndoRedoEventBindings() {
historyBus.off('revertAddConnection', onRevertCreateConnection);
historyBus.off('revertRemoveConnection', onRevertDeleteConnection);
historyBus.off('revertRenameNode', onRevertRenameNode);
historyBus.off('revertReplaceNodeParameters', onRevertReplaceNodeParameters);
historyBus.off('enableNodeToggle', onRevertToggleNodeDisabled);
}
@@ -1977,6 +2004,7 @@ onBeforeUnmount(() => {
@selection:end="onSelectionEnd"
@drag-and-drop="onDragAndDrop"
@tidy-up="onTidyUp"
@extract-workflow="onExtractWorkflow"
@start-chat="startChat()"
>
<Suspense>