handle nodes moving

This commit is contained in:
Mutasem 2021-10-13 12:45:41 +02:00
parent 1c961d4b0b
commit 97280329b2
5 changed files with 62 additions and 29 deletions

View file

@ -103,11 +103,6 @@ export interface INodeUi extends INode {
color?: string; color?: string;
notes?: string; notes?: string;
issues?: INodeIssues; issues?: INodeIssues;
_jsPlumb?: {
endpoints?: {
[key: string]: IEndpointOptions[];
};
};
} }
export interface INodeTypesMaxCount { export interface INodeTypesMaxCount {

View file

@ -328,6 +328,8 @@ export const nodeBase = mixins(
this.$store.commit('updateNodeProperties', updateInformation); this.$store.commit('updateNodeProperties', updateInformation);
}); });
this.$emit('moved', node);
} }
}, },
filter: '.node-description, .node-description .node-name, .node-description .node-subtitle', filter: '.node-description, .node-description .node-name, .node-description .node-subtitle',

View file

@ -728,9 +728,7 @@ export const store = new Vuex.Store({
allConnections: (state): IConnections => { allConnections: (state): IConnections => {
return state.workflow.connections; return state.workflow.connections;
}, },
// connectionsByNodeName: (state) => (nodeName: string): {[key: string]: Connection[][]} | null => { outgoingConnectionsByNodeName: (state) => (nodeName: string): INodeConnections => {
// connectionsByNodeName: (state) => (nodeName: string): { [key: string]: NodeConnections} | null => {
connectionsByNodeName: (state) => (nodeName: string): INodeConnections => {
if (state.workflow.connections.hasOwnProperty(nodeName)) { if (state.workflow.connections.hasOwnProperty(nodeName)) {
return state.workflow.connections[nodeName]; return state.workflow.connections[nodeName];
} }

View file

@ -21,6 +21,7 @@
@nodeSelected="nodeSelectedByName" @nodeSelected="nodeSelectedByName"
@removeNode="removeNode" @removeNode="removeNode"
@runWorkflow="runWorkflow" @runWorkflow="runWorkflow"
@moved="onNodeMoved"
:id="'node-' + getNodeIndex(nodeData.name)" :id="'node-' + getNodeIndex(nodeData.name)"
:key="getNodeIndex(nodeData.name)" :key="getNodeIndex(nodeData.name)"
:name="nodeData.name" :name="nodeData.name"
@ -105,6 +106,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { import {
Connection,
OverlaySpec, OverlaySpec,
} from 'jsplumb'; } from 'jsplumb';
import { MessageBoxInputData } from 'element-ui/types/message-box'; import { MessageBoxInputData } from 'element-ui/types/message-box';
@ -130,7 +132,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 { getLeftmostTopNode, getWorkflowCorners, scaleSmaller, scaleBigger, scaleReset } from './helpers'; import { getLeftmostTopNode, getWorkflowCorners, scaleSmaller, scaleBigger, scaleReset, addOrRemoveMidpointArrow } from './helpers';
import mixins from 'vue-typed-mixins'; import mixins from 'vue-typed-mixins';
import { v4 as uuidv4} from 'uuid'; import { v4 as uuidv4} from 'uuid';
@ -266,9 +268,6 @@ export default mixins(
lastSelectedNode (): INodeUi { lastSelectedNode (): INodeUi {
return this.$store.getters.lastSelectedNode; return this.$store.getters.lastSelectedNode;
}, },
connections (): IConnectionsUi {
return this.$store.getters.allConnections;
},
nodes (): INodeUi[] { nodes (): INodeUi[] {
return this.$store.getters.allNodes; return this.$store.getters.allNodes;
}, },
@ -670,7 +669,7 @@ export default mixins(
return; return;
} }
const connections = this.$store.getters.connectionsByNodeName(lastSelectedNode.name); const connections = this.$store.getters.outgoingConnectionsByNodeName(lastSelectedNode.name);
if (connections.main === undefined || connections.main.length === 0) { if (connections.main === undefined || connections.main.length === 0) {
return; return;
@ -725,7 +724,7 @@ export default mixins(
} }
const parentNode = connections.main[0][0].node; const parentNode = connections.main[0][0].node;
const connectionsParent = this.$store.getters.connectionsByNodeName(parentNode); const connectionsParent = this.$store.getters.outgoingConnectionsByNodeName(parentNode);
if (connectionsParent.main === undefined || connectionsParent.main.length === 0) { if (connectionsParent.main === undefined || connectionsParent.main.length === 0) {
return; return;
@ -1258,7 +1257,7 @@ export default mixins(
await Vue.nextTick(); await Vue.nextTick();
// Add connections of active node to newly created one // Add connections of active node to newly created one
let connections = this.$store.getters.connectionsByNodeName( let connections = this.$store.getters.outgoingConnectionsByNodeName(
lastSelectedNode.name, lastSelectedNode.name,
); );
connections = JSON.parse(JSON.stringify(connections)); connections = JSON.parse(JSON.stringify(connections));
@ -1317,6 +1316,7 @@ export default mixins(
[ [
'Arrow', 'Arrow',
{ {
id: 'endpoint-arrow',
location: 1, location: 1,
width: 12, width: 12,
foldback: 1, foldback: 1,
@ -1366,12 +1366,15 @@ export default mixins(
info.connection.addOverlay([ info.connection.addOverlay([
'Arrow', 'Arrow',
{ {
id: 'endpoint-arrow',
location: 1, location: 1,
width: 12, width: 12,
foldback: 1, foldback: 1,
length: 10, length: 10,
}, },
]); ]);
addOrRemoveMidpointArrow(info.connection);
// @ts-ignore // @ts-ignore
const sourceInfo = info.sourceEndpoint.getParameters(); const sourceInfo = info.sourceEndpoint.getParameters();
// @ts-ignore // @ts-ignore
@ -1383,19 +1386,6 @@ export default mixins(
const sourceNode = this.$store.getters.nodeByName(sourceNodeName); const sourceNode = this.$store.getters.nodeByName(sourceNodeName);
const targetNode = this.$store.getters.nodeByName(targetNodeName); const targetNode = this.$store.getters.nodeByName(targetNodeName);
// TODO: That should happen after each move (only the setConnector part)
if (info.sourceEndpoint.anchor.lastReturnValue[0] >= info.targetEndpoint.anchor.lastReturnValue[0]) {
info.connection.addOverlay([
'Arrow',
{
location: 0.5,
width: 12,
foldback: 1,
length: 10,
},
]);
}
// @ts-ignore // @ts-ignore
info.connection.removeOverlay('drop-add-node'); info.connection.removeOverlay('drop-add-node');
@ -1739,6 +1729,22 @@ export default mixins(
this.nodeSelectedByName(newNodeData.name, true); this.nodeSelectedByName(newNodeData.name, true);
}); });
}, },
onNodeMoved (node: INodeUi) {
const name = `${NODE_NAME_PREFIX}${this.$store.getters.getNodeIndex(node.name)}`;
// @ts-ignore
const outgoing = this.instance.getConnections({
source: name,
}) as Connection[];
// @ts-ignore
const incoming = this.instance.getConnections({
target: name,
}) as Connection[];
[...incoming, ...outgoing].forEach((connection: Connection) => {
addOrRemoveMidpointArrow(connection);
});
},
removeNode (nodeName: string) { removeNode (nodeName: string) {
if (this.editAllowedCheck() === false) { if (this.editAllowedCheck() === false) {
return; return;
@ -2101,7 +2107,7 @@ export default mixins(
typeConnections: INodeConnections; typeConnections: INodeConnections;
data.nodes.forEach((node) => { data.nodes.forEach((node) => {
connections = this.$store.getters.connectionsByNodeName(node.name); connections = this.$store.getters.outgoingConnectionsByNodeName(node.name);
if (Object.keys(connections).length === 0) { if (Object.keys(connections).length === 0) {
return; return;
} }

View file

@ -1,4 +1,5 @@
import { INodeUi, IZoomConfig } from "@/Interface"; import { INodeUi, IZoomConfig } from "@/Interface";
import { Connection } from "jsplumb";
interface ICorners { interface ICorners {
minX: number; minX: number;
@ -83,3 +84,34 @@ export const scaleReset = (config: IZoomConfig): IZoomConfig => {
return config; return config;
}; };
export const addOrRemoveMidpointArrow = (connection: Connection) => {
const sourceEndpoint = connection.endpoints[0];
const targetEndpoint = connection.endpoints[1];
const requiresArrow = sourceEndpoint.anchor.lastReturnValue[0] >= targetEndpoint.anchor.lastReturnValue[0];
const hasArrow = !!connection.getOverlay('midpoint-arrow');
if (!requiresArrow) {
if (hasArrow) {
connection.removeOverlay('midpoint-arrow');
}
return;
}
if (hasArrow) {
return;
}
connection.addOverlay([
'Arrow',
{
id: 'midpoint-arrow',
location: 0.5,
width: 12,
foldback: 1,
length: 10,
},
]);
};