refactor(editor): Refactor workflowHelpers mixin to composable (no-changelog) (#8600)

This commit is contained in:
oleg
2024-02-12 10:45:05 +01:00
committed by GitHub
parent a6211c9a5d
commit 510bf8905d
47 changed files with 1487 additions and 1403 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div :class="$style['content']" ref="nodeViewRootRef">
<div ref="nodeViewRootRef" :class="$style['content']">
<div
id="node-view-root"
class="node-view-root do-not-select"
@@ -258,7 +258,6 @@ import { useUniqueNodeName } from '@/composables/useUniqueNodeName';
import { useI18n } from '@/composables/useI18n';
import { useMessage } from '@/composables/useMessage';
import { useToast } from '@/composables/useToast';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { workflowRun } from '@/mixins/workflowRun';
import NodeDetailsView from '@/components/NodeDetailsView.vue';
@@ -316,7 +315,7 @@ import type {
ToggleNodeCreatorOptions,
} from '@/Interface';
import type { Route, RawLocation } from 'vue-router';
import { type Route, type RawLocation, useRouter } from 'vue-router';
import { dataPinningEventBus, nodeViewEventBus } from '@/event-bus';
import { useCanvasStore } from '@/stores/canvas.store';
import { useCollaborationStore } from '@/stores/collaboration.store';
@@ -381,6 +380,7 @@ import { useDeviceSupport } from 'n8n-design-system';
import { useDebounce } from '@/composables/useDebounce';
import { useCanvasPanning } from '@/composables/useCanvasPanning';
import { tryToParseNumber } from '@/utils/typesUtils';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
interface AddNodeOptions {
position?: XYPosition;
@@ -412,7 +412,7 @@ export default defineComponent({
ContextMenu,
SetupWorkflowCredentialsButton,
},
mixins: [workflowHelpers, workflowRun],
mixins: [workflowRun],
async beforeRouteLeave(to, from, next) {
if (
getNodeViewTab(to) === MAIN_HEADER_TABS.EXECUTIONS ||
@@ -440,7 +440,7 @@ export default defineComponent({
if (confirmModal === MODAL_CONFIRM) {
// Make sure workflow id is empty when leaving the editor
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
const saved = await this.saveCurrentWorkflow({}, false);
const saved = await this.workflowHelpers.saveCurrentWorkflow({}, false);
if (saved) {
await this.settingsStore.fetchPromptsData();
}
@@ -477,6 +477,7 @@ export default defineComponent({
const nodeViewRootRef = ref(null);
const nodeViewRef = ref(null);
const onMouseMoveEnd = ref(null);
const router = useRouter();
const ndvStore = useNDVStore();
const externalHooks = useExternalHooks();
@@ -490,6 +491,7 @@ export default defineComponent({
const deviceSupport = useDeviceSupport();
const { callDebounced } = useDebounce();
const canvasPanning = useCanvasPanning(nodeViewRootRef, { onMouseMoveEnd });
const workflowHelpers = useWorkflowHelpers(router);
return {
locale,
@@ -504,6 +506,7 @@ export default defineComponent({
nodeViewRootRef,
nodeViewRef,
onMouseMoveEnd,
workflowHelpers,
callDebounced,
...useCanvasMouseSelect(),
...useGlobalLinkActions(),
@@ -1068,12 +1071,14 @@ export default defineComponent({
this.uiStore.openModal(WORKFLOW_LM_CHAT_MODAL_KEY);
},
async onRunWorkflow() {
void this.getWorkflowDataToSave().then((workflowData) => {
void this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
const telemetryPayload = {
workflow_id: this.workflowsStore.workflowId,
node_graph_string: JSON.stringify(
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes())
.nodeGraph,
TelemetryHelpers.generateNodesGraph(
workflowData as IWorkflowBase,
this.workflowHelpers.getNodeTypes(),
).nodeGraph,
),
};
this.$telemetry.track('User clicked execute workflow button', telemetryPayload);
@@ -1150,7 +1155,7 @@ export default defineComponent({
this.nodeHelpers.updateNodesExecutionIssues();
},
async onSaveKeyboardShortcut(e: KeyboardEvent) {
let saved = await this.saveCurrentWorkflow();
let saved = await this.workflowHelpers.saveCurrentWorkflow();
if (saved) {
await this.settingsStore.fetchPromptsData();
@@ -1636,7 +1641,7 @@ export default defineComponent({
return;
}
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
if (!workflow.connectionsByDestinationNode.hasOwnProperty(lastSelectedNode.name)) {
return;
@@ -1664,7 +1669,7 @@ export default defineComponent({
return;
}
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
if (!workflow.connectionsByDestinationNode.hasOwnProperty(lastSelectedNode.name)) {
return;
@@ -1793,9 +1798,13 @@ export default defineComponent({
this.deselectAllNodes();
// Get all upstream nodes and select them
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const checkNodes = this.getConnectedNodes('upstream', workflow, lastSelectedNode.name);
const checkNodes = this.workflowHelpers.getConnectedNodes(
'upstream',
workflow,
lastSelectedNode.name,
);
for (const nodeName of checkNodes) {
this.nodeSelectedByName(nodeName);
}
@@ -1812,9 +1821,13 @@ export default defineComponent({
this.deselectAllNodes();
// Get all downstream nodes and select them
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const checkNodes = this.getConnectedNodes('downstream', workflow, lastSelectedNode.name);
const checkNodes = this.workflowHelpers.getConnectedNodes(
'downstream',
workflow,
lastSelectedNode.name,
);
for (const nodeName of checkNodes) {
this.nodeSelectedByName(nodeName);
}
@@ -1826,9 +1839,13 @@ export default defineComponent({
pushDownstreamNodes(sourceNodeName: string, margin: number, recordHistory = false) {
const sourceNode = this.workflowsStore.nodesByName[sourceNodeName];
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const checkNodes = this.getConnectedNodes('downstream', workflow, sourceNodeName);
const checkNodes = this.workflowHelpers.getConnectedNodes(
'downstream',
workflow,
sourceNodeName,
);
for (const nodeName of checkNodes) {
const node = this.workflowsStore.nodesByName[nodeName];
const oldPosition = node.position;
@@ -1877,7 +1894,7 @@ export default defineComponent({
...data,
};
this.removeForeignCredentialsFromWorkflow(
this.workflowHelpers.removeForeignCredentialsFromWorkflow(
workflowToCopy,
this.credentialsStore.allCredentials,
);
@@ -1962,12 +1979,14 @@ export default defineComponent({
}
this.stopExecutionInProgress = false;
void this.getWorkflowDataToSave().then((workflowData) => {
void this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
const trackProps = {
workflow_id: this.workflowsStore.workflowId,
node_graph_string: JSON.stringify(
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes())
.nodeGraph,
TelemetryHelpers.generateNodesGraph(
workflowData as IWorkflowBase,
this.workflowHelpers.getNodeTypes(),
).nodeGraph,
),
};
@@ -2090,9 +2109,9 @@ export default defineComponent({
workflowData.nodes.forEach((node: INode) => {
//generate new webhookId if workflow already contains a node with the same webhookId
if (node.webhookId && UPDATE_WEBHOOK_ID_NODE_TYPES.includes(node.type)) {
const isDuplicate = Object.values(this.getCurrentWorkflow().nodes).some(
(n) => n.webhookId === node.webhookId,
);
const isDuplicate = Object.values(
this.workflowHelpers.getCurrentWorkflow().nodes,
).some((n) => n.webhookId === node.webhookId);
if (isDuplicate) {
node.webhookId = uuid();
}
@@ -2114,13 +2133,17 @@ export default defineComponent({
const currInstanceId = this.rootStore.instanceId;
const nodeGraph = JSON.stringify(
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes(), {
nodeIdMap,
sourceInstanceId:
workflowData.meta && workflowData.meta.instanceId !== currInstanceId
? workflowData.meta.instanceId
: '',
}).nodeGraph,
TelemetryHelpers.generateNodesGraph(
workflowData as IWorkflowBase,
this.workflowHelpers.getNodeTypes(),
{
nodeIdMap,
sourceInstanceId:
workflowData.meta && workflowData.meta.instanceId !== currInstanceId
? workflowData.meta.instanceId
: '',
},
).nodeGraph,
);
if (source === 'paste') {
this.$telemetry.track('User pasted nodes', {
@@ -2147,7 +2170,7 @@ export default defineComponent({
// Fix the node position as it could be totally offscreen
// and the pasted nodes would so not be directly visible to
// the user
this.updateNodePositions(
this.workflowHelpers.updateNodePositions(
workflowData,
NodeViewUtils.getNewNodePosition(this.nodes, this.lastClickPosition),
);
@@ -2387,7 +2410,7 @@ export default defineComponent({
if (
nodeTypeData.maxNodes !== undefined &&
this.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes
this.workflowHelpers.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes
) {
this.showMaxNodeTypeError(nodeTypeData);
return;
@@ -2428,7 +2451,7 @@ export default defineComponent({
this.canvasStore.newNodeInsertPosition = null;
} else {
let yOffset = 0;
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
if (lastSelectedConnection) {
const sourceNodeType = this.nodeTypesStore.getNodeType(
@@ -2487,8 +2510,8 @@ export default defineComponent({
const lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);
const lastSelectedInputs = NodeHelpers.getNodeInputs(
workflow,
lastSelectedNodeWorkflow!,
lastSelectedNodeType!,
lastSelectedNodeWorkflow,
lastSelectedNodeType,
);
const lastSelectedInputTypes = NodeHelpers.getConnectionTypes(lastSelectedInputs);
@@ -2512,7 +2535,7 @@ export default defineComponent({
const inputs = NodeHelpers.getNodeInputs(
workflow,
lastSelectedNode,
lastSelectedNodeType!,
lastSelectedNodeType,
);
const inputsTypes = NodeHelpers.getConnectionTypes(inputs);
@@ -2698,7 +2721,7 @@ export default defineComponent({
if (
lastSelectedEndpoint &&
this.checkNodeConnectionAllowed(
lastSelectedNode!,
lastSelectedNode,
newNodeData,
lastSelectedEndpoint.scope as NodeConnectionType,
)
@@ -2752,7 +2775,7 @@ export default defineComponent({
},
getNodeCreatorFilter(nodeName: string, outputType?: NodeConnectionType) {
let filter;
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const workflowNode = workflow.getNode(nodeName);
if (!workflowNode) return { nodes: [] };
@@ -2884,11 +2907,11 @@ export default defineComponent({
);
if (targetNodeType?.inputs?.length) {
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const workflowNode = workflow.getNode(targetNode.name);
let inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];
if (targetNodeType) {
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, targetNodeType);
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode, targetNodeType);
}
for (const input of inputs || []) {
@@ -3543,7 +3566,7 @@ export default defineComponent({
},
);
if (confirmModal === MODAL_CONFIRM) {
const saved = await this.saveCurrentWorkflow();
const saved = await this.workflowHelpers.saveCurrentWorkflow();
if (saved) await this.settingsStore.fetchPromptsData();
} else if (confirmModal === MODAL_CLOSE) {
return;
@@ -3869,13 +3892,13 @@ export default defineComponent({
// connect nodes before/after deleted node
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const workflowNode = workflow.getNode(node.name);
let inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];
let outputs: Array<ConnectionTypes | INodeOutputConfiguration> = [];
if (nodeType) {
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, nodeType);
outputs = NodeHelpers.getNodeOutputs(workflow, workflowNode!, nodeType);
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode, nodeType);
outputs = NodeHelpers.getNodeOutputs(workflow, workflowNode, nodeType);
}
if (outputs.length === 1 && inputs.length === 1) {
@@ -4000,7 +4023,7 @@ export default defineComponent({
this.historyStore.startRecordingUndo();
}
const activeNodeName = this.activeNode && this.activeNode.name;
const activeNodeName = this.activeNode?.name;
const isActive = activeNodeName === currentName;
if (isActive) {
this.renamingActive = true;
@@ -4009,7 +4032,7 @@ export default defineComponent({
newName = this.uniqueNodeName(newName);
// Rename the node and update the connections
const workflow = this.getCurrentWorkflow(true);
const workflow = this.workflowHelpers.getCurrentWorkflow(true);
workflow.renameNode(currentName, newName);
if (trackHistory) {
@@ -4249,7 +4272,7 @@ export default defineComponent({
// Get how many of the nodes of the types which have
// a max limit set already exist
const nodeTypesCount = this.getNodeTypesMaxCount();
const nodeTypesCount = this.workflowHelpers.getNodeTypesMaxCount();
let oldName: string;
let newName: string;
@@ -4334,7 +4357,7 @@ export default defineComponent({
// Create a workflow with the new nodes and connections that we can use
// the rename method
const tempWorkflow: Workflow = this.getWorkflow(createNodes, newConnections);
const tempWorkflow: Workflow = this.workflowHelpers.getWorkflow(createNodes, newConnections);
// Rename all the nodes of which the name changed
for (oldName in nodeNameTable) {
@@ -4398,7 +4421,7 @@ export default defineComponent({
const exportNodeNames: string[] = [];
for (const node of nodes) {
nodeData = this.getNodeDataToSave(node);
nodeData = this.workflowHelpers.getNodeDataToSave(node);
exportNodeNames.push(node.name);
data.nodes.push(nodeData);
@@ -4728,7 +4751,7 @@ export default defineComponent({
}
const lastAddedNode = this.nodes[this.nodes.length - 1];
const workflow = this.getCurrentWorkflow();
const workflow = this.workflowHelpers.getCurrentWorkflow();
const lastNodeInputs = workflow.getParentNodesByDepth(lastAddedNode.name, 1);
// If the last added node has multiple inputs, move them down
@@ -4748,7 +4771,7 @@ export default defineComponent({
},
async saveCurrentWorkflowExternal(callback: () => void) {
await this.saveCurrentWorkflow();
await this.workflowHelpers.saveCurrentWorkflow();
callback?.();
},
setSuspendRecordingDetachedConnections(suspend: boolean) {

View File

@@ -57,7 +57,6 @@ import TemplateDetails from '@/components/TemplateDetails.vue';
import TemplateList from '@/components/TemplateList.vue';
import TemplatesView from './TemplatesView.vue';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import type {
ITemplatesCollection,
ITemplatesCollectionFull,
@@ -80,7 +79,6 @@ export default defineComponent({
TemplateList,
TemplatesView,
},
mixins: [workflowHelpers],
setup() {
const externalHooks = useExternalHooks();

View File

@@ -64,7 +64,6 @@ import TemplatesView from './TemplatesView.vue';
import WorkflowPreview from '@/components/WorkflowPreview.vue';
import type { ITemplatesWorkflowFull } from '@/Interface';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { setPageTitle } from '@/utils/htmlUtils';
import { useTemplatesStore } from '@/stores/templates.store';
import { usePostHog } from '@/stores/posthog.store';
@@ -79,7 +78,6 @@ export default defineComponent({
TemplatesView,
WorkflowPreview,
},
mixins: [workflowHelpers],
setup() {
const externalHooks = useExternalHooks();