@processmaker/modeler 1.39.19 → 1.39.21

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.39.19",
3
+ "version": "1.39.21",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve --mode development",
6
6
  "test:unit": "vue-cli-service test:unit",
@@ -137,6 +137,20 @@ export default {
137
137
  store.commit('updateNodeProp', { node: this.node, key: 'color', value: color });
138
138
  Vue.set(this.node.definition, 'color', color);
139
139
  this.$emit('save-state');
140
+
141
+ const properties = {
142
+ id: this.node.definition.id,
143
+ properties: {
144
+ color: this.node.definition.color,
145
+ x: this.node.diagram.bounds.x,
146
+ y: this.node.diagram.bounds.y,
147
+ height: this.node.diagram.bounds.height,
148
+ width: this.node.diagram.bounds.width,
149
+ type: this.node.type,
150
+ id: this.node.definition.id,
151
+ },
152
+ };
153
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [properties]);
140
154
  },
141
155
  resetNodeColor() {
142
156
  store.commit('updateNodeProp', { node: this.node, key: 'color', value: undefined });
@@ -952,7 +952,25 @@ export default {
952
952
  },
953
953
  async createNodeAsync(type, definition, diagram) {
954
954
  const node = this.createNode(type, definition, diagram);
955
+ if (!this.isMultiplayer) {
956
+ store.commit('addNode', node);
957
+ }
958
+ else {
959
+ this.loadNodeForMultiplayer(node);
960
+ }
961
+ },
962
+ async loadNodeForMultiplayer(node) {
963
+ if (node.type === 'processmaker-modeler-lane') {
964
+ await this.addNode(node, node.definition.id, true);
965
+ this.nodeIdGenerator.updateCounters();
966
+ await this.$nextTick();
967
+ await this.paperManager.awaitScheduledUpdates();
968
+ window.ProcessMaker.EventBus.$emit('multiplayer-addLanes', [node]);
969
+ return;
970
+ }
971
+ this.multiplayerHook(node, false);
955
972
  store.commit('addNode', node);
973
+ this.poolTarget = null;
956
974
  },
957
975
  createNode(type, definition, diagram) {
958
976
  if (Node.isTimerType(type)) {
@@ -1112,7 +1130,7 @@ export default {
1112
1130
  const view = newNodeComponent.shapeView;
1113
1131
  await this.$refs.selector.selectElement(view);
1114
1132
  },
1115
- multiplayerHook(node, fromClient) {
1133
+ multiplayerHook(node, fromClient, isProcessRequested = false) {
1116
1134
  const blackList = [
1117
1135
  'processmaker-modeler-lane',
1118
1136
  'processmaker-modeler-generic-flow',
@@ -1136,10 +1154,16 @@ export default {
1136
1154
  type: node.type,
1137
1155
  id: node.definition.id,
1138
1156
  isAddingLaneAbove: true,
1157
+ color: node.color,
1139
1158
  };
1140
1159
  if (node?.pool?.component) {
1141
1160
  defaultData['poolId'] = node.pool.component.id;
1142
1161
  }
1162
+
1163
+ if (isProcessRequested) {
1164
+ return defaultData;
1165
+ }
1166
+
1143
1167
  window.ProcessMaker.EventBus.$emit('multiplayer-addNode', defaultData);
1144
1168
  }
1145
1169
  if (this.flowTypes.includes(node.type)) {
@@ -1148,17 +1172,23 @@ export default {
1148
1172
 
1149
1173
  if (node.type === 'processmaker-modeler-data-input-association') {
1150
1174
  sourceRefId = Array.isArray(node.definition.sourceRef) && node.definition.sourceRef[0]?.id;
1151
- targetRefId = node.definition.targetRef?.$parent?.$parent.get('id');
1175
+ targetRefId = node.definition.targetRef?.$parent?.$parent?.get('id');
1152
1176
  }
1153
1177
 
1154
1178
  if (sourceRefId && targetRefId) {
1155
- window.ProcessMaker.EventBus.$emit('multiplayer-addFlow', {
1179
+ const flowData = {
1156
1180
  id: node.definition.id,
1157
1181
  type: node.type,
1158
1182
  sourceRefId,
1159
1183
  targetRefId,
1160
1184
  waypoint: node.diagram.waypoint,
1161
- });
1185
+ };
1186
+
1187
+ if (isProcessRequested) {
1188
+ return flowData;
1189
+ }
1190
+
1191
+ window.ProcessMaker.EventBus.$emit('multiplayer-addFlow', flowData);
1162
1192
  }
1163
1193
  }
1164
1194
  }
@@ -1281,36 +1311,34 @@ export default {
1281
1311
  nodeThatWillBeReplaced: node,
1282
1312
  };
1283
1313
 
1284
- if (this.isMultiplayer) {
1285
- // Get all node types
1286
- const nodeTypes = nodeTypesStore.getters.getNodeTypes;
1287
- // Get the new control
1288
- const newControl = nodeTypes.flatMap(nodeType => {
1289
- return nodeType.items?.filter(item => item.type === typeToReplaceWith);
1290
- }).filter(Boolean);
1291
- // If the new control is found, emit event to server to replace node
1292
- if (newControl.length === 1) {
1293
- window.ProcessMaker.EventBus.$emit('multiplayer-replaceNode', { nodeData, newControl: newControl[0].type });
1294
- }
1295
- } else {
1296
- await this.replaceNodeProcedure(nodeData, true);
1297
- }
1314
+ await this.replaceNodeProcedure(nodeData);
1298
1315
  });
1299
1316
  });
1300
1317
  },
1301
1318
  async replaceNodeProcedure(data, isReplaced = false) {
1302
- if (isReplaced) {
1303
- // Get the clientX and clientY from the node that will be replaced
1304
- const { x: clientX, y: clientY } = this.paper.localToClientPoint(data.nodeThatWillBeReplaced.diagram.bounds);
1305
- data.clientX = clientX;
1306
- data.clientY = clientY;
1307
- }
1319
+ // Get the clientX and clientY from the node that will be replaced
1320
+ const { x: clientX, y: clientY } = this.paper.localToClientPoint(data.nodeThatWillBeReplaced.diagram.bounds);
1321
+ data.clientX = clientX;
1322
+ data.clientY = clientY;
1308
1323
 
1309
1324
  const newNode = await this.handleDrop(data);
1310
1325
 
1311
1326
  await this.removeNode(data.nodeThatWillBeReplaced, { removeRelationships: false, isReplaced });
1312
1327
  this.highlightNode(newNode);
1313
1328
  this.selectNewNode(newNode);
1329
+
1330
+ if (this.isMultiplayer && !isReplaced) {
1331
+ // Get all node types
1332
+ const nodeTypes = nodeTypesStore.getters.getNodeTypes;
1333
+ // Get the new control
1334
+ const newControl = nodeTypes.flatMap(nodeType => {
1335
+ return nodeType.items?.filter(item => item.type === data.typeToReplaceWith);
1336
+ }).filter(Boolean);
1337
+ // If the new control is found, emit event to server to replace node
1338
+ if (newControl.length === 1) {
1339
+ window.ProcessMaker.EventBus.$emit('multiplayer-replaceNode', { data, newControl: newControl[0].type });
1340
+ }
1341
+ }
1314
1342
  },
1315
1343
  replaceAiNode({ node, typeToReplaceWith, assetId, assetName, redirectTo }) {
1316
1344
  this.performSingleUndoRedoTransaction(async() => {
@@ -1727,6 +1755,7 @@ export default {
1727
1755
  try {
1728
1756
  const multiplayer = new Multiplayer(this);
1729
1757
  multiplayer.init();
1758
+ this.multiplayer = multiplayer;
1730
1759
  } catch (error) {
1731
1760
  console.warn('Could not initialize multiplayer', error);
1732
1761
  }
@@ -604,6 +604,7 @@ export default {
604
604
  y: shape.model.get('position').y,
605
605
  height: shape.model.get('size').height,
606
606
  width: shape.model.get('size').width,
607
+ color: shape.model.get('color'),
607
608
  },
608
609
  };
609
610
  if (node?.pool?.component) {
@@ -624,6 +625,7 @@ export default {
624
625
  y: model.get('position').y,
625
626
  height: model.get('size').height,
626
627
  width: model.get('size').width,
628
+ color: model.get('color'),
627
629
  },
628
630
  });
629
631
  });
@@ -3,7 +3,7 @@ import * as Y from 'yjs';
3
3
  import { getNodeIdGenerator } from '../NodeIdGenerator';
4
4
  import { getDefaultAnchorPoint } from '@/portsUtils';
5
5
  import Room from './room';
6
-
6
+ import store from '@/store';
7
7
  export default class Multiplayer {
8
8
  clientIO = null;
9
9
  yDoc = null;
@@ -66,6 +66,26 @@ export default class Multiplayer {
66
66
  this.modeler.enableMultiplayer(payload.isMultiplayer);
67
67
  });
68
68
 
69
+ this.clientIO.on('requestProcess', (payload) => {
70
+ const { firstClient, clientId } = payload;
71
+
72
+ // Check if the current client is the first client
73
+ if (firstClient.id === this.clientIO.id) {
74
+ // Get the process definition
75
+ const nodes = this.modeler.nodes.map((node) => this.modeler.multiplayerHook(node, false, true));
76
+
77
+ nodes.forEach((node) => {
78
+ const yMapNested = new Y.Map();
79
+ this.doTransact(yMapNested, node);
80
+ this.yArray.push([yMapNested]);
81
+ // Encode the state as an update and send it to the server
82
+ const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
83
+ // Send the update to the web socket server
84
+ this.clientIO.emit('createElement', { updateDoc: stateUpdate, clientId });
85
+ });
86
+ }
87
+ });
88
+
69
89
  // Listen for updates when a new element is added
70
90
  this.clientIO.on('createElement', async(payload) => {
71
91
  // Create the new element in the process
@@ -74,6 +94,16 @@ export default class Multiplayer {
74
94
  Y.applyUpdate(this.yDoc, new Uint8Array(payload.updateDoc));
75
95
  });
76
96
 
97
+ // Listen for updates when a new element is requested
98
+ this.clientIO.on('createRequestedElement', async(payload) => {
99
+ if (payload.clientId === this.clientIO.id) {
100
+ // Create the new element in the process
101
+ await this.createRemoteShape(payload.changes);
102
+ // Add the new element to the shared array
103
+ Y.applyUpdate(this.yDoc, new Uint8Array(payload.updateDoc));
104
+ }
105
+ });
106
+
77
107
  // Listen for updates when an element is removed
78
108
  this.clientIO.on('removeElement', (payload) => {
79
109
  payload.deletedNodes.forEach(nodeId => {
@@ -135,7 +165,7 @@ export default class Multiplayer {
135
165
  // Encode the state as an update and send it to the server
136
166
  const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
137
167
  // Send the update to the web socket server
138
- this.clientIO.emit('createElement', stateUpdate);
168
+ this.clientIO.emit('createElement', { updateDoc: stateUpdate });
139
169
  }
140
170
  createShape(value){
141
171
  if (this.modeler.nodeRegistry[value.type] && this.modeler.nodeRegistry[value.type].multiplayerClient) {
@@ -229,6 +259,7 @@ export default class Multiplayer {
229
259
  clientY,
230
260
  control: { type: updatedNode.type },
231
261
  nodeThatWillBeReplaced: node,
262
+ color: node.color,
232
263
  id: updatedNode.id,
233
264
  };
234
265
 
@@ -292,6 +323,10 @@ export default class Multiplayer {
292
323
  data.height,
293
324
  );
294
325
  element.set('position', { x: data.x, y: data.y });
326
+
327
+ const node = this.getNodeById(data.id);
328
+ store.commit('updateNodeProp', { node, key: 'color', value: data.color });
329
+
295
330
  // Trigger a rendering of the element on the paper
296
331
  await paper.findViewByModel(element).update();
297
332
  // validate if the parent pool was updated
@@ -310,7 +345,7 @@ export default class Multiplayer {
310
345
  // Encode the state as an update and send it to the server
311
346
  const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
312
347
  // Send the update to the web socket server
313
- this.clientIO.emit('createElement', stateUpdate);
348
+ this.clientIO.emit('createElement', { updateDoc: stateUpdate });
314
349
  this.#nodeIdGenerator.updateCounters();
315
350
  }
316
351
 
@@ -333,7 +368,7 @@ export default class Multiplayer {
333
368
  this.doTransact(yMapNested, data);
334
369
  this.yArray.push([yMapNested]);
335
370
  const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
336
- this.clientIO.emit('createElement', stateUpdate);
371
+ this.clientIO.emit('createElement', { updateDoc: stateUpdate });
337
372
  });
338
373
  });
339
374
  }