From 84b348978a10df682c5cde74a6e6d679efb19d49 Mon Sep 17 00:00:00 2001 From: Mutasem Date: Thu, 4 Nov 2021 16:32:24 +0100 Subject: [PATCH] refactor node component --- packages/editor-ui/src/Interface.ts | 6 - packages/editor-ui/src/components/Node.vue | 23 ++- .../src/components/mixins/nodeBase.ts | 156 ++++++++---------- 3 files changed, 92 insertions(+), 93 deletions(-) diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index d4beda47f7..88bf34e9f0 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -104,12 +104,6 @@ export interface IEndpointOptions { enabled?: boolean; } -export interface IConnectionsUi { - [key: string]: { - [key: string]: IEndpointOptions; - }; -} - export interface IUpdateInformation { name: string; key: string; diff --git a/packages/editor-ui/src/components/Node.vue b/packages/editor-ui/src/components/Node.vue index 5a64233b02..ee66a92e38 100644 --- a/packages/editor-ui/src/components/Node.vue +++ b/packages/editor-ui/src/components/Node.vue @@ -76,7 +76,7 @@ import mixins from 'vue-typed-mixins'; import { get } from 'lodash'; import { getStyleTokenValue } from './helpers'; -import { INodeUi } from '@/Interface'; +import { INodeUi, XYPosition } from '@/Interface'; export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).extend({ name: 'Node', @@ -87,6 +87,12 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext nodeRunData(): ITaskData[] { return this.$store.getters.getWorkflowResultDataByNodeName(this.data.name); }, + hasIssues (): boolean { + if (this.data.issues !== undefined && Object.keys(this.data.issues).length) { + return true; + } + return false; + }, workflowDataItems (): number { const workflowResultDataNode = this.nodeRunData; if (workflowResultDataNode === null) { @@ -146,6 +152,21 @@ export default mixins(externalHooks, nodeBase, nodeHelpers, workflowHelpers).ext return 'play'; } }, + position (): XYPosition { + const node = this.$store.getters.nodesByName[this.name] as INodeUi; // position responsive to store changes + + return node.position; + }, + nodePosition (): object { + const returnStyles: { + [key: string]: string; + } = { + left: this.position[0] + 'px', + top: this.position[1] + 'px', + }; + + return returnStyles; + }, waiting (): string | undefined { const workflowExecution = this.$store.getters.getWorkflowExecution; diff --git a/packages/editor-ui/src/components/mixins/nodeBase.ts b/packages/editor-ui/src/components/mixins/nodeBase.ts index 49897cbc74..ba6dba9885 100644 --- a/packages/editor-ui/src/components/mixins/nodeBase.ts +++ b/packages/editor-ui/src/components/mixins/nodeBase.ts @@ -1,4 +1,4 @@ -import { IConnectionsUi, IEndpointOptions, INodeUi, XYPosition } from '@/Interface'; +import { IEndpointOptions, INodeUi, XYPosition } from '@/Interface'; import mixins from 'vue-typed-mixins'; @@ -9,6 +9,10 @@ import { getStyleTokenValue } from '../helpers'; import * as CanvasHelpers from '@/views/canvasHelpers'; import { Endpoint } from 'jsplumb'; +import { + INodeTypeDescription, +} from 'n8n-workflow'; + const anchorPositions: { [key: string]: { [key: number]: string[] | number[][]; @@ -70,33 +74,12 @@ export const nodeBase = mixins( data (): INodeUi { return this.$store.getters.getNodeByName(this.name); }, - hasIssues (): boolean { - if (this.data.issues !== undefined && Object.keys(this.data.issues).length) { - return true; - } - return false; - }, - nodeName (): string { + nodeId (): string { return NODE_NAME_PREFIX + this.nodeIndex; }, nodeIndex (): string { return this.$store.getters.getNodeIndex(this.data.name).toString(); }, - position (): XYPosition { - const node = this.$store.getters.nodesByName[this.name] as INodeUi; // position responsive to store changes - - return node.position; - }, - nodePosition (): object { - const returnStyles: { - [key: string]: string; - } = { - left: this.position[0] + 'px', - top: this.position[1] + 'px', - }; - - return returnStyles; - }, }, props: [ 'name', @@ -107,67 +90,35 @@ export const nodeBase = mixins( 'hideActions', ], methods: { - __addNode (node: INodeUi) { - // TODO: Later move the node-connection definitions to a special file - - let nodeTypeData = this.$store.getters.nodeType(node.type); - - const nodeConnectors: IConnectionsUi = { - main: { - input: { - uuid: '-input', - maxConnections: -1, - endpoint: 'Rectangle', - endpointStyle: { - width: 8, - height: nodeTypeData && nodeTypeData.outputs.length > 2 ? 18 : 20, - fill: getStyleTokenValue('--color-foreground-xdark'), - stroke: getStyleTokenValue('--color-foreground-xdark'), - lineWidth: 0, - }, - endpointHoverStyle: { - width: 8, - height: nodeTypeData && nodeTypeData.outputs.length > 2 ? 18 : 20, - fill: getStyleTokenValue('--color-primary'), - stroke: getStyleTokenValue('--color-primary'), - lineWidth: 0, - }, - dragAllowedWhenFull: true, - }, - output: { - uuid: '-output', - maxConnections: -1, - endpoint: 'Dot', - endpointStyle: { - radius: nodeTypeData && nodeTypeData.outputs.length > 2 ? 7 : 9, - fill: getStyleTokenValue('--color-foreground-xdark'), - outlineStroke: 'none', - }, - endpointHoverStyle: { - radius: nodeTypeData && nodeTypeData.outputs.length > 2 ? 7 : 9, - fill: getStyleTokenValue('--color-primary'), - outlineStroke: 'none', - }, - dragAllowedWhenFull: true, - }, - }, - }; - - if (!nodeTypeData) { - // If node type is not know use by default the base.noOp data to display it - nodeTypeData = this.$store.getters.nodeType(NO_OP_NODE_TYPE); - } - + __addInputEndpoints (node: INodeUi, nodeTypeData: INodeTypeDescription) { // Add Inputs - let index, inputData, anchorPosition; + let index, anchorPosition; let newEndpointData: IEndpointOptions; - let indexData: { + const indexData: { [key: string]: number; } = {}; nodeTypeData.inputs.forEach((inputName: string, i: number) => { - // @ts-ignore - inputData = nodeConnectors[inputName].input; + const inputData = { + uuid: '-input', + maxConnections: -1, + endpoint: 'Rectangle', + endpointStyle: { + width: 8, + height: nodeTypeData && nodeTypeData.outputs.length > 2 ? 18 : 20, + fill: getStyleTokenValue('--color-foreground-xdark'), + stroke: getStyleTokenValue('--color-foreground-xdark'), + lineWidth: 0, + }, + endpointHoverStyle: { + width: 8, + height: nodeTypeData && nodeTypeData.outputs.length > 2 ? 18 : 20, + fill: getStyleTokenValue('--color-primary'), + stroke: getStyleTokenValue('--color-primary'), + lineWidth: 0, + }, + dragAllowedWhenFull: true, + }; // Increment the index for inputs with current name if (indexData.hasOwnProperty(inputName)) { @@ -216,7 +167,7 @@ export const nodeBase = mixins( ]; } - const endpoint: Endpoint = this.instance.addEndpoint(this.nodeName, newEndpointData); + const endpoint: Endpoint = this.instance.addEndpoint(this.nodeId, newEndpointData); endpoint.__meta = { nodeName: node.name, index: i, @@ -230,14 +181,34 @@ export const nodeBase = mixins( // if (index === 0 && inputName === 'main') { // // Make the first main-input the default one to connect to when connection gets dropped on node - // this.instance.makeTarget(this.nodeName, newEndpointData); + // this.instance.makeTarget(this.nodeId, newEndpointData); // } }); + }, + __addOutputEndpoints(node: INodeUi, nodeTypeData: INodeTypeDescription) { + let index, anchorPosition; + let newEndpointData: IEndpointOptions; + const indexData: { + [key: string]: number; + } = {}; - // Add Outputs - indexData = {}; nodeTypeData.outputs.forEach((inputName: string, i: number) => { - inputData = nodeConnectors[inputName].output; + const inputData = { + uuid: '-output', + maxConnections: -1, + endpoint: 'Dot', + endpointStyle: { + radius: nodeTypeData && nodeTypeData.outputs.length > 2 ? 7 : 9, + fill: getStyleTokenValue('--color-foreground-xdark'), + outlineStroke: 'none', + }, + endpointHoverStyle: { + radius: nodeTypeData && nodeTypeData.outputs.length > 2 ? 7 : 9, + fill: getStyleTokenValue('--color-primary'), + outlineStroke: 'none', + }, + dragAllowedWhenFull: true, + }; // Increment the index for outputs with current name if (indexData.hasOwnProperty(inputName)) { @@ -284,18 +255,19 @@ export const nodeBase = mixins( ]; } - const endpoint: Endpoint = this.instance.addEndpoint(this.nodeName, newEndpointData); + const endpoint: Endpoint = this.instance.addEndpoint(this.nodeId, newEndpointData); endpoint.__meta = { nodeName: node.name, index: i, }; }); - + }, + __makeInstanceDraggable(node: INodeUi) { // TODO: This caused problems with displaying old information // https://github.com/jsplumb/katavorio/wiki // https://jsplumb.github.io/jsplumb/home.html // Make nodes draggable - this.instance.draggable(this.nodeName, { + this.instance.draggable(this.nodeId, { grid: [20, 20], start: (params: { e: MouseEvent }) => { if (this.isReadOnly === true) { @@ -357,7 +329,19 @@ export const nodeBase = mixins( }, filter: '.node-description, .node-description .node-name, .node-description .node-subtitle', }); + }, + __addNode (node: INodeUi) { + // TODO: Later move the node-connection definitions to a special file + let nodeTypeData = this.$store.getters.nodeType(node.type); + if (!nodeTypeData) { + // If node type is not know use by default the base.noOp data to display it + nodeTypeData = this.$store.getters.nodeType(NO_OP_NODE_TYPE); + } + + this.__addInputEndpoints(node, nodeTypeData); + this.__addOutputEndpoints(node, nodeTypeData); + this.__makeInstanceDraggable(node); }, touchEnd(e: MouseEvent) { if (this.isTouchDevice) {