@processmaker/modeler 1.39.17 → 1.39.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/modeler.common.js +1717 -1211
  2. package/dist/modeler.common.js.map +1 -1
  3. package/dist/modeler.umd.js +1717 -1211
  4. package/dist/modeler.umd.js.map +1 -1
  5. package/dist/modeler.umd.min.js +4 -4
  6. package/dist/modeler.umd.min.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/components/crown/utils.js +10 -9
  9. package/src/components/modeler/Modeler.vue +94 -27
  10. package/src/components/modeler/Selection.vue +42 -15
  11. package/src/components/nodes/association/AssociationFlow.js +27 -0
  12. package/src/components/nodes/association/associationConfig.js +15 -0
  13. package/src/components/nodes/association/index.js +19 -12
  14. package/src/components/nodes/dataInputAssociation/DataInputAssociation.js +30 -0
  15. package/src/components/nodes/dataInputAssociation/index.js +17 -0
  16. package/src/components/nodes/dataOutputAssociation/index.js +15 -0
  17. package/src/components/nodes/genericFlow/DataOutputAssociation.js +1 -1
  18. package/src/components/nodes/genericFlow/genericFlow.vue +0 -10
  19. package/src/components/nodes/messageFlow/index.js +16 -0
  20. package/src/components/nodes/pool/pool.vue +40 -10
  21. package/src/components/nodes/poolLane/index.js +36 -0
  22. package/src/components/nodes/sequenceFlow/index.js +15 -0
  23. package/src/components/topRail/multiplayerViewUsers/MultiplayerViewUsers.vue +1 -1
  24. package/src/mixins/cloneSelection.js +1 -1
  25. package/src/mixins/linkConfig.js +35 -17
  26. package/src/mixins/poolLaneCrownConfig.js +0 -2
  27. package/src/multiplayer/multiplayer.js +139 -80
  28. package/src/nodeTypesStore.js +3 -3
  29. package/src/setup/globals.js +6 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.39.17",
3
+ "version": "1.39.19",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve --mode development",
6
6
  "test:unit": "vue-cli-service test:unit",
@@ -62,15 +62,16 @@ export function removeNodeAssociations(node, modeler) {
62
62
 
63
63
  export function removeBoundaryEvents(graph, node, removeNode) {
64
64
  const nodeShape = graph.getCells().find(el => el.component && el.component.node === node);
65
-
66
- nodeShape.getEmbeddedCells({ deep: true })
67
- .filter(cell => {
68
- return cell.component && cell.component.node.isBpmnType('bpmn:BoundaryEvent');
69
- })
70
- .forEach(boundaryEventShape => {
71
- graph.getConnectedLinks(boundaryEventShape).forEach(shape => removeNode(shape.component.node));
72
- removeNode(boundaryEventShape.component.node);
73
- });
65
+ if (nodeShape) {
66
+ nodeShape.getEmbeddedCells({ deep: true })
67
+ .filter(cell => {
68
+ return cell.component && cell.component.node.isBpmnType('bpmn:BoundaryEvent');
69
+ })
70
+ .forEach(boundaryEventShape => {
71
+ graph.getConnectedLinks(boundaryEventShape).forEach(shape => removeNode(shape.component.node));
72
+ removeNode(boundaryEventShape.component.node);
73
+ });
74
+ }
74
75
  }
75
76
 
76
77
  export function removeOutgoingAndIncomingRefsToFlow(node){
@@ -189,7 +189,7 @@ import getValidationProperties from '@/targetValidationUtils';
189
189
  import { id as laneId } from '@/components/nodes/poolLane/config';
190
190
  import { id as processId } from '@/components/inspectors/process';
191
191
  import { id as sequenceFlowId } from '../nodes/sequenceFlow';
192
- import { id as associationId } from '../nodes/association';
192
+ import { id as associationId } from '../nodes/association/associationConfig';
193
193
  import { id as messageFlowId } from '../nodes/messageFlow/config';
194
194
  import { id as dataOutputAssociationFlowId } from '../nodes/dataOutputAssociation/config';
195
195
  import { id as dataInputAssociationFlowId } from '../nodes/dataInputAssociation/config';
@@ -332,6 +332,13 @@ export default {
332
332
  previewConfigs: [],
333
333
  multiplayer: null,
334
334
  isMultiplayer: false,
335
+ flowTypes: [
336
+ 'processmaker-modeler-sequence-flow',
337
+ 'processmaker-modeler-message-flow',
338
+ 'processmaker-modeler-data-input-association',
339
+ 'processmaker-modeler-data-output-association',
340
+ 'processmaker-modeler-association',
341
+ ],
335
342
  };
336
343
  },
337
344
  watch: {
@@ -529,6 +536,10 @@ export default {
529
536
  return this.paper.findViewByModel(shape);
530
537
  });
531
538
  },
539
+ getElementByNodeId(id) {
540
+ const cells = this.paper.model.getCells();
541
+ return cells.find((cell) => cell.component && cell.component.id === id);
542
+ },
532
543
  async close() {
533
544
  this.$emit('close');
534
545
  },
@@ -1035,21 +1046,22 @@ export default {
1035
1046
  control,
1036
1047
  });
1037
1048
  },
1038
- handleDrop(data) {
1039
- const { clientX, clientY, control } = data;
1040
- if (this.isMultiplayer) {
1041
- window.ProcessMaker.EventBus.$emit('multiplayer-addNode', {
1042
- clientX,
1043
- clientY,
1044
- control,
1045
- id: `node_${this.nodeIdGenerator.getDefinitionNumber()}`,
1046
- });
1047
- } else {
1048
- this.handleDropProcedure(data);
1049
+ async addRemoteNode(data){
1050
+ const definition = this.nodeRegistry[data.type].definition(this.moddle, this.$t);
1051
+ const diagram = this.nodeRegistry[data.type].diagram(this.moddle);
1052
+ diagram.bounds.x = data.x;
1053
+ diagram.bounds.y = data.y;
1054
+ const newNode = this.createNode(data.type, definition, diagram);
1055
+ await this.addNode(newNode, data.id, true);
1056
+ await this.$nextTick();
1057
+ await this.paperManager.awaitScheduledUpdates();
1058
+ if (this.autoValidate) {
1059
+ this.validateBpmnDiagram();
1049
1060
  }
1050
1061
  },
1051
- async handleDropProcedure(data, selected=true) {
1052
- const { clientX, clientY, control, nodeThatWillBeReplaced, id } = data;
1062
+
1063
+ async handleDrop(data) {
1064
+ const { clientX, clientY, control, nodeThatWillBeReplaced } = data;
1053
1065
  this.validateDropTarget({ clientX, clientY, control });
1054
1066
  if (!this.allowDrop) {
1055
1067
  return;
@@ -1068,11 +1080,10 @@ export default {
1068
1080
  if (newNode.isBpmnType('bpmn:BoundaryEvent')) {
1069
1081
  this.setShapeCenterUnderCursor(diagram);
1070
1082
  }
1071
- if (selected) {
1072
- this.highlightNode(newNode);
1073
- }
1074
1083
 
1075
- await this.addNode(newNode, id, selected);
1084
+ this.highlightNode(newNode);
1085
+
1086
+ await this.addNode(newNode);
1076
1087
  if (!nodeThatWillBeReplaced) {
1077
1088
  return;
1078
1089
  }
@@ -1101,7 +1112,58 @@ export default {
1101
1112
  const view = newNodeComponent.shapeView;
1102
1113
  await this.$refs.selector.selectElement(view);
1103
1114
  },
1104
- async addNode(node, id = null, selected = true) {
1115
+ multiplayerHook(node, fromClient) {
1116
+ const blackList = [
1117
+ 'processmaker-modeler-lane',
1118
+ 'processmaker-modeler-generic-flow',
1119
+ 'processmaker-modeler-sequence-flow',
1120
+ 'processmaker-modeler-association',
1121
+ 'processmaker-modeler-data-input-association',
1122
+ 'processmaker-modeler-data-output-association',
1123
+ ];
1124
+
1125
+ if (!this.isMultiplayer) {
1126
+ return;
1127
+ }
1128
+
1129
+ if (!fromClient) {
1130
+ if (!blackList.includes(node.type) && !this.flowTypes.includes(node.type)) {
1131
+ const defaultData = {
1132
+ x: node.diagram.bounds.x,
1133
+ y: node.diagram.bounds.y,
1134
+ height: node.diagram.bounds.height,
1135
+ width: node.diagram.bounds.width,
1136
+ type: node.type,
1137
+ id: node.definition.id,
1138
+ isAddingLaneAbove: true,
1139
+ };
1140
+ if (node?.pool?.component) {
1141
+ defaultData['poolId'] = node.pool.component.id;
1142
+ }
1143
+ window.ProcessMaker.EventBus.$emit('multiplayer-addNode', defaultData);
1144
+ }
1145
+ if (this.flowTypes.includes(node.type)) {
1146
+ let sourceRefId = node.definition.sourceRef?.id;
1147
+ let targetRefId = node.definition.targetRef?.id;
1148
+
1149
+ if (node.type === 'processmaker-modeler-data-input-association') {
1150
+ sourceRefId = Array.isArray(node.definition.sourceRef) && node.definition.sourceRef[0]?.id;
1151
+ targetRefId = node.definition.targetRef?.$parent?.$parent.get('id');
1152
+ }
1153
+
1154
+ if (sourceRefId && targetRefId) {
1155
+ window.ProcessMaker.EventBus.$emit('multiplayer-addFlow', {
1156
+ id: node.definition.id,
1157
+ type: node.type,
1158
+ sourceRefId,
1159
+ targetRefId,
1160
+ waypoint: node.diagram.waypoint,
1161
+ });
1162
+ }
1163
+ }
1164
+ }
1165
+ },
1166
+ async addNode(node, id = null, fromClient = false) {
1105
1167
  if (!node.pool) {
1106
1168
  node.pool = this.poolTarget;
1107
1169
  }
@@ -1111,6 +1173,9 @@ export default {
1111
1173
  node.setIds(this.nodeIdGenerator, id);
1112
1174
 
1113
1175
  this.planeElements.push(node.diagram);
1176
+ // add multiplayer logic as a hook
1177
+ this.multiplayerHook(node, fromClient);
1178
+
1114
1179
  store.commit('addNode', node);
1115
1180
  this.poolTarget = null;
1116
1181
 
@@ -1126,7 +1191,7 @@ export default {
1126
1191
  ].includes(node.type)) {
1127
1192
  return;
1128
1193
  }
1129
- if (selected) {
1194
+ if (!fromClient) {
1130
1195
  // Select the node after it has been added to the store (does not apply to flows)
1131
1196
  this.selectNewNode(node);
1132
1197
  }
@@ -1148,6 +1213,7 @@ export default {
1148
1213
  addNodeToProcess(node, targetProcess);
1149
1214
 
1150
1215
  this.planeElements.push(node.diagram);
1216
+ this.multiplayerHook(node, false);
1151
1217
  store.commit('addNode', node);
1152
1218
  this.poolTarget = null;
1153
1219
  });
@@ -1207,10 +1273,10 @@ export default {
1207
1273
  replaceNode({ node, typeToReplaceWith }) {
1208
1274
  this.performSingleUndoRedoTransaction(async() => {
1209
1275
  await this.paperManager.performAtomicAction(async() => {
1210
- const { x: clientX, y: clientY } = this.paper.localToClientPoint(node.diagram.bounds);
1276
+ const { x, y } = node.diagram.bounds;
1211
1277
 
1212
1278
  const nodeData = {
1213
- clientX, clientY,
1279
+ x, y,
1214
1280
  control: { type: typeToReplaceWith },
1215
1281
  nodeThatWillBeReplaced: node,
1216
1282
  };
@@ -1224,10 +1290,10 @@ export default {
1224
1290
  }).filter(Boolean);
1225
1291
  // If the new control is found, emit event to server to replace node
1226
1292
  if (newControl.length === 1) {
1227
- window.ProcessMaker.EventBus.$emit('multiplayer-replaceNode', { nodeData, newControl: newControl[0] });
1293
+ window.ProcessMaker.EventBus.$emit('multiplayer-replaceNode', { nodeData, newControl: newControl[0].type });
1228
1294
  }
1229
1295
  } else {
1230
- await this.replaceNodeProcedure(nodeData);
1296
+ await this.replaceNodeProcedure(nodeData, true);
1231
1297
  }
1232
1298
  });
1233
1299
  });
@@ -1240,7 +1306,7 @@ export default {
1240
1306
  data.clientY = clientY;
1241
1307
  }
1242
1308
 
1243
- const newNode = await this.handleDropProcedure(data);
1309
+ const newNode = await this.handleDrop(data);
1244
1310
 
1245
1311
  await this.removeNode(data.nodeThatWillBeReplaced, { removeRelationships: false, isReplaced });
1246
1312
  this.highlightNode(newNode);
@@ -1250,7 +1316,7 @@ export default {
1250
1316
  this.performSingleUndoRedoTransaction(async() => {
1251
1317
  await this.paperManager.performAtomicAction(async() => {
1252
1318
  const { x: clientX, y: clientY } = this.paper.localToClientPoint(node.diagram.bounds);
1253
- const newNode = await this.handleDropProcedure({
1319
+ const newNode = await this.handleDrop({
1254
1320
  clientX, clientY,
1255
1321
  control: { type: typeToReplaceWith },
1256
1322
  nodeThatWillBeReplaced: node,
@@ -1287,9 +1353,10 @@ export default {
1287
1353
  await this.paperManager.performAtomicAction(async() => {
1288
1354
  await this.highlightNode(null);
1289
1355
  await this.$nextTick();
1290
- await this.addNode(actualFlow);
1291
1356
  await store.commit('removeNode', genericFlow);
1292
1357
  await this.$nextTick();
1358
+ await this.addNode(actualFlow, genericFlow.definition.id);
1359
+ await this.$nextTick();
1293
1360
  await this.highlightNode(targetNode);
1294
1361
  });
1295
1362
  });
@@ -31,7 +31,7 @@ import { id as poolId } from '@/components/nodes/pool/config';
31
31
  import { id as laneId } from '@/components/nodes/poolLane/config';
32
32
  import { id as genericFlowId } from '@/components/nodes/genericFlow/config';
33
33
  import { id as sequenceFlowId } from '@/components/nodes/sequenceFlow';
34
- import { id as associationId } from '@/components/nodes/association';
34
+ import { id as associationId } from '@/components/nodes/association/associationConfig';
35
35
  import { id as messageFlowId } from '@/components/nodes/messageFlow/config';
36
36
  import { id as dataOutputAssociationFlowId } from '@/components/nodes/dataOutputAssociation/config';
37
37
  import { id as dataInputAssociationFlowId } from '@/components/nodes/dataInputAssociation/config';
@@ -577,29 +577,56 @@ export default {
577
577
  await this.paperManager.awaitScheduledUpdates();
578
578
  this.overPoolStopDrag();
579
579
  this.updateSelectionBox();
580
- if (this.isMultiplayer) {
581
- window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', this.getProperties());
580
+ if (this.isMultiplayer) {
581
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', this.getProperties(this.selected));
582
582
  }
583
-
584
-
585
583
  },
586
- getProperties() {
587
- const changed = [];
584
+
585
+ getProperties(shapes) {
586
+ let changed = [];
588
587
  const shapesToNotTranslate = [
589
588
  'PoolLane',
590
589
  'standard.Link',
591
590
  'processmaker.components.nodes.boundaryEvent.Shape',
592
591
  ];
593
- this.selected.filter(shape => !shapesToNotTranslate.includes(shape.model.get('type')))
592
+
593
+ shapes.filter(shape => !shapesToNotTranslate.includes(shape.model.get('type')))
594
594
  .forEach(shape => {
595
- changed.push({
596
- id: shape.model.component.node.definition.id,
597
- properties: {
598
- clientX: shape.model.get('position').x,
599
- clientY: shape.model.get('position').y,
600
- },
601
- });
595
+ if (shape.model.get('type') === 'processmaker.modeler.bpmn.pool') {
596
+ const children = shape.model.component.getElementsUnderArea(shape.model, this.graph);
597
+ changed = [...changed, ...this.getContainerProperties(children, changed)];
598
+ } else {
599
+ const { node } = shape.model.component;
600
+ const defaultData = {
601
+ id: node.definition.id,
602
+ properties: {
603
+ x: shape.model.get('position').x,
604
+ y: shape.model.get('position').y,
605
+ height: shape.model.get('size').height,
606
+ width: shape.model.get('size').width,
607
+ },
608
+ };
609
+ if (node?.pool?.component) {
610
+ defaultData['poolId'] = node.pool.component.id;
611
+ }
612
+ changed.push(defaultData);
613
+ }
614
+ });
615
+ return changed;
616
+ },
617
+ getContainerProperties(children) {
618
+ const changed = [];
619
+ children.forEach(model => {
620
+ changed.push({
621
+ id: model.component.node.definition.id,
622
+ properties: {
623
+ x: model.get('position').x,
624
+ y: model.get('position').y,
625
+ height: model.get('size').height,
626
+ width: model.get('size').width,
627
+ },
602
628
  });
629
+ });
603
630
  return changed;
604
631
  },
605
632
  /**
@@ -0,0 +1,27 @@
1
+ import Node from '@/components/nodes/node';
2
+ import * as associationConfig from './associationConfig';
3
+
4
+ export class AssociationFlow {
5
+ constructor(nodeRegistry, moddle, paper) {
6
+ this.nodeRegistry = nodeRegistry;
7
+ this.moddle = moddle;
8
+ this.paper = paper;
9
+ }
10
+
11
+ makeFlowNode(sourceShape, targetShape, waypoint) {
12
+ const diagram = associationConfig.diagram(this.moddle);
13
+ const associationFlow = associationConfig.definition(this.moddle);
14
+
15
+ associationFlow.set('sourceRef', sourceShape.component.node.definition);
16
+ associationFlow.set('targetRef', targetShape.component.node.definition);
17
+
18
+ diagram.waypoint = waypoint.map(point => this.moddle.create('dc:Point', point));
19
+
20
+ const node = new Node(
21
+ associationConfig.id,
22
+ associationFlow,
23
+ diagram,
24
+ );
25
+ return node;
26
+ }
27
+ }
@@ -1 +1,16 @@
1
+ export const id = 'processmaker-modeler-association';
2
+
3
+ export const bpmnType = 'bpmn:Association';
4
+
1
5
  export const direction = { none: 'None', one: 'One', both: 'Both' };
6
+
7
+ export function definition(moddle) {
8
+ return moddle.create(bpmnType, {
9
+ associationDirection: direction.none,
10
+ targetRef: { x: undefined, y: undefined },
11
+ });
12
+ }
13
+
14
+ export function diagram(moddle) {
15
+ return moddle.create('bpmndi:BPMNEdge');
16
+ }
@@ -1,22 +1,16 @@
1
+ import { getNodeIdGenerator } from '@/NodeIdGenerator';
1
2
  import component from './association.vue';
2
- import { direction } from './associationConfig';
3
+ import { id, bpmnType, direction, definition, diagram } from './associationConfig';
3
4
  import idConfigSettings from '@/components/inspectors/idConfigSettings';
4
-
5
- export const id = 'processmaker-modeler-association';
5
+ import { AssociationFlow } from './AssociationFlow';
6
6
 
7
7
  export default {
8
8
  id,
9
9
  component,
10
- bpmnType: 'bpmn:Association',
10
+ bpmnType,
11
11
  control: false,
12
- definition(moddle) {
13
- return moddle.create('bpmn:Association', {
14
- associationDirection: `${direction.none}`,
15
- });
16
- },
17
- diagram(moddle) {
18
- return moddle.create('bpmndi:BPMNEdge');
19
- },
12
+ definition,
13
+ diagram,
20
14
  inspectorConfig: [
21
15
  {
22
16
  name: 'Data Association',
@@ -53,4 +47,17 @@ export default {
53
47
  ],
54
48
  },
55
49
  ],
50
+ async multiplayerClient(modeler, data) {
51
+ const { paper } = modeler;
52
+ const sourceElem = modeler.getElementByNodeId(data.sourceRefId);
53
+ const targetElem = modeler.getElementByNodeId(data.targetRefId);
54
+ if (sourceElem && targetElem) {
55
+ const flow = new AssociationFlow(modeler.nodeRegistry, modeler.moddle, paper);
56
+ const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
57
+ // add Nodes
58
+ modeler.addNode(actualFlow, data.id, true);
59
+ const nodeIdIterator = getNodeIdGenerator(modeler.definitions);
60
+ nodeIdIterator.updateCounters();
61
+ }
62
+ },
56
63
  };
@@ -0,0 +1,30 @@
1
+ import Node from '@/components/nodes/node';
2
+ import * as associationConfig from './config';
3
+ import { getOrFindDataInput } from '@/components/crown/utils';
4
+
5
+ export class DataInputAssociation {
6
+ constructor(nodeRegistry, moddle, paper) {
7
+ this.nodeRegistry = nodeRegistry;
8
+ this.moddle = moddle;
9
+ this.paper = paper;
10
+ }
11
+
12
+ makeFlowNode(sourceShape, targetShape, waypoint) {
13
+ const diagram = associationConfig.diagram(this.moddle);
14
+ const associationFlow = associationConfig.definition(this.moddle);
15
+
16
+ // When saving the BPMN, if this is not an array the sourceRef is not stored
17
+ const dataInput = getOrFindDataInput(this.moddle, targetShape.component.node, sourceShape.component.node.definition);
18
+ associationFlow.set('targetRef', dataInput);
19
+ associationFlow.set('sourceRef', [sourceShape.component.node.definition]);
20
+
21
+ diagram.waypoint = waypoint.map(point => this.moddle.create('dc:Point', point));
22
+
23
+ const node = new Node(
24
+ associationConfig.id,
25
+ associationFlow,
26
+ diagram,
27
+ );
28
+ return node;
29
+ }
30
+ }
@@ -1,6 +1,8 @@
1
1
  import component from './dataInputAssociation.vue';
2
2
  import idConfigSettings from '@/components/inspectors/idConfigSettings';
3
3
  import * as config from './config';
4
+ import { DataInputAssociation } from './DataInputAssociation';
5
+ import { getNodeIdGenerator } from '@/NodeIdGenerator';
4
6
 
5
7
  export default {
6
8
  ...config,
@@ -29,4 +31,19 @@ export default {
29
31
  ],
30
32
  },
31
33
  ],
34
+ async multiplayerClient(modeler, data) {
35
+ const { paper } = modeler;
36
+ const sourceElem = modeler.getElementByNodeId(data.sourceRefId);
37
+ const targetElem = modeler.getElementByNodeId(data.targetRefId);
38
+ if (sourceElem && targetElem) {
39
+ const flow = new DataInputAssociation(modeler.nodeRegistry, modeler.moddle, paper);
40
+ const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
41
+
42
+ targetElem.component.node.definition.set('dataInputAssociations', [actualFlow.definition]);
43
+ // add Nodes
44
+ modeler.addNode(actualFlow, data.id, true);
45
+ const nodeIdIterator = getNodeIdGenerator(modeler.definitions);
46
+ nodeIdIterator.updateCounters();
47
+ }
48
+ },
32
49
  };
@@ -1,6 +1,8 @@
1
1
  import component from './dataOutputAssociation.vue';
2
2
  import idConfigSettings from '@/components/inspectors/idConfigSettings';
3
3
  import * as config from './config';
4
+ import { getNodeIdGenerator } from '@/NodeIdGenerator';
5
+ import DataOutputAssociation from '../genericFlow/DataOutputAssociation';
4
6
 
5
7
  export default {
6
8
  ...config,
@@ -29,4 +31,17 @@ export default {
29
31
  ],
30
32
  },
31
33
  ],
34
+ async multiplayerClient(modeler, data) {
35
+ const { paper } = modeler;
36
+ const sourceElem = modeler.getElementByNodeId(data.sourceRefId);
37
+ const targetElem = modeler.getElementByNodeId(data.targetRefId);
38
+ if (sourceElem && targetElem) {
39
+ const flow = new DataOutputAssociation(modeler.nodeRegistry, modeler.moddle, paper);
40
+ const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
41
+ // add Nodes
42
+ modeler.addNode(actualFlow, data.id, true);
43
+ const nodeIdIterator = getNodeIdGenerator(modeler.definitions);
44
+ nodeIdIterator.updateCounters();
45
+ }
46
+ },
32
47
  };
@@ -55,7 +55,7 @@ export default class DataOutputAssociation extends DataAssociation {
55
55
  const sourceIsDataObject = sourceNode.definition.$type === 'bpmn:DataObjectReference';
56
56
  const targetIsDataStore = targetNode.definition.$type === 'bpmn:DataStoreReference';
57
57
  const targetIsDataObject = targetNode.definition.$type === 'bpmn:DataObjectReference';
58
-
58
+
59
59
  if (sourceIsDataStore && dataStoreValidTargets.includes(targetType)) {
60
60
  return true;
61
61
  }
@@ -109,16 +109,6 @@ export default {
109
109
  const flow = new bpmnFlow.factory(this.nodeRegistry, this.moddle, this.paper);
110
110
  const genericLink = this.shape.findView(this.paper);
111
111
  const waypoint = [genericLink.sourceAnchor.toJSON(), genericLink.targetAnchor.toJSON()];
112
- // Multiplayer hook
113
- if (this.$parent.isMultiplayer) {
114
- window.ProcessMaker.EventBus.$emit('multiplayer-addFlow', {
115
- type: bpmnFlow.type,
116
- id: `node_${this.$parent.nodeIdGenerator.getDefinitionNumber()}`,
117
- sourceRefId: this.sourceNode.definition.id,
118
- targetRefId: this.targetNode.definition.id,
119
- waypoint,
120
- });
121
- }
122
112
 
123
113
  this.$emit('replace-generic-flow', {
124
114
  actualFlow: flow.makeFlowNode(this.sourceShape, this.target, waypoint),
@@ -2,6 +2,9 @@ import component from './messageFlow.vue';
2
2
  import nameConfigSettings from '@/components/inspectors/nameConfigSettings';
3
3
  import advancedAccordionConfig from '@/components/inspectors/advancedAccordionConfig';
4
4
  import documentationAccordionConfig from '@/components/inspectors/documentationAccordionConfig';
5
+ import { getNodeIdGenerator } from '@/NodeIdGenerator';
6
+ import MessageFlow from '@/components/nodes/genericFlow/MessageFlow';
7
+
5
8
  import { id } from '@/components/nodes/messageFlow/config';
6
9
 
7
10
  export default {
@@ -42,4 +45,17 @@ export default {
42
45
  ],
43
46
  },
44
47
  ],
48
+ async multiplayerClient(modeler, data) {
49
+ const { paper } = modeler;
50
+ const sourceElem = modeler.getElementByNodeId( data.sourceRefId);
51
+ const targetElem = modeler.getElementByNodeId( data.targetRefId);
52
+ if (sourceElem && targetElem) {
53
+ const flow = new MessageFlow(modeler.nodeRegistry, modeler.moddle, paper);
54
+ const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
55
+ // add Nodes
56
+ modeler.addNode(actualFlow, data.id, true);
57
+ const nodeIdereator = getNodeIdGenerator(modeler.definitions);
58
+ nodeIdereator.updateCounters();
59
+ }
60
+ },
45
61
  };
@@ -133,6 +133,31 @@ export default {
133
133
  pull(this.containingProcess.get('flowElements'), elementDefinition);
134
134
  toPool.component.containingProcess.get('flowElements').push(elementDefinition);
135
135
  },
136
+ moveElementRemote(element, toPool) {
137
+ const elementDefinition = element.component.node.definition;
138
+
139
+ if (this.laneSet) {
140
+ /* Remove references to the element from the current Lane */
141
+ const containingLane = this.laneSet.get('lanes').find(lane => {
142
+ return lane.get('flowNodeRef').includes(elementDefinition);
143
+ });
144
+
145
+ pull(containingLane.get('flowNodeRef'), elementDefinition);
146
+ }
147
+
148
+ /* Remove references to the element from the current process */
149
+ pull(this.containingProcess.get('flowElements'), elementDefinition);
150
+
151
+ element.component.node.pool = toPool;
152
+
153
+ this.shape.unembed(element);
154
+ toPool.component.shape.embed(element);
155
+ if (element.component.node.type !== laneId && toPool.component.laneSet) {
156
+ toPool.component.updateLaneChildren();
157
+ }
158
+ this.$emit('set-shape-stacking', element.component.shape);
159
+ },
160
+
136
161
  moveElement(element, toPool) {
137
162
  const elementDefinition = element.component.node.definition;
138
163
 
@@ -155,7 +180,7 @@ export default {
155
180
  this.shape.unembed(element);
156
181
  toPool.component.addToPool(element);
157
182
  },
158
- async addLane() {
183
+ async addLane(emitMultiplayer = true) {
159
184
  /* A Lane element must be contained in a LaneSet element.
160
185
  * Get the current laneSet element or create a new one. */
161
186
 
@@ -177,35 +202,40 @@ export default {
177
202
 
178
203
  lanes.push(this.pushNewLane());
179
204
 
180
- await Promise.all(lanes);
205
+ await Promise.all(lanes)
206
+ .then((val) => {
207
+ if (emitMultiplayer && this.$parent.isMultiplayer) {
208
+ window.ProcessMaker.EventBus.$emit('multiplayer-addLanes', val);
209
+ }
210
+ });
181
211
  this.$emit('set-shape-stacking', this.shape);
182
212
  this.graph.getLinks().forEach(link => {
183
213
  this.$emit('set-shape-stacking', link);
184
214
  });
185
215
  this.$emit('save-state');
186
216
  },
187
- createLaneSet() {
217
+ createLaneSet(id) {
188
218
  const laneSet = this.moddle.create('bpmn:LaneSet');
189
219
  this.laneSet = laneSet;
190
220
  const generator = this.nodeIdGenerator;
191
- const [laneSetId] = generator.generate();
221
+ const [laneSetId] = id ?? generator.generate();
192
222
  this.laneSet.set('id', laneSetId);
193
223
  this.containingProcess.get('laneSets').push(laneSet);
194
224
  },
195
- pushNewLane(definition = Lane.definition(this.moddle, this.$t)) {
225
+ async pushNewLane(definition = Lane.definition(this.moddle, this.$t)) {
196
226
  definition.set('color', this.node.definition.get('color'));
197
227
  this.$emit('set-pool-target', this.shape);
198
228
 
199
229
  const diagram = Lane.diagram(this.moddle);
200
230
  diagram.bounds.width = this.shape.getBBox().width;
201
-
202
- this.$emit('add-node', new Node(
231
+ const node = new Node(
203
232
  Lane.id,
204
233
  definition,
205
234
  diagram,
206
- ));
207
-
208
- return this.$nextTick();
235
+ );
236
+ this.$emit('add-node', node);
237
+ await this.$nextTick();
238
+ return node;
209
239
  },
210
240
  addToPool(element) {
211
241
  if (element.component.node.isBpmnType('bpmn:BoundaryEvent')) {