@processmaker/modeler 1.40.3 → 1.42.0

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.
@@ -4,8 +4,8 @@ import { getNodeIdGenerator } from '../NodeIdGenerator';
4
4
  import { getDefaultAnchorPoint } from '@/portsUtils';
5
5
  import Room from './room';
6
6
  import store from '@/store';
7
- import { setEventTimerDefinition } from '@/components/nodes/boundaryTimerEvent';
8
7
  import { getBoundaryEventData } from '@/components/nodes/boundaryEvent/boundaryEventUtils';
8
+ import { InspectorUtils } from './inspector.utils';
9
9
 
10
10
  export default class Multiplayer {
11
11
  clientIO = null;
@@ -14,6 +14,7 @@ export default class Multiplayer {
14
14
  modeler = null;
15
15
  #nodeIdGenerator = null;
16
16
  room = null;
17
+ inspector = null;
17
18
  deletedItem = null;
18
19
 
19
20
  constructor(modeler) {
@@ -30,6 +31,7 @@ export default class Multiplayer {
30
31
  // Get the room name from the process id
31
32
  const processId = window.ProcessMaker.modeler.process.uuid ?? window.ProcessMaker.modeler.process.id;
32
33
  this.room = new Room(`room-${processId}`);
34
+ this.inspector = new InspectorUtils(this.modeler, store);
33
35
 
34
36
  // Connect to websocket server
35
37
  this.clientIO = io(window.ProcessMaker.multiplayer.host, { transports: ['websocket', 'polling']});
@@ -59,8 +61,8 @@ export default class Multiplayer {
59
61
  const newPlayer = {
60
62
  id: client.id,
61
63
  name: client.name,
62
- color: '#FF6F61',
63
- avatar: client.avatar,
64
+ color: client.color,
65
+ avatar: client.avatar || null,
64
66
  top: 90,
65
67
  left: 80,
66
68
  };
@@ -165,7 +167,9 @@ export default class Multiplayer {
165
167
  });
166
168
 
167
169
  window.ProcessMaker.EventBus.$on('multiplayer-updateNodes', ( data ) => {
168
- this.updateNodes(data);
170
+ if (this.modeler.isMultiplayer) {
171
+ this.updateNodes(data);
172
+ }
169
173
  });
170
174
 
171
175
  window.ProcessMaker.EventBus.$on('multiplayer-replaceNode', ({ nodeData, newControl }) => {
@@ -199,13 +203,17 @@ export default class Multiplayer {
199
203
  * Sync the modeler nodes with the microservice
200
204
  * @param {String} clientId
201
205
  */
202
- syncLocalNodes(clientId){
206
+ syncLocalNodes(clientId) {
203
207
  // Get the process definition
204
208
  const nodes = this.modeler.nodes.map((node) => {
205
209
  if (node.definition.$type === 'bpmn:BoundaryEvent') {
206
210
  return getBoundaryEventData(node);
207
211
  }
208
212
 
213
+ if (node.definition.$type === 'bpmn:Lane') {
214
+ return this.prepareLaneData(node);
215
+ }
216
+
209
217
  return this.modeler.multiplayerHook(node, false, true);
210
218
  });
211
219
 
@@ -359,52 +367,32 @@ export default class Multiplayer {
359
367
  const newPool = this.modeler.getElementByNodeId(data.poolId);
360
368
 
361
369
  if (this.modeler.flowTypes.includes(data.type)) {
362
- const { waypoint } = data;
363
-
364
- if (waypoint) {
365
- // Update the element's waypoints
366
- // Get the source and target elements
367
- const sourceElem = this.modeler.getElementByNodeId(data.sourceRefId);
368
- const targetElem = this.modeler.getElementByNodeId(data.targetRefId);
369
-
370
- const startWaypoint = waypoint.shift();
371
- const endWaypoint = waypoint.pop();
372
-
373
- // Update the element's waypoints
374
- const newWaypoint = waypoint.map(point => this.modeler.moddle.create('dc:Point', point));
375
- element.set('vertices', newWaypoint);
376
-
377
- // Update the element's source anchor
378
- element.source(sourceElem, {
379
- anchor: () => {
380
- return getDefaultAnchorPoint(this.getConnectionPoint(sourceElem, startWaypoint), sourceElem.findView(paper));
381
- },
382
- connectionPoint: { name: 'boundary' },
383
- });
384
-
385
- // Update the element's target anchor
386
- element.target(targetElem, {
387
- anchor: () => {
388
- return getDefaultAnchorPoint(this.getConnectionPoint(targetElem, endWaypoint), targetElem.findView(paper));
389
- },
390
- connectionPoint: { name: 'boundary' },
391
- });
370
+ if ('waypoint' in data) {
371
+ this.updateMovedWaypoint(element, data);
392
372
  } else {
393
373
  const node = this.getNodeById(data.id);
394
374
  store.commit('updateNodeProp', { node, key: 'color', value: data.color });
395
375
  }
396
376
  } else {
377
+ // updata gateway default folow
378
+ this.updateGatewayDefaultFlow(element, data);
379
+ if (typeof element.resize === 'function' && data.width && data.height) {
380
+ element.resize(
381
+ /* Add labelWidth to ensure elements don't overlap with the pool label */
382
+ data.width,
383
+ data.height,
384
+ );
385
+ }
397
386
  // Update the element's position attribute
398
- element.resize(
399
- /* Add labelWidth to ensure elements don't overlap with the pool label */
400
- data.width,
401
- data.height,
402
- );
403
- element.set('position', { x: data.x, y: data.y });
404
-
405
- const node = this.getNodeById(data.id);
406
- store.commit('updateNodeProp', { node, key: 'color', value: data.color });
407
-
387
+ if (data.x && data.y) {
388
+ element.set('position', { x: data.x, y: data.y });
389
+ }
390
+ // udpdate the element's color
391
+ if (data.color) {
392
+ const node = this.getNodeById(data.id);
393
+ store.commit('updateNodeProp', { node, key: 'color', value: data.color });
394
+ return;
395
+ }
408
396
  // boundary type
409
397
  if (element.component.node.definition.$type === 'bpmn:BoundaryEvent') {
410
398
  this.attachBoundaryEventToNode(element, data);
@@ -421,6 +409,53 @@ export default class Multiplayer {
421
409
  this.modeler.updateLasso();
422
410
  }
423
411
  }
412
+ /**
413
+ * Update default Flow property
414
+ * @param {Object} element
415
+ * @param {Object} data
416
+ */
417
+ updateGatewayDefaultFlow(element, data){
418
+ if (Object.hasOwn(data, 'default')) {
419
+ const node = this.getNodeById(data.default);
420
+ element.component.node.definition.set('default', node || null);
421
+ }
422
+ }
423
+ /**
424
+ * Update moved waypoint object
425
+ * @param {Object} element
426
+ * @param {Object} data
427
+ */
428
+ updateMovedWaypoint(element, data ) {
429
+ const { waypoint } = data;
430
+ const { paper } = this.modeler;
431
+ // Update the element's waypoints
432
+ // Get the source and target elements
433
+ const sourceElem = this.modeler.getElementByNodeId(data.sourceRefId);
434
+ const targetElem = this.modeler.getElementByNodeId(data.targetRefId);
435
+
436
+ let { 0: startWaypoint, [waypoint.length - 1]: endWaypoint } = waypoint;
437
+ // Update the element's waypoints
438
+ element.vertices(waypoint);
439
+ // update bpmn waypoints
440
+ element.component.node.diagram.waypoint = waypoint.map(point => this.modeler.moddle.create('dc:Point', point));
441
+ // Force Remount Flow
442
+ element.component.node._modelerId += '_replaced';
443
+ // Update the element's source anchor
444
+ element.source(sourceElem, {
445
+ anchor: () => {
446
+ return getDefaultAnchorPoint(this.getConnectionPoint(sourceElem, startWaypoint), sourceElem.findView(paper));
447
+ },
448
+ connectionPoint: { name: 'boundary' },
449
+ });
450
+
451
+ // Update the element's target anchor
452
+ element.target(targetElem, {
453
+ anchor: () => {
454
+ return getDefaultAnchorPoint(this.getConnectionPoint(targetElem, endWaypoint), targetElem.findView(paper));
455
+ },
456
+ connectionPoint: { name: 'boundary' },
457
+ });
458
+ }
424
459
  attachBoundaryEventToNode(element, data) {
425
460
  const node = this.getNodeById(data.attachedToRefId);
426
461
 
@@ -453,7 +488,8 @@ export default class Multiplayer {
453
488
  }
454
489
  addLaneNodes(lanes) {
455
490
  const pool = this.getPool(lanes);
456
- window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [{
491
+
492
+ const defaultPoolData = {
457
493
  id: pool.component.node.definition.id,
458
494
  properties: {
459
495
  x: pool.component.node.diagram.bounds.x,
@@ -462,7 +498,10 @@ export default class Multiplayer {
462
498
  width: pool.component.node.diagram.bounds.width,
463
499
  isAddingLaneAbove: pool.isAddingLaneAbove,
464
500
  },
465
- }]);
501
+ };
502
+
503
+ window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [defaultPoolData]);
504
+
466
505
  this.yDoc.transact(() => {
467
506
  lanes.forEach((lane) => {
468
507
  const yMapNested = new Y.Map();
@@ -485,6 +524,8 @@ export default class Multiplayer {
485
524
  height: lane.diagram.bounds.height,
486
525
  poolId: lane.pool.component.node.definition.id,
487
526
  laneSetId: lane.pool.component.laneSet.id,
527
+ poolX: lane.pool.component.node.diagram.bounds.x,
528
+ poolY: lane.pool.component.node.diagram.bounds.y,
488
529
  };
489
530
  return data;
490
531
  }
@@ -534,104 +575,48 @@ export default class Multiplayer {
534
575
  updateShapeFromInspector(data) {
535
576
  let node = null;
536
577
  if (data.oldNodeId && data.oldNodeId !== data.id) {
537
- const index = this.getIndex(data.oldNodeId);
538
- const yNode = this.yArray.get(index);
539
- yNode.set('id', data.id);
540
- node = this.getNodeById(data.oldNodeId);
541
- store.commit('updateNodeProp', { node, key: 'id', value: data.id });
542
- return;
578
+ this.inspector.updateNodeId(data.oldNodeId, data.id);
543
579
  }
544
- // create a node
545
- node = this.getNodeById(data.id);
546
-
547
- if (node) {
548
- let extras = {};
549
- // extras property section
550
- if (data.extras && Object.keys(data.extras).length > 0) {
551
- extras = data.extras;
552
- }
553
- // loopCharacteristics property section
554
- if (data.loopCharacteristics) {
555
- const loopCharacteristics = JSON.parse(data.loopCharacteristics);
556
- this.modeler.nodeRegistry[node.type].loopCharacteristicsHandler({
557
- type: node.definition.type,
558
- '$loopCharactetistics': {
559
- id: data.id,
560
- loopCharacteristics,
561
- },
562
- }, node, this.setNodeProp, this.modeler.moddle, this.modeler.definitions, false);
563
- return;
564
- }
565
- if (this.modeler.nodeRegistry[node.type]?.multiplayerInspectorHandler) {
566
- this.modeler.nodeRegistry[node.type].multiplayerInspectorHandler(node, data,this.setNodeProp, this.modeler.moddle);
567
- return;
568
- }
569
- const keys = Object.keys(data).filter((key) => key !== 'id');
570
- let key = keys[0];
571
- let value = data[key];
572
-
573
- if (key === 'condition') {
574
- node.definition.get('eventDefinitions')[0].get('condition').body = value;
575
- }
576
-
577
- if (key === 'gatewayDirection') {
578
- node.definition.set('gatewayDirection', value);
579
- }
580
-
581
- if (key === 'messageRef') {
582
- let message = this.modeler.definitions.rootElements.find(element => element.id === value);
583
-
584
- if (!message) {
585
- message = this.modeler.moddle.create('bpmn:Message', {
586
- id: value,
587
- name: extras?.messageName || value,
588
- });
589
- this.modeler.definitions.rootElements.push(message);
590
- }
591
-
592
- node.definition.get('eventDefinitions')[0].messageRef = message;
593
-
594
- if (extras?.allowedUsers) {
595
- node.definition.set('allowedUsers', extras.allowedUsers);
596
- }
597
-
598
- if (extras?.allowedGroups) {
599
- node.definition.set('allowedGroups', extras.allowedGroups);
600
- }
601
- }
602
-
603
- if (key === 'signalRef') {
604
- let signal = this.modeler.definitions.rootElements.find(element => element.id === value);
605
-
606
- if (!signal) {
607
- signal = this.modeler.moddle.create('bpmn:Signal', {
608
- id: value,
609
- name: extras?.signalName || value,
610
- });
611
- this.modeler.definitions.rootElements.push(signal);
612
- }
613
-
614
- node.definition.get('eventDefinitions')[0].signalRef = signal;
615
- }
616
580
 
617
- if (key === 'eventTimerDefinition') {
618
- const { type, body } = value;
581
+ node = this.getNodeById(data.id);
582
+ if (!node) {
583
+ return;
584
+ }
619
585
 
620
- const eventDefinitions = setEventTimerDefinition(this.modeler.moddle, node, type, body);
586
+ const { extras = {} } = data;
587
+ const { definition } = node;
621
588
 
622
- key = 'eventDefinitions';
623
- value = eventDefinitions;
624
- }
589
+ if (data.loopCharacteristics) {
590
+ this.inspector.handleLoopCharacteristics(node, data.loopCharacteristics);
591
+ return;
592
+ }
625
593
 
626
- const specialProperties = [
627
- 'messageRef', 'signalRef', 'gatewayDirection', 'condition', 'allowedUsers', 'allowedGroups',
628
- ];
594
+ if (this.modeler.nodeRegistry[node.type]?.multiplayerInspectorHandler) {
595
+ this.modeler.nodeRegistry[node.type].multiplayerInspectorHandler(node, data, this.setNodeProp, this.modeler.moddle);
596
+ return;
597
+ }
629
598
 
630
- if (!specialProperties.includes(key)) {
631
- store.commit('updateNodeProp', { node, key, value });
632
- }
599
+ const keys = Object.keys(data).filter((key) => key !== 'id');
600
+ const key = keys[0];
601
+ const value = data[key];
602
+
603
+ if (key === 'condition') {
604
+ this.inspector.updateEventCondition(definition, value);
605
+ } else if (key === 'gatewayDirection') {
606
+ this.inspector.updateGatewayDirection(definition, value);
607
+ } else if (key === 'messageRef') {
608
+ this.inspector.updateMessageRef(node, value, extras);
609
+ } else if (key === 'signalRef') {
610
+ this.inspector.updateSignalRef(node, value, extras);
611
+ } else if (key === 'signalPayload') {
612
+ this.inspector.updateSignalPayload(node, value);
613
+ } else if (key === 'eventTimerDefinition') {
614
+ this.inspector.updateEventTimerDefinition(node, value);
615
+ } else if (!this.inspector.isSpecialProperty(key)) {
616
+ this.inspector.updateNodeProperty(node, key, value);
633
617
  }
634
618
  }
619
+
635
620
  /**
636
621
  * Update the shared document and emit socket sign to update the flows
637
622
  * @param {Object} data
@@ -661,27 +646,44 @@ export default class Multiplayer {
661
646
  const flow = this.getNodeById(data.id);
662
647
  if (flow && data.sourceRefId) {
663
648
  const sourceRef = this.getNodeById(data.sourceRefId);
664
- flow.definition.set('sourceRef', sourceRef.definition);
649
+
665
650
  const outgoing = sourceRef.definition.get('outgoing')
666
651
  .find((element) => element.id === flow.definition.id);
667
652
  if (!outgoing) {
668
653
  sourceRef.definition.get('outgoing').push(...[flow.definition]);
669
654
  }
655
+ flow.definition.set('sourceRef', sourceRef.definition);
670
656
  remount = true;
671
657
  }
672
658
  if (flow && data.targetRefId) {
673
659
  const targetRef = this.getNodeById(data.targetRefId);
674
- flow.definition.set('targetRef', targetRef.definition);
660
+
675
661
  const incoming = targetRef.definition.get('incoming')
676
662
  .find((element) => element.id === flow.definition.id);
677
663
  if (!incoming) {
678
664
  targetRef.definition.get('incoming').push(...[flow.definition]);
679
665
  }
666
+ flow.definition.set('targetRef', targetRef.definition);
680
667
  remount = true;
681
668
  }
669
+
670
+ // update moddle waypoints
671
+ this.refreshNodeWaypoint(this.modeler.getElementByNodeId(data.id));
682
672
  if (remount) {
683
673
  // Force Remount Flow
684
674
  flow._modelerId += '_replaced';
685
675
  }
686
676
  }
677
+ /**
678
+ * Refresh the node waypoint data
679
+ * @param {Object} element
680
+ */
681
+ refreshNodeWaypoint(element) {
682
+ const linkView = this.modeler.paper.findViewByModel(element);
683
+ const start = linkView.sourceAnchor;
684
+ const end = linkView.targetAnchor;
685
+ element.component.node.diagram.waypoint = [start,
686
+ ...element.component.shape.vertices(),
687
+ end].map(point => this.modeler.moddle.create('dc:Point', point));
688
+ }
687
689
  }