fix(editor): Fix for missing node connections in dev environment (#4707)

* 🐛 Fixing connections not showing up in dev environment
* 🐛 Fixing a bug when opening execution page directly
This commit is contained in:
Milorad FIlipović
2022-11-24 10:52:56 +01:00
committed by GitHub
parent ee6ac5d341
commit b18ae18a6b
10 changed files with 810 additions and 843 deletions

View File

@@ -172,41 +172,6 @@ import NodeSettings from '@/components/NodeSettings.vue';
import Sticky from '@/components/Sticky.vue';
import CanvasAddButton from './CanvasAddButton.vue';
import {
CONNECTOR_ARROW_OVERLAYS,
CONNECTOR_FLOWCHART_TYPE,
CONNECTOR_PAINT_STYLE_DEFAULT,
CONNECTOR_PAINT_STYLE_PRIMARY,
GRID_SIZE,
MAX_X_TO_PUSH_DOWNSTREAM_NODES,
NODE_SIZE,
PUSH_NODES_OFFSET,
WELCOME_STICKY_NODE,
addConnectionActionsOverlay,
addConnectionOutputSuccess,
getAccountAge,
getBackgroundStyles,
getConnectorLengths,
getFixedNodesList,
getMousePosition,
getNewNodePosition,
getNodeViewTab,
getInputEndpointUUID,
getOutputEndpointUUID,
getOutputSummary,
getRunItemsLabel,
hideConnectionActions,
moveBackInputLabelPosition,
showDropConnectionState,
showOrHideMidpointArrow,
showOrHideItemsLabel,
showPullConnectionState,
resetConnection,
resetConnectionAfterPull,
resetInputLabelPosition,
showConnectionActions,
} from '@/utils';
import mixins from 'vue-typed-mixins';
import { v4 as uuid } from 'uuid';
import {
@@ -265,6 +230,8 @@ import { useNodeCreatorStore } from '@/stores/nodeCreator';
import { dataPinningEventBus } from '@/event-bus/data-pinning-event-bus';
import { useCanvasStore } from '@/stores/canvas';
import useWorkflowsEEStore from "@/stores/workflows.ee";
import * as NodeViewUtils from '@/utils/nodeViewUtils';
import { getAccountAge, getNodeViewTab } from '@/utils';
interface AddNodeOptions {
position?: XYPosition;
@@ -488,7 +455,7 @@ export default mixins(
};
},
backgroundStyle(): object {
return getBackgroundStyles(
return NodeViewUtils.getBackgroundStyles(
this.nodeViewScale,
this.uiStore.nodeViewOffsetPosition,
this.isExecutionPreview,
@@ -549,7 +516,7 @@ export default mixins(
},
data() {
return {
GRID_SIZE,
GRID_SIZE: NodeViewUtils.GRID_SIZE,
STICKY_NODE_TYPE,
createNodeActive: false,
lastSelectedConnection: null as null | Connection,
@@ -781,7 +748,7 @@ export default mixins(
throw new Error('Invalid workflow object');
}
this.resetWorkspace();
data.workflow.nodes = getFixedNodesList(data.workflow.nodes);
data.workflow.nodes = NodeViewUtils.getFixedNodesList(data.workflow.nodes);
await this.addNodes(data.workflow.nodes as INodeUi[], data.workflow.connections);
@@ -820,7 +787,7 @@ export default mixins(
return;
}
data.workflow.nodes = getFixedNodesList(data.workflow.nodes) as INodeUi[];
data.workflow.nodes = NodeViewUtils.getFixedNodesList(data.workflow.nodes) as INodeUi[];
this.blankRedirect = true;
this.$router.replace({ name: VIEWS.NEW_WORKFLOW, query: { templateId } });
@@ -1453,7 +1420,7 @@ export default mixins(
// 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(workflowData, getNewNodePosition(this.nodes, this.lastClickPosition));
this.updateNodePositions(workflowData, NodeViewUtils.getNewNodePosition(this.nodes, this.lastClickPosition));
const data = await this.addNodesToWorkflow(workflowData);
@@ -1522,8 +1489,8 @@ export default mixins(
this.addNode(nodeTypeName, {
position: [
mousePosition[0] - NODE_SIZE / 2,
mousePosition[1] - NODE_SIZE / 2,
mousePosition[0] - NodeViewUtils.NODE_SIZE / 2,
mousePosition[1] - NodeViewUtils.NODE_SIZE / 2,
],
dragAndDrop: true,
});
@@ -1664,21 +1631,21 @@ export default mixins(
const lastSelectedNode = this.lastSelectedNode;
if (options.position) {
newNodeData.position = getNewNodePosition(this.canvasStore.getNodesWithPlaceholderNode(), options.position);
newNodeData.position = NodeViewUtils.getNewNodePosition(this.canvasStore.getNodesWithPlaceholderNode(), options.position);
} else if (lastSelectedNode) {
const lastSelectedConnection = this.lastSelectedConnection;
if (lastSelectedConnection) { // set when injecting into a connection
const [diffX] = getConnectorLengths(lastSelectedConnection);
if (diffX <= MAX_X_TO_PUSH_DOWNSTREAM_NODES) {
this.pushDownstreamNodes(lastSelectedNode.name, PUSH_NODES_OFFSET);
const [diffX] = NodeViewUtils.getConnectorLengths(lastSelectedConnection);
if (diffX <= NodeViewUtils.MAX_X_TO_PUSH_DOWNSTREAM_NODES) {
this.pushDownstreamNodes(lastSelectedNode.name, NodeViewUtils.PUSH_NODES_OFFSET);
}
}
// set when pulling connections
if (this.newNodeInsertPosition) {
newNodeData.position = getNewNodePosition(this.nodes, [
this.newNodeInsertPosition[0] + GRID_SIZE,
this.newNodeInsertPosition[1] - NODE_SIZE / 2,
newNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, [
this.newNodeInsertPosition[0] + NodeViewUtils.GRID_SIZE,
this.newNodeInsertPosition[1] - NodeViewUtils.NODE_SIZE / 2,
]);
this.newNodeInsertPosition = null;
} else {
@@ -1696,9 +1663,9 @@ export default mixins(
// 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 = getNewNodePosition(
newNodeData.position = NodeViewUtils.getNewNodePosition(
this.nodes,
[lastSelectedNode.position[0] + PUSH_NODES_OFFSET, lastSelectedNode.position[1] + yOffset],
[lastSelectedNode.position[0] + NodeViewUtils.PUSH_NODES_OFFSET, lastSelectedNode.position[1] + yOffset],
[100, 0],
);
}
@@ -1710,7 +1677,7 @@ export default mixins(
// If no node is active find a free spot
: this.lastClickPosition as XYPosition;
newNodeData.position = getNewNodePosition(this.nodes, position);
newNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, position);
}
@@ -1820,12 +1787,12 @@ export default mixins(
},
initNodeView() {
this.instance.importDefaults({
Connector: CONNECTOR_FLOWCHART_TYPE,
Connector: NodeViewUtils.CONNECTOR_FLOWCHART_TYPE,
Endpoint: ['Dot', { radius: 5 }],
DragOptions: { cursor: 'pointer', zIndex: 5000 },
PaintStyle: CONNECTOR_PAINT_STYLE_DEFAULT,
HoverPaintStyle: CONNECTOR_PAINT_STYLE_PRIMARY,
ConnectionOverlays: CONNECTOR_ARROW_OVERLAYS,
PaintStyle: NodeViewUtils.CONNECTOR_PAINT_STYLE_DEFAULT,
HoverPaintStyle: NodeViewUtils.CONNECTOR_PAINT_STYLE_PRIMARY,
ConnectionOverlays: NodeViewUtils.CONNECTOR_ARROW_OVERLAYS,
Container: '#node-view',
});
@@ -1921,7 +1888,7 @@ export default mixins(
};
}
resetConnection(info.connection);
NodeViewUtils.resetConnection(info.connection);
if (!this.isReadOnly) {
let exitTimer: NodeJS.Timeout | undefined;
@@ -1941,14 +1908,14 @@ export default mixins(
return;
}
hideConnectionActions(activeConnection);
NodeViewUtils.hideConnectionActions(activeConnection);
enterTimer = setTimeout(() => {
enterTimer = undefined;
if (info.connection) {
activeConnection = info.connection;
showConnectionActions(info.connection);
NodeViewUtils.showConnectionActions(info.connection);
}
}, 150);
} catch (e) {
@@ -1975,7 +1942,7 @@ export default mixins(
exitTimer = undefined;
if (info.connection && activeConnection === info.connection) {
hideConnectionActions(activeConnection);
NodeViewUtils.hideConnectionActions(activeConnection);
activeConnection = null;
}
}, 500);
@@ -1984,7 +1951,7 @@ export default mixins(
}
});
addConnectionActionsOverlay(info.connection,
NodeViewUtils.addConnectionActionsOverlay(info.connection,
() => {
activeConnection = null;
this.__deleteJSPlumbConnection(info.connection);
@@ -2001,7 +1968,7 @@ export default mixins(
});
}
moveBackInputLabelPosition(info.targetEndpoint);
NodeViewUtils.moveBackInputLabelPosition(info.targetEndpoint);
this.workflowsStore.addConnection({
connection: [
@@ -2029,7 +1996,7 @@ export default mixins(
// calls the "connection" event but not the "connectionDetached" one. So we listen
// additionally to the "connectionMoved" event and then only delete the existing connection.
resetInputLabelPosition(info.originalTargetEndpoint);
NodeViewUtils.resetInputLabelPosition(info.originalTargetEndpoint);
// @ts-ignore
const sourceInfo = info.originalSourceEndpoint.getParameters();
@@ -2057,7 +2024,7 @@ export default mixins(
this.instance.bind('connectionDetached', (info) => {
try {
resetInputLabelPosition(info.targetEndpoint);
NodeViewUtils.resetInputLabelPosition(info.targetEndpoint);
info.connection.removeOverlays();
this.__removeConnectionByConnectionInfo(info, false);
@@ -2080,7 +2047,7 @@ export default mixins(
this.pullConnActiveNodeName = null;
this.pullConnActive = true;
this.newNodeInsertPosition = null;
resetConnection(connection);
NodeViewUtils.resetConnection(connection);
const nodes = [...document.querySelectorAll('.node-default')];
@@ -2092,14 +2059,14 @@ export default mixins(
const element = document.querySelector('.jtk-endpoint.dropHover');
if (element) {
// @ts-ignore
showDropConnectionState(connection, element._jsPlumb);
NodeViewUtils.showDropConnectionState(connection, element._jsPlumb);
return;
}
const inputMargin = 24;
const intersecting = nodes.find((element: Element) => {
const { top, left, right, bottom } = element.getBoundingClientRect();
const [x, y] = getMousePosition(e);
const [x, y] = NodeViewUtils.getMousePosition(e);
if (top <= y && bottom >= y && (left - inputMargin) <= x && right >= x) {
const nodeName = (element as HTMLElement).dataset['name'] as string;
const node = this.workflowsStore.getNodeByName(nodeName) as INodeUi | null;
@@ -2111,7 +2078,7 @@ export default mixins(
if (endpointUUID) {
const endpoint = this.instance.getEndpoint(endpointUUID);
showDropConnectionState(connection, endpoint);
NodeViewUtils.showDropConnectionState(connection, endpoint);
return true;
}
@@ -2123,7 +2090,7 @@ export default mixins(
});
if (!intersecting) {
showPullConnectionState(connection);
NodeViewUtils.showPullConnectionState(connection);
this.pullConnActiveNodeName = null;
}
};
@@ -2131,7 +2098,7 @@ export default mixins(
const onMouseUp = (e: MouseEvent | TouchEvent) => {
this.pullConnActive = false;
this.newNodeInsertPosition = this.getMousePositionWithinNodeView(e);
resetConnectionAfterPull(connection);
NodeViewUtils.resetConnectionAfterPull(connection);
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
};
@@ -2164,7 +2131,7 @@ export default mixins(
this.workflowsStore.activeWorkflowExecution = null;
this.uiStore.stateIsDirty = false;
this.canvasStore.setZoomLevel(1);
this.canvasStore.setZoomLevel(1, 0);
this.canvasStore.zoomToFit();
},
tryToAddWelcomeSticky: once(async function(this: any) {
@@ -2174,19 +2141,19 @@ export default mixins(
// Inject welcome sticky note and zoom to fit
if (newWorkflow?.onboardingFlowEnabled && !this.isReadOnly) {
const collisionPadding = GRID_SIZE + NODE_SIZE;
const collisionPadding = NodeViewUtils.GRID_SIZE + NodeViewUtils.NODE_SIZE;
// Position the welcome sticky left to the added trigger node
let position: XYPosition = [...(this.triggerNodes[0].position as XYPosition)];
position[0] -= WELCOME_STICKY_NODE.parameters.width + (GRID_SIZE * 4);
position = getNewNodePosition(this.nodes, position, [collisionPadding, collisionPadding]);
position[0] -= NodeViewUtils.WELCOME_STICKY_NODE.parameters.width + (NodeViewUtils.GRID_SIZE * 4);
position = NodeViewUtils.getNewNodePosition(this.nodes, position, [collisionPadding, collisionPadding]);
await this.addNodes([{
id: uuid(),
...WELCOME_STICKY_NODE,
...NodeViewUtils.WELCOME_STICKY_NODE,
parameters: {
// Use parameters from the template but add translated content
...WELCOME_STICKY_NODE.parameters,
...NodeViewUtils.WELCOME_STICKY_NODE.parameters,
content: this.$locale.baseText('onboardingWorkflow.stickyContent'),
},
position,
@@ -2285,7 +2252,7 @@ export default mixins(
return null;
}
return getOutputEndpointUUID(node.id, index);
return NodeViewUtils.getOutputEndpointUUID(node.id, index);
},
getInputEndpointUUID(nodeName: string, index: number) {
const node = this.workflowsStore.getNodeByName(nodeName);
@@ -2293,7 +2260,7 @@ export default mixins(
return null;
}
return getInputEndpointUUID(node.id, index);
return NodeViewUtils.getInputEndpointUUID(node.id, index);
},
__addConnection(connection: [IConnection, IConnection], addVisualConnection = false) {
if (addVisualConnection) {
@@ -2408,7 +2375,7 @@ export default mixins(
type: newNodeData.type,
});
newNodeData.position = getNewNodePosition(
newNodeData.position = NodeViewUtils.getNewNodePosition(
this.nodes,
[node.position[0], node.position[1] + 140],
[0, 140],
@@ -2460,8 +2427,8 @@ export default mixins(
const sourceId = sourceNode.id;
const targetId = targetNode.id;
const sourceEndpoint = getOutputEndpointUUID(sourceId, sourceOutputIndex);
const targetEndpoint = getInputEndpointUUID(targetId, targetInputIndex);
const sourceEndpoint = NodeViewUtils.getOutputEndpointUUID(sourceId, sourceOutputIndex);
const targetEndpoint = NodeViewUtils.getInputEndpointUUID(targetId, targetInputIndex);
// @ts-ignore
const connections = this.instance.getConnections({
@@ -2508,8 +2475,8 @@ export default mixins(
const { incoming, outgoing } = this.getIncomingOutgoingConnections(node.name);
[...incoming, ...outgoing].forEach((connection: Connection) => {
showOrHideMidpointArrow(connection);
showOrHideItemsLabel(connection);
NodeViewUtils.showOrHideMidpointArrow(connection);
NodeViewUtils.showOrHideItemsLabel(connection);
});
},
onNodeRun({ name, data, waiting }: { name: string, data: ITaskData[] | null, waiting: boolean }) {
@@ -2528,7 +2495,7 @@ export default mixins(
}) as Connection[];
outgoing.forEach((connection: Connection) => {
resetConnection(connection);
NodeViewUtils.resetConnection(connection);
});
const endpoints = this.getJSPlumbEndpoints(sourceNodeName);
endpoints.forEach((endpoint: Endpoint) => {
@@ -2542,7 +2509,7 @@ export default mixins(
}
const nodeConnections = this.workflowsStore.outgoingConnectionsByNodeName(sourceNodeName).main;
const outputMap = getOutputSummary(data, nodeConnections || []);
const outputMap = NodeViewUtils.getOutputSummary(data, nodeConnections || []);
Object.keys(outputMap).forEach((sourceOutputIndex: string) => {
Object.keys(outputMap[sourceOutputIndex]).forEach((targetNodeName: string) => {
@@ -2554,10 +2521,10 @@ export default mixins(
const output = outputMap[sourceOutputIndex][targetNodeName][targetInputIndex];
if (!output || !output.total) {
resetConnection(connection);
NodeViewUtils.resetConnection(connection);
}
else {
addConnectionOutputSuccess(connection, output);
NodeViewUtils.addConnectionOutputSuccess(connection, output);
}
}
}
@@ -2566,7 +2533,7 @@ export default mixins(
if (endpoint && endpoint.endpoint) {
const output = outputMap[sourceOutputIndex][NODE_OUTPUT_DEFAULT_KEY][0];
if (output && output.total > 0) {
(endpoint.endpoint as N8nPlusEndpoint).setSuccessOutput(getRunItemsLabel(output));
(endpoint.endpoint as N8nPlusEndpoint).setSuccessOutput(NodeViewUtils.getRunItemsLabel(output));
}
else {
(endpoint.endpoint as N8nPlusEndpoint).clearSuccessOutput();
@@ -3237,7 +3204,7 @@ export default mixins(
}) as Connection[];
connections.forEach((connection) => {
addConnectionOutputSuccess(connection, {
NodeViewUtils.addConnectionOutputSuccess(connection, {
total: pinData[nodeName].length,
iterations: 0,
});
@@ -3256,7 +3223,7 @@ export default mixins(
source: node.id,
}) as Connection[];
connections.forEach(resetConnection);
connections.forEach(NodeViewUtils.resetConnection);
});
},
onToggleNodeCreator({ source, createNodeActive }: { source?: string; createNodeActive: boolean }) {