mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-29 06:29:42 -08:00
refactor helpers
This commit is contained in:
parent
71b50aeaf6
commit
0015cb4f34
|
@ -681,3 +681,11 @@ export interface IZoomConfig {
|
||||||
scale: number;
|
scale: number;
|
||||||
offset: XYPosition;
|
offset: XYPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IBounds {
|
||||||
|
minX: number;
|
||||||
|
minY: number;
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { deviceSupportHelpers } from '@/components/mixins/deviceSupportHelpers';
|
||||||
import { nodeIndex } from '@/components/mixins/nodeIndex';
|
import { nodeIndex } from '@/components/mixins/nodeIndex';
|
||||||
import { NODE_NAME_PREFIX, NO_OP_NODE_TYPE } from '@/constants';
|
import { NODE_NAME_PREFIX, NO_OP_NODE_TYPE } from '@/constants';
|
||||||
import { getStyleTokenValue } from '../helpers';
|
import { getStyleTokenValue } from '../helpers';
|
||||||
import { OVERLAY_INPUT_NAME_LABEL } from '@/views/canvasHelpers';
|
import * as CanvasHelpers from '@/views/canvasHelpers';
|
||||||
|
|
||||||
export const nodeBase = mixins(
|
export const nodeBase = mixins(
|
||||||
deviceSupportHelpers,
|
deviceSupportHelpers,
|
||||||
|
@ -200,7 +200,7 @@ export const nodeBase = mixins(
|
||||||
newEndpointData.overlays = [
|
newEndpointData.overlays = [
|
||||||
['Label',
|
['Label',
|
||||||
{
|
{
|
||||||
id: OVERLAY_INPUT_NAME_LABEL,
|
id: CanvasHelpers.OVERLAY_INPUT_NAME_LABEL,
|
||||||
location: [-3, 0.5],
|
location: [-3, 0.5],
|
||||||
label: nodeTypeData.inputNames[index],
|
label: nodeTypeData.inputNames[index],
|
||||||
cssClass: 'node-input-endpoint-label',
|
cssClass: 'node-input-endpoint-label',
|
||||||
|
|
|
@ -110,7 +110,8 @@ export const showMessage = mixins(externalHooks).extend({
|
||||||
return errorMessage;
|
return errorMessage;
|
||||||
},
|
},
|
||||||
|
|
||||||
$showError(error: Error, title: string, message?: string) {
|
$showError(e: Error | unknown, title: string, message?: string) {
|
||||||
|
const error = e as Error;
|
||||||
const messageLine = message ? `${message}<br/>` : '';
|
const messageLine = message ? `${message}<br/>` : '';
|
||||||
this.$showMessage({
|
this.$showMessage({
|
||||||
title,
|
title,
|
||||||
|
|
|
@ -135,7 +135,7 @@ import NodeCreator from '@/components/NodeCreator/NodeCreator.vue';
|
||||||
import NodeSettings from '@/components/NodeSettings.vue';
|
import NodeSettings from '@/components/NodeSettings.vue';
|
||||||
import RunData from '@/components/RunData.vue';
|
import RunData from '@/components/RunData.vue';
|
||||||
|
|
||||||
import { OVERLAY_INPUT_NAME_LABEL, JSPLUMB_FLOWCHART_STUB, getLeftmostTopNode, getWorkflowCorners, scaleSmaller, scaleBigger, scaleReset, showOrHideMidpointArrow, getIcon, getNewNodePosition, hideOverlay, showOrHideItemsLabel, showOverlay, OVERLAY_ENDPOINT_ARROW_ID, OVERLAY_MIDPOINT_ARROW_ID, OVERLAY_DROP_NODE_ID, OVERLAY_RUN_ITEMS_ID, OVERLAY_CONNECTION_ACTIONS_ID, getConnectorLengths, getRelativePosition, getMousePosition } from './canvasHelpers';
|
import * as CanvasHelpers from './canvasHelpers';
|
||||||
|
|
||||||
import mixins from 'vue-typed-mixins';
|
import mixins from 'vue-typed-mixins';
|
||||||
import { v4 as uuidv4} from 'uuid';
|
import { v4 as uuidv4} from 'uuid';
|
||||||
|
@ -158,7 +158,6 @@ import {
|
||||||
import {
|
import {
|
||||||
ICredentialsResponse,
|
ICredentialsResponse,
|
||||||
IExecutionResponse,
|
IExecutionResponse,
|
||||||
IN8nUISettings,
|
|
||||||
IWorkflowDb,
|
IWorkflowDb,
|
||||||
IWorkflowData,
|
IWorkflowData,
|
||||||
INodeUi,
|
INodeUi,
|
||||||
|
@ -174,113 +173,6 @@ import { mapGetters } from 'vuex';
|
||||||
import { getStyleTokenValue } from '@/components/helpers';
|
import { getStyleTokenValue } from '@/components/helpers';
|
||||||
import '../plugins/N8nFlowchartType';
|
import '../plugins/N8nFlowchartType';
|
||||||
|
|
||||||
const NODE_SIZE = 100;
|
|
||||||
const DEFAULT_START_POSITION_X = 240;
|
|
||||||
const DEFAULT_START_POSITION_Y = 300;
|
|
||||||
const HEADER_HEIGHT = 65;
|
|
||||||
const SIDEBAR_WIDTH = 65;
|
|
||||||
const MAX_X_TO_PUSH_DOWNSTREAM_NODES = 300;
|
|
||||||
|
|
||||||
const DEFAULT_START_NODE = {
|
|
||||||
name: 'Start',
|
|
||||||
type: START_NODE_TYPE,
|
|
||||||
typeVersion: 1,
|
|
||||||
position: [
|
|
||||||
DEFAULT_START_POSITION_X,
|
|
||||||
DEFAULT_START_POSITION_Y,
|
|
||||||
] as XYPosition,
|
|
||||||
parameters: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const _OUTLINE_STROKE_COLOR = 'transparent';
|
|
||||||
const _OUTLINE_STROKE_WIDTH = 12;
|
|
||||||
const _ALWAYS_RESPECT_STUB = true;
|
|
||||||
const _PUSH_NODES_LENGTH = 200;
|
|
||||||
|
|
||||||
const CONNECTOR_PAINT_STYLE_DEFAULT: PaintStyle = {
|
|
||||||
stroke: getStyleTokenValue('--color-foreground-dark'),
|
|
||||||
strokeWidth: 2,
|
|
||||||
outlineWidth: _OUTLINE_STROKE_WIDTH,
|
|
||||||
outlineStroke: _OUTLINE_STROKE_COLOR,
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONNECTOR_PAINT_STYLE_PRIMARY = {
|
|
||||||
...CONNECTOR_PAINT_STYLE_DEFAULT,
|
|
||||||
stroke: getStyleTokenValue('--color-primary'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONNECTOR_PAINT_STYLE_SUCCESS = {
|
|
||||||
...CONNECTOR_PAINT_STYLE_DEFAULT,
|
|
||||||
stroke: getStyleTokenValue('--color-success'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONNECTOR_TYPE_STRIGHT = ['Straight'];
|
|
||||||
|
|
||||||
const getFlowChartType = (connection: Connection) => {
|
|
||||||
const inputIndex = connection.__meta ? connection.__meta.targetOutputIndex : 0;
|
|
||||||
const outputIndex = connection.__meta ? connection.__meta.sourceOutputIndex : 0;
|
|
||||||
|
|
||||||
const outputEndpoint = connection.endpoints[0];
|
|
||||||
const outputOverlay = outputEndpoint.getOverlay('output-name-label');
|
|
||||||
let labelOffset = 0;
|
|
||||||
if (outputOverlay && outputOverlay.label && outputOverlay.label.length > 1) {
|
|
||||||
labelOffset = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ['N8nFlowchart', {
|
|
||||||
cornerRadius: 4,
|
|
||||||
stub: JSPLUMB_FLOWCHART_STUB + 10 * outputIndex + 10 * inputIndex + labelOffset,
|
|
||||||
gap: 5,
|
|
||||||
alwaysRespectStubs: _ALWAYS_RESPECT_STUB,
|
|
||||||
yOffset: NODE_SIZE,
|
|
||||||
loopbackMinimum: 140,
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONNECTOR_ARROW_OVERLAYS: OverlaySpec[] = [
|
|
||||||
[
|
|
||||||
'Arrow',
|
|
||||||
{
|
|
||||||
id: OVERLAY_ENDPOINT_ARROW_ID,
|
|
||||||
location: 1,
|
|
||||||
width: 12,
|
|
||||||
foldback: 1,
|
|
||||||
length: 10,
|
|
||||||
visible: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Arrow',
|
|
||||||
{
|
|
||||||
id: OVERLAY_MIDPOINT_ARROW_ID,
|
|
||||||
location: 0.5,
|
|
||||||
width: 12,
|
|
||||||
foldback: 1,
|
|
||||||
length: 10,
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
const CONNECTOR_DROP_NODE_OVERLAY: OverlaySpec[] = [
|
|
||||||
[
|
|
||||||
'Label',
|
|
||||||
{
|
|
||||||
id: OVERLAY_DROP_NODE_ID,
|
|
||||||
label: 'Drop connection<br />to create node',
|
|
||||||
cssClass: 'drop-add-node-label',
|
|
||||||
location: 0.5,
|
|
||||||
visible: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
const addOverlays = (connection: Connection, overlays: OverlaySpec[]) => {
|
|
||||||
overlays.forEach((overlay: OverlaySpec) => {
|
|
||||||
connection.addOverlay(overlay);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default mixins(
|
export default mixins(
|
||||||
copyPaste,
|
copyPaste,
|
||||||
externalHooks,
|
externalHooks,
|
||||||
|
@ -557,18 +449,18 @@ export default mixins(
|
||||||
const nodes = data.workflow.nodes;
|
const nodes = data.workflow.nodes;
|
||||||
const hasStartNode = !!nodes.find(node => node.type === START_NODE_TYPE);
|
const hasStartNode = !!nodes.find(node => node.type === START_NODE_TYPE);
|
||||||
|
|
||||||
const leftmostTop = getLeftmostTopNode(nodes);
|
const leftmostTop = CanvasHelpers.getLeftmostTopNode(nodes);
|
||||||
|
|
||||||
const diffX = DEFAULT_START_POSITION_X - leftmostTop.position[0];
|
const diffX = CanvasHelpers.DEFAULT_START_POSITION_X - leftmostTop.position[0];
|
||||||
const diffY = DEFAULT_START_POSITION_Y - leftmostTop.position[1];
|
const diffY = CanvasHelpers.DEFAULT_START_POSITION_Y - leftmostTop.position[1];
|
||||||
|
|
||||||
data.workflow.nodes.map((node) => {
|
data.workflow.nodes.map((node) => {
|
||||||
node.position[0] += diffX + (hasStartNode? 0 : NODE_SIZE * 2);
|
node.position[0] += diffX + (hasStartNode? 0 : CanvasHelpers.NODE_SIZE * 2);
|
||||||
node.position[1] += diffY;
|
node.position[1] += diffY;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!hasStartNode) {
|
if (!hasStartNode) {
|
||||||
data.workflow.nodes.push(DEFAULT_START_NODE);
|
data.workflow.nodes.push(CanvasHelpers.DEFAULT_START_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.blankRedirect = true;
|
this.blankRedirect = true;
|
||||||
|
@ -976,21 +868,21 @@ export default mixins(
|
||||||
},
|
},
|
||||||
|
|
||||||
resetZoom () {
|
resetZoom () {
|
||||||
const { scale, offset } = scaleReset({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
const { scale, offset } = CanvasHelpers.scaleReset({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
||||||
|
|
||||||
this.setZoomLevel(scale);
|
this.setZoomLevel(scale);
|
||||||
this.$store.commit('setNodeViewOffsetPosition', {newOffset: offset});
|
this.$store.commit('setNodeViewOffsetPosition', {newOffset: offset});
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomIn() {
|
zoomIn() {
|
||||||
const { scale, offset: [xOffset, yOffset] } = scaleBigger({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
const { scale, offset: [xOffset, yOffset] } = CanvasHelpers.scaleBigger({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
||||||
|
|
||||||
this.setZoomLevel(scale);
|
this.setZoomLevel(scale);
|
||||||
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomOut() {
|
zoomOut() {
|
||||||
const { scale, offset: [xOffset, yOffset] } = scaleSmaller({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
const { scale, offset: [xOffset, yOffset] } = CanvasHelpers.scaleSmaller({scale: this.nodeViewScale, offset: this.$store.getters.getNodeViewOffsetPosition});
|
||||||
|
|
||||||
this.setZoomLevel(scale);
|
this.setZoomLevel(scale);
|
||||||
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
||||||
|
@ -1021,24 +913,24 @@ export default mixins(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {minX, minY, maxX, maxY} = getWorkflowCorners(nodes);
|
const {minX, minY, maxX, maxY} = CanvasHelpers.getWorkflowCorners(nodes);
|
||||||
|
|
||||||
const PADDING = NODE_SIZE * 4;
|
const PADDING = CanvasHelpers.NODE_SIZE * 4;
|
||||||
|
|
||||||
const editorWidth = window.innerWidth;
|
const editorWidth = window.innerWidth;
|
||||||
const diffX = maxX - minX + SIDEBAR_WIDTH + PADDING;
|
const diffX = maxX - minX + CanvasHelpers.SIDEBAR_WIDTH + PADDING;
|
||||||
const scaleX = editorWidth / diffX;
|
const scaleX = editorWidth / diffX;
|
||||||
|
|
||||||
const editorHeight = window.innerHeight;
|
const editorHeight = window.innerHeight;
|
||||||
const diffY = maxY - minY + HEADER_HEIGHT + PADDING;
|
const diffY = maxY - minY + CanvasHelpers.HEADER_HEIGHT + PADDING;
|
||||||
const scaleY = editorHeight / diffY;
|
const scaleY = editorHeight / diffY;
|
||||||
|
|
||||||
const zoomLevel = Math.min(scaleX, scaleY, 1);
|
const zoomLevel = Math.min(scaleX, scaleY, 1);
|
||||||
let xOffset = (minX * -1) * zoomLevel + SIDEBAR_WIDTH; // find top right corner
|
let xOffset = (minX * -1) * zoomLevel + CanvasHelpers.SIDEBAR_WIDTH; // find top right corner
|
||||||
xOffset += (editorWidth - SIDEBAR_WIDTH - (maxX - minX + NODE_SIZE) * zoomLevel) / 2; // add padding to center workflow
|
xOffset += (editorWidth - CanvasHelpers.SIDEBAR_WIDTH - (maxX - minX + CanvasHelpers.NODE_SIZE) * zoomLevel) / 2; // add padding to center workflow
|
||||||
|
|
||||||
let yOffset = (minY * -1) * zoomLevel + HEADER_HEIGHT; // find top right corner
|
let yOffset = (minY * -1) * zoomLevel + CanvasHelpers.HEADER_HEIGHT; // find top right corner
|
||||||
yOffset += (editorHeight - HEADER_HEIGHT - (maxY - minY + NODE_SIZE * 2) * zoomLevel) / 2; // add padding to center workflow
|
yOffset += (editorHeight - CanvasHelpers.HEADER_HEIGHT - (maxY - minY + CanvasHelpers.NODE_SIZE * 2) * zoomLevel) / 2; // add padding to center workflow
|
||||||
|
|
||||||
this.setZoomLevel(zoomLevel);
|
this.setZoomLevel(zoomLevel);
|
||||||
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
this.$store.commit('setNodeViewOffsetPosition', {newOffset: [xOffset, yOffset]});
|
||||||
|
@ -1190,7 +1082,7 @@ export default mixins(
|
||||||
// Fix the node position as it could be totally offscreen
|
// Fix the node position as it could be totally offscreen
|
||||||
// and the pasted nodes would so not be directly visible to
|
// and the pasted nodes would so not be directly visible to
|
||||||
// the user
|
// the user
|
||||||
this.updateNodePositions(workflowData, getNewNodePosition(this.nodes, this.lastClickPosition));
|
this.updateNodePositions(workflowData, CanvasHelpers.getNewNodePosition(this.nodes, this.lastClickPosition));
|
||||||
|
|
||||||
const data = await this.addNodesToWorkflow(workflowData);
|
const data = await this.addNodesToWorkflow(workflowData);
|
||||||
|
|
||||||
|
@ -1319,14 +1211,14 @@ export default mixins(
|
||||||
if (lastSelectedNode) {
|
if (lastSelectedNode) {
|
||||||
const lastSelectedConnection = this.lastSelectedConnection;
|
const lastSelectedConnection = this.lastSelectedConnection;
|
||||||
if (lastSelectedConnection) {
|
if (lastSelectedConnection) {
|
||||||
const [diffX] = getConnectorLengths(lastSelectedConnection);
|
const [diffX] = CanvasHelpers.getConnectorLengths(lastSelectedConnection);
|
||||||
if (diffX <= MAX_X_TO_PUSH_DOWNSTREAM_NODES) {
|
if (diffX <= CanvasHelpers.MAX_X_TO_PUSH_DOWNSTREAM_NODES) {
|
||||||
this.pushDownstreamNodes(lastSelectedNode.name, _PUSH_NODES_LENGTH);
|
this.pushDownstreamNodes(lastSelectedNode.name, CanvasHelpers.PUSH_NODES_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.newNodeInsertPosition) {
|
if (this.newNodeInsertPosition) {
|
||||||
newNodeData.position = getNewNodePosition(this.nodes, [this.newNodeInsertPosition[0], this.newNodeInsertPosition[1] - NODE_SIZE / 2]);
|
newNodeData.position = CanvasHelpers.getNewNodePosition(this.nodes, [this.newNodeInsertPosition[0], this.newNodeInsertPosition[1] - CanvasHelpers.NODE_SIZE / 2]);
|
||||||
this.newNodeInsertPosition = null;
|
this.newNodeInsertPosition = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1343,7 +1235,7 @@ export default mixins(
|
||||||
|
|
||||||
// If a node is active then add the new node directly after the current one
|
// If a node is active then add the new node directly after the current one
|
||||||
// newNodeData.position = [activeNode.position[0], activeNode.position[1] + 60];
|
// newNodeData.position = [activeNode.position[0], activeNode.position[1] + 60];
|
||||||
newNodeData.position = getNewNodePosition(
|
newNodeData.position = CanvasHelpers.getNewNodePosition(
|
||||||
this.nodes,
|
this.nodes,
|
||||||
[lastSelectedNode.position[0] + 200, lastSelectedNode.position[1] + yOffset],
|
[lastSelectedNode.position[0] + 200, lastSelectedNode.position[1] + yOffset],
|
||||||
[100, 0],
|
[100, 0],
|
||||||
|
@ -1351,7 +1243,7 @@ export default mixins(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no node is active find a free spot
|
// If no node is active find a free spot
|
||||||
newNodeData.position = getNewNodePosition(this.nodes, this.lastClickPosition);
|
newNodeData.position = CanvasHelpers.getNewNodePosition(this.nodes, this.lastClickPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if node-name is unique else find one that is
|
// Check if node-name is unique else find one that is
|
||||||
|
@ -1427,12 +1319,12 @@ export default mixins(
|
||||||
},
|
},
|
||||||
initNodeView () {
|
initNodeView () {
|
||||||
this.instance.importDefaults({
|
this.instance.importDefaults({
|
||||||
Connector: CONNECTOR_TYPE_STRIGHT ,
|
Connector: CanvasHelpers.CONNECTOR_TYPE_STRIGHT,
|
||||||
Endpoint: ['Dot', { radius: 5 }],
|
Endpoint: ['Dot', { radius: 5 }],
|
||||||
DragOptions: { cursor: 'pointer', zIndex: 5000 },
|
DragOptions: { cursor: 'pointer', zIndex: 5000 },
|
||||||
PaintStyle: { strokeWidth: 2, stroke: getStyleTokenValue('--color-foreground-dark')},
|
PaintStyle: { strokeWidth: 2, stroke: getStyleTokenValue('--color-foreground-dark')},
|
||||||
HoverPaintStyle: { stroke: getStyleTokenValue('--color-primary'), lineWidth: 4 },
|
HoverPaintStyle: { stroke: getStyleTokenValue('--color-primary'), lineWidth: 4 },
|
||||||
ConnectionOverlays: CONNECTOR_ARROW_OVERLAYS,
|
ConnectionOverlays: CanvasHelpers.CONNECTOR_ARROW_OVERLAYS,
|
||||||
Container: '#node-view',
|
Container: '#node-view',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1489,18 +1381,18 @@ export default mixins(
|
||||||
|
|
||||||
const hideActions = (connection: Connection | null) => {
|
const hideActions = (connection: Connection | null) => {
|
||||||
if (connection) {
|
if (connection) {
|
||||||
hideOverlay(connection, OVERLAY_CONNECTION_ACTIONS_ID);
|
CanvasHelpers.hideOverlay(connection, CanvasHelpers.OVERLAY_CONNECTION_ACTIONS_ID);
|
||||||
showOrHideItemsLabel(connection);
|
CanvasHelpers.showOrHideItemsLabel(connection);
|
||||||
showOrHideMidpointArrow(connection);
|
CanvasHelpers.showOrHideMidpointArrow(connection);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showActions = (connection: Connection | null) => {
|
const showActions = (connection: Connection | null) => {
|
||||||
if (connection) {
|
if (connection) {
|
||||||
showOverlay(connection, OVERLAY_CONNECTION_ACTIONS_ID);
|
CanvasHelpers.showOverlay(connection, CanvasHelpers.OVERLAY_CONNECTION_ACTIONS_ID);
|
||||||
hideOverlay(connection, OVERLAY_RUN_ITEMS_ID);
|
CanvasHelpers.hideOverlay(connection, CanvasHelpers.OVERLAY_RUN_ITEMS_ID);
|
||||||
if (!connection.getOverlay(OVERLAY_RUN_ITEMS_ID)) {
|
if (!connection.getOverlay(CanvasHelpers.OVERLAY_RUN_ITEMS_ID)) {
|
||||||
hideOverlay(connection, OVERLAY_MIDPOINT_ARROW_ID);
|
CanvasHelpers.hideOverlay(connection, CanvasHelpers.OVERLAY_MIDPOINT_ARROW_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1519,15 +1411,15 @@ export default mixins(
|
||||||
targetOutputIndex: targetInfo.index,
|
targetOutputIndex: targetInfo.index,
|
||||||
};
|
};
|
||||||
|
|
||||||
const connectorType = getFlowChartType(info.connection);
|
const connectorType = CanvasHelpers.getFlowChartType(info.connection);
|
||||||
|
|
||||||
info.connection.setConnector(connectorType);
|
info.connection.setConnector(connectorType);
|
||||||
info.connection.setPaintStyle(CONNECTOR_PAINT_STYLE_DEFAULT);
|
info.connection.setPaintStyle(CanvasHelpers.CONNECTOR_PAINT_STYLE_DEFAULT);
|
||||||
addOverlays(info.connection, CONNECTOR_ARROW_OVERLAYS);
|
CanvasHelpers.addOverlays(info.connection, CanvasHelpers.CONNECTOR_ARROW_OVERLAYS);
|
||||||
|
|
||||||
showOrHideMidpointArrow(info.connection);
|
CanvasHelpers.showOrHideMidpointArrow(info.connection);
|
||||||
|
|
||||||
info.connection.removeOverlay(OVERLAY_DROP_NODE_ID);
|
info.connection.removeOverlay(CanvasHelpers.OVERLAY_DROP_NODE_ID);
|
||||||
|
|
||||||
if (this.isReadOnly === false) {
|
if (this.isReadOnly === false) {
|
||||||
let exitTimer: NodeJS.Timeout | undefined;
|
let exitTimer: NodeJS.Timeout | undefined;
|
||||||
|
@ -1583,9 +1475,9 @@ export default mixins(
|
||||||
info.connection.addOverlay([
|
info.connection.addOverlay([
|
||||||
'Label',
|
'Label',
|
||||||
{
|
{
|
||||||
id: OVERLAY_CONNECTION_ACTIONS_ID,
|
id: CanvasHelpers.OVERLAY_CONNECTION_ACTIONS_ID,
|
||||||
label: `<div class="add">${getIcon('plus')}</div> <div class="delete">${getIcon('trash')}</div>`,
|
label: `<div class="add">${CanvasHelpers.getIcon('plus')}</div> <div class="delete">${CanvasHelpers.getIcon('trash')}</div>`,
|
||||||
cssClass: OVERLAY_CONNECTION_ACTIONS_ID,
|
cssClass: CanvasHelpers.OVERLAY_CONNECTION_ACTIONS_ID,
|
||||||
visible: false,
|
visible: false,
|
||||||
events: {
|
events: {
|
||||||
mousedown: (overlay: Overlay, event: MouseEvent) => {
|
mousedown: (overlay: Overlay, event: MouseEvent) => {
|
||||||
|
@ -1610,7 +1502,7 @@ export default mixins(
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputNameOverlay = info.targetEndpoint.getOverlay(OVERLAY_INPUT_NAME_LABEL);
|
const inputNameOverlay = info.targetEndpoint.getOverlay(CanvasHelpers.OVERLAY_INPUT_NAME_LABEL);
|
||||||
if (inputNameOverlay) {
|
if (inputNameOverlay) {
|
||||||
inputNameOverlay.setLocation([-4.5, .5]);
|
inputNameOverlay.setLocation([-4.5, .5]);
|
||||||
}
|
}
|
||||||
|
@ -1642,7 +1534,7 @@ export default mixins(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetEndpoint !== undefined && targetEndpoint.connections!.length === maxConnections) {
|
if (targetEndpoint !== undefined && targetEndpoint.connections!.length === maxConnections) {
|
||||||
const inputNameOverlay = targetEndpoint.getOverlay(OVERLAY_INPUT_NAME_LABEL);
|
const inputNameOverlay = targetEndpoint.getOverlay(CanvasHelpers.OVERLAY_INPUT_NAME_LABEL);
|
||||||
if (![null, undefined].includes(inputNameOverlay)) {
|
if (![null, undefined].includes(inputNameOverlay)) {
|
||||||
inputNameOverlay.setVisible(true);
|
inputNameOverlay.setVisible(true);
|
||||||
}
|
}
|
||||||
|
@ -1682,7 +1574,7 @@ export default mixins(
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.bind('connectionDetached', (info) => {
|
this.instance.bind('connectionDetached', (info) => {
|
||||||
const inputNameOverlay = info.targetEndpoint.getOverlay(OVERLAY_INPUT_NAME_LABEL);
|
const inputNameOverlay = info.targetEndpoint.getOverlay(CanvasHelpers.OVERLAY_INPUT_NAME_LABEL);
|
||||||
if (inputNameOverlay) {
|
if (inputNameOverlay) {
|
||||||
// todo
|
// todo
|
||||||
inputNameOverlay.setLocation([-3, .5]);
|
inputNameOverlay.setLocation([-3, .5]);
|
||||||
|
@ -1696,7 +1588,7 @@ export default mixins(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.instance.bind('connectionDrag', (connection: Connection) => {
|
this.instance.bind('connectionDrag', (connection: Connection) => {
|
||||||
this.newNodeInsertPosition = null;
|
this.newNodeInsertPosition = null;
|
||||||
addOverlays(connection, CONNECTOR_DROP_NODE_OVERLAY);
|
CanvasHelpers.addOverlays(connection, CanvasHelpers.CONNECTOR_DROP_NODE_OVERLAY);
|
||||||
|
|
||||||
let droppable = false;
|
let droppable = false;
|
||||||
const onMouseMove = () => {
|
const onMouseMove = () => {
|
||||||
|
@ -1707,17 +1599,17 @@ export default mixins(
|
||||||
const elements = document.querySelector('div.jtk-endpoint.dropHover');
|
const elements = document.querySelector('div.jtk-endpoint.dropHover');
|
||||||
if (elements && !droppable) {
|
if (elements && !droppable) {
|
||||||
droppable = true;
|
droppable = true;
|
||||||
connection.setConnector(getFlowChartType(connection));
|
connection.setConnector(CanvasHelpers.getFlowChartType(connection));
|
||||||
connection.setPaintStyle(CONNECTOR_PAINT_STYLE_PRIMARY);
|
connection.setPaintStyle(CanvasHelpers.CONNECTOR_PAINT_STYLE_PRIMARY);
|
||||||
addOverlays(connection, CONNECTOR_ARROW_OVERLAYS);
|
CanvasHelpers.addOverlays(connection, CanvasHelpers.CONNECTOR_ARROW_OVERLAYS);
|
||||||
hideOverlay(connection, OVERLAY_DROP_NODE_ID);
|
CanvasHelpers.hideOverlay(connection, CanvasHelpers.OVERLAY_DROP_NODE_ID);
|
||||||
}
|
}
|
||||||
else if (!elements && droppable) {
|
else if (!elements && droppable) {
|
||||||
droppable = false;
|
droppable = false;
|
||||||
connection.setConnector(CONNECTOR_TYPE_STRIGHT );
|
connection.setConnector(CanvasHelpers.CONNECTOR_TYPE_STRIGHT);
|
||||||
connection.setPaintStyle(CONNECTOR_PAINT_STYLE_DEFAULT);
|
connection.setPaintStyle(CanvasHelpers.CONNECTOR_PAINT_STYLE_DEFAULT);
|
||||||
addOverlays(connection, CONNECTOR_ARROW_OVERLAYS);
|
CanvasHelpers.addOverlays(connection, CanvasHelpers.CONNECTOR_ARROW_OVERLAYS);
|
||||||
showOverlay(connection, OVERLAY_DROP_NODE_ID);
|
CanvasHelpers.showOverlay(connection, CanvasHelpers.OVERLAY_DROP_NODE_ID);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1736,9 +1628,9 @@ export default mixins(
|
||||||
await this.$store.dispatch('workflows/setNewWorkflowName');
|
await this.$store.dispatch('workflows/setNewWorkflowName');
|
||||||
this.$store.commit('setStateDirty', false);
|
this.$store.commit('setStateDirty', false);
|
||||||
|
|
||||||
await this.addNodes([DEFAULT_START_NODE]);
|
await this.addNodes([CanvasHelpers.DEFAULT_START_NODE]);
|
||||||
|
|
||||||
this.nodeSelectedByName(DEFAULT_START_NODE.name, false);
|
this.nodeSelectedByName(CanvasHelpers.DEFAULT_START_NODE.name, false);
|
||||||
|
|
||||||
this.$store.commit('setStateDirty', false);
|
this.$store.commit('setStateDirty', false);
|
||||||
|
|
||||||
|
@ -1889,7 +1781,7 @@ export default mixins(
|
||||||
// Check if node-name is unique else find one that is
|
// Check if node-name is unique else find one that is
|
||||||
newNodeData.name = this.getUniqueNodeName(newNodeData.name);
|
newNodeData.name = this.getUniqueNodeName(newNodeData.name);
|
||||||
|
|
||||||
newNodeData.position = getNewNodePosition(
|
newNodeData.position = CanvasHelpers.getNewNodePosition(
|
||||||
this.nodes,
|
this.nodes,
|
||||||
[node.position[0], node.position[1] + 140],
|
[node.position[0], node.position[1] + 140],
|
||||||
[0, 140],
|
[0, 140],
|
||||||
|
@ -1947,8 +1839,8 @@ export default mixins(
|
||||||
}) as Connection[];
|
}) as Connection[];
|
||||||
|
|
||||||
[...incoming, ...outgoing].forEach((connection: Connection) => {
|
[...incoming, ...outgoing].forEach((connection: Connection) => {
|
||||||
showOrHideMidpointArrow(connection);
|
CanvasHelpers.showOrHideMidpointArrow(connection);
|
||||||
showOrHideItemsLabel(connection);
|
CanvasHelpers.showOrHideItemsLabel(connection);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onNodeRun ({name, data}: {name: string, data: ITaskData[] | null}) {
|
onNodeRun ({name, data}: {name: string, data: ITaskData[] | null}) {
|
||||||
|
@ -1957,9 +1849,9 @@ export default mixins(
|
||||||
const sourceId = `${NODE_NAME_PREFIX}${sourceIndex}`;
|
const sourceId = `${NODE_NAME_PREFIX}${sourceIndex}`;
|
||||||
|
|
||||||
const resetConnection = (connection: Connection) => {
|
const resetConnection = (connection: Connection) => {
|
||||||
connection.removeOverlay(OVERLAY_RUN_ITEMS_ID);
|
connection.removeOverlay(CanvasHelpers.OVERLAY_RUN_ITEMS_ID);
|
||||||
connection.setPaintStyle(CONNECTOR_PAINT_STYLE_DEFAULT);
|
connection.setPaintStyle(CanvasHelpers.CONNECTOR_PAINT_STYLE_DEFAULT);
|
||||||
showOrHideMidpointArrow(connection);
|
CanvasHelpers.showOrHideMidpointArrow(connection);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (connection.canvas) {
|
if (connection.canvas) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -2039,15 +1931,15 @@ export default mixins(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.setPaintStyle(CONNECTOR_PAINT_STYLE_SUCCESS);
|
conn.setPaintStyle(CanvasHelpers.CONNECTOR_PAINT_STYLE_SUCCESS);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (conn.canvas) {
|
if (conn.canvas) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
(conn.canvas as Element).classList.add('success');
|
(conn.canvas as Element).classList.add('success');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn.getOverlay(OVERLAY_RUN_ITEMS_ID)) {
|
if (conn.getOverlay(CanvasHelpers.OVERLAY_RUN_ITEMS_ID)) {
|
||||||
conn.removeOverlay(OVERLAY_RUN_ITEMS_ID);
|
conn.removeOverlay(CanvasHelpers.OVERLAY_RUN_ITEMS_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
let label = `${output.total}`;
|
let label = `${output.total}`;
|
||||||
|
@ -2057,15 +1949,15 @@ export default mixins(
|
||||||
conn.addOverlay([
|
conn.addOverlay([
|
||||||
'Label',
|
'Label',
|
||||||
{
|
{
|
||||||
id: OVERLAY_RUN_ITEMS_ID,
|
id: CanvasHelpers.OVERLAY_RUN_ITEMS_ID,
|
||||||
label,
|
label,
|
||||||
cssClass: 'connection-output-items-label',
|
cssClass: 'connection-output-items-label',
|
||||||
location: .5,
|
location: .5,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
showOrHideItemsLabel(conn);
|
CanvasHelpers.showOrHideItemsLabel(conn);
|
||||||
showOrHideMidpointArrow(conn);
|
CanvasHelpers.showOrHideMidpointArrow(conn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { INodeUi, IZoomConfig, XYPosition } from "@/Interface";
|
import { getStyleTokenValue } from "@/components/helpers";
|
||||||
import { Connection } from "jsplumb";
|
import { START_NODE_TYPE } from "@/constants";
|
||||||
|
import { IBounds, INodeUi, IZoomConfig, XYPosition } from "@/Interface";
|
||||||
|
import { Connection, OverlaySpec, PaintStyle } from "jsplumb";
|
||||||
|
|
||||||
export const OVERLAY_DROP_NODE_ID = 'drop-add-node';
|
export const OVERLAY_DROP_NODE_ID = 'drop-add-node';
|
||||||
export const OVERLAY_MIDPOINT_ARROW_ID = 'midpoint-arrow';
|
export const OVERLAY_MIDPOINT_ARROW_ID = 'midpoint-arrow';
|
||||||
|
@ -9,15 +11,111 @@ export const OVERLAY_CONNECTION_ACTIONS_ID = 'connection-actions';
|
||||||
export const JSPLUMB_FLOWCHART_STUB = 26;
|
export const JSPLUMB_FLOWCHART_STUB = 26;
|
||||||
export const OVERLAY_INPUT_NAME_LABEL = 'input-name-label';
|
export const OVERLAY_INPUT_NAME_LABEL = 'input-name-label';
|
||||||
|
|
||||||
const _MIN_X_TO_SHOW_OUTPUT_LABEL = 90;
|
const MIN_X_TO_SHOW_OUTPUT_LABEL = 90;
|
||||||
const _MIN_Y_TO_SHOW_OUTPUT_LABEL = 100;
|
const MIN_Y_TO_SHOW_OUTPUT_LABEL = 100;
|
||||||
|
|
||||||
interface ICorners {
|
export const NODE_SIZE = 100;
|
||||||
minX: number;
|
export const DEFAULT_START_POSITION_X = 240;
|
||||||
minY: number;
|
export const DEFAULT_START_POSITION_Y = 300;
|
||||||
maxX: number;
|
export const HEADER_HEIGHT = 65;
|
||||||
maxY: number;
|
export const SIDEBAR_WIDTH = 65;
|
||||||
}
|
export const MAX_X_TO_PUSH_DOWNSTREAM_NODES = 300;
|
||||||
|
export const PUSH_NODES_OFFSET = 200;
|
||||||
|
|
||||||
|
export const DEFAULT_START_NODE = {
|
||||||
|
name: 'Start',
|
||||||
|
type: START_NODE_TYPE,
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [
|
||||||
|
DEFAULT_START_POSITION_X,
|
||||||
|
DEFAULT_START_POSITION_Y,
|
||||||
|
] as XYPosition,
|
||||||
|
parameters: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONNECTOR_PAINT_STYLE_DEFAULT: PaintStyle = {
|
||||||
|
stroke: getStyleTokenValue('--color-foreground-dark'),
|
||||||
|
strokeWidth: 2,
|
||||||
|
outlineWidth: 12,
|
||||||
|
outlineStroke: 'transparent',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONNECTOR_PAINT_STYLE_PRIMARY = {
|
||||||
|
...CONNECTOR_PAINT_STYLE_DEFAULT,
|
||||||
|
stroke: getStyleTokenValue('--color-primary'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONNECTOR_PAINT_STYLE_SUCCESS = {
|
||||||
|
...CONNECTOR_PAINT_STYLE_DEFAULT,
|
||||||
|
stroke: getStyleTokenValue('--color-success'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONNECTOR_TYPE_STRIGHT = ['Straight'];
|
||||||
|
|
||||||
|
export const getFlowChartType = (connection: Connection) => {
|
||||||
|
const inputIndex = connection.__meta ? connection.__meta.targetOutputIndex : 0;
|
||||||
|
const outputIndex = connection.__meta ? connection.__meta.sourceOutputIndex : 0;
|
||||||
|
|
||||||
|
const outputEndpoint = connection.endpoints[0];
|
||||||
|
const outputOverlay = outputEndpoint.getOverlay('output-name-label');
|
||||||
|
let labelOffset = 0;
|
||||||
|
if (outputOverlay && outputOverlay.label && outputOverlay.label.length > 1) {
|
||||||
|
labelOffset = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['N8nFlowchart', {
|
||||||
|
cornerRadius: 4,
|
||||||
|
stub: JSPLUMB_FLOWCHART_STUB + 10 * outputIndex + 10 * inputIndex + labelOffset,
|
||||||
|
gap: 5,
|
||||||
|
alwaysRespectStubs: true,
|
||||||
|
yOffset: NODE_SIZE,
|
||||||
|
loopbackMinimum: 140,
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONNECTOR_ARROW_OVERLAYS: OverlaySpec[] = [
|
||||||
|
[
|
||||||
|
'Arrow',
|
||||||
|
{
|
||||||
|
id: OVERLAY_ENDPOINT_ARROW_ID,
|
||||||
|
location: 1,
|
||||||
|
width: 12,
|
||||||
|
foldback: 1,
|
||||||
|
length: 10,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Arrow',
|
||||||
|
{
|
||||||
|
id: OVERLAY_MIDPOINT_ARROW_ID,
|
||||||
|
location: 0.5,
|
||||||
|
width: 12,
|
||||||
|
foldback: 1,
|
||||||
|
length: 10,
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
export const CONNECTOR_DROP_NODE_OVERLAY: OverlaySpec[] = [
|
||||||
|
[
|
||||||
|
'Label',
|
||||||
|
{
|
||||||
|
id: OVERLAY_DROP_NODE_ID,
|
||||||
|
label: 'Drop connection<br />to create node',
|
||||||
|
cssClass: 'drop-add-node-label',
|
||||||
|
location: 0.5,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
export const addOverlays = (connection: Connection, overlays: OverlaySpec[]) => {
|
||||||
|
overlays.forEach((overlay: OverlaySpec) => {
|
||||||
|
connection.addOverlay(overlay);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const getLeftmostTopNode = (nodes: INodeUi[]): INodeUi => {
|
export const getLeftmostTopNode = (nodes: INodeUi[]): INodeUi => {
|
||||||
return nodes.reduce((leftmostTop, node) => {
|
return nodes.reduce((leftmostTop, node) => {
|
||||||
|
@ -29,8 +127,8 @@ export const getLeftmostTopNode = (nodes: INodeUi[]): INodeUi => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWorkflowCorners = (nodes: INodeUi[]): ICorners => {
|
export const getWorkflowCorners = (nodes: INodeUi[]): IBounds => {
|
||||||
return nodes.reduce((accu: ICorners, node: INodeUi) => {
|
return nodes.reduce((accu: IBounds, node: INodeUi) => {
|
||||||
if (node.position[0] < accu.minX) {
|
if (node.position[0] < accu.minX) {
|
||||||
accu.minX = node.position[0];
|
accu.minX = node.position[0];
|
||||||
}
|
}
|
||||||
|
@ -147,7 +245,7 @@ export const showOrHideItemsLabel = (connection: Connection) => {
|
||||||
|
|
||||||
const [diffX, diffY] = getConnectorLengths(connection);
|
const [diffX, diffY] = getConnectorLengths(connection);
|
||||||
|
|
||||||
if (diffX < _MIN_X_TO_SHOW_OUTPUT_LABEL && diffY < _MIN_Y_TO_SHOW_OUTPUT_LABEL) {
|
if (diffX < MIN_X_TO_SHOW_OUTPUT_LABEL && diffY < MIN_Y_TO_SHOW_OUTPUT_LABEL) {
|
||||||
overlay.setVisible(false);
|
overlay.setVisible(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue