@processmaker/modeler 1.40.2 → 1.41.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 }) => {
@@ -359,52 +363,32 @@ export default class Multiplayer {
359
363
  const newPool = this.modeler.getElementByNodeId(data.poolId);
360
364
 
361
365
  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
- });
366
+ if ('waypoint' in data) {
367
+ this.updateMovedWaypoint(element, data);
392
368
  } else {
393
369
  const node = this.getNodeById(data.id);
394
370
  store.commit('updateNodeProp', { node, key: 'color', value: data.color });
395
371
  }
396
372
  } else {
373
+ // updata gateway default folow
374
+ this.updateGatewayDefaultFlow(element, data);
375
+ if (typeof element.resize === 'function' && data.width && data.height) {
376
+ element.resize(
377
+ /* Add labelWidth to ensure elements don't overlap with the pool label */
378
+ data.width,
379
+ data.height,
380
+ );
381
+ }
397
382
  // 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
-
383
+ if (data.x && data.y) {
384
+ element.set('position', { x: data.x, y: data.y });
385
+ }
386
+ // udpdate the element's color
387
+ if (data.color) {
388
+ const node = this.getNodeById(data.id);
389
+ store.commit('updateNodeProp', { node, key: 'color', value: data.color });
390
+ return;
391
+ }
408
392
  // boundary type
409
393
  if (element.component.node.definition.$type === 'bpmn:BoundaryEvent') {
410
394
  this.attachBoundaryEventToNode(element, data);
@@ -421,6 +405,53 @@ export default class Multiplayer {
421
405
  this.modeler.updateLasso();
422
406
  }
423
407
  }
408
+ /**
409
+ * Update default Flow property
410
+ * @param {Object} element
411
+ * @param {Object} data
412
+ */
413
+ updateGatewayDefaultFlow(element, data){
414
+ if (Object.hasOwn(data, 'default')) {
415
+ const node = this.getNodeById(data.default);
416
+ element.component.node.definition.set('default', node || null);
417
+ }
418
+ }
419
+ /**
420
+ * Update moved waypoint object
421
+ * @param {Object} element
422
+ * @param {Object} data
423
+ */
424
+ updateMovedWaypoint(element, data ) {
425
+ const { waypoint } = data;
426
+ const { paper } = this.modeler;
427
+ // Update the element's waypoints
428
+ // Get the source and target elements
429
+ const sourceElem = this.modeler.getElementByNodeId(data.sourceRefId);
430
+ const targetElem = this.modeler.getElementByNodeId(data.targetRefId);
431
+
432
+ let { 0: startWaypoint, [waypoint.length - 1]: endWaypoint } = waypoint;
433
+ // Update the element's waypoints
434
+ element.vertices(waypoint);
435
+ // update bpmn waypoints
436
+ element.component.node.diagram.waypoint = waypoint.map(point => this.modeler.moddle.create('dc:Point', point));
437
+ // Force Remount Flow
438
+ element.component.node._modelerId += '_replaced';
439
+ // Update the element's source anchor
440
+ element.source(sourceElem, {
441
+ anchor: () => {
442
+ return getDefaultAnchorPoint(this.getConnectionPoint(sourceElem, startWaypoint), sourceElem.findView(paper));
443
+ },
444
+ connectionPoint: { name: 'boundary' },
445
+ });
446
+
447
+ // Update the element's target anchor
448
+ element.target(targetElem, {
449
+ anchor: () => {
450
+ return getDefaultAnchorPoint(this.getConnectionPoint(targetElem, endWaypoint), targetElem.findView(paper));
451
+ },
452
+ connectionPoint: { name: 'boundary' },
453
+ });
454
+ }
424
455
  attachBoundaryEventToNode(element, data) {
425
456
  const node = this.getNodeById(data.attachedToRefId);
426
457
 
@@ -534,104 +565,48 @@ export default class Multiplayer {
534
565
  updateShapeFromInspector(data) {
535
566
  let node = null;
536
567
  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;
568
+ this.inspector.updateNodeId(data.oldNodeId, data.id);
543
569
  }
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
570
 
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
-
617
- if (key === 'eventTimerDefinition') {
618
- const { type, body } = value;
571
+ node = this.getNodeById(data.id);
572
+ if (!node) {
573
+ return;
574
+ }
619
575
 
620
- const eventDefinitions = setEventTimerDefinition(this.modeler.moddle, node, type, body);
576
+ const { extras = {} } = data;
577
+ const { definition } = node;
621
578
 
622
- key = 'eventDefinitions';
623
- value = eventDefinitions;
624
- }
579
+ if (data.loopCharacteristics) {
580
+ this.inspector.handleLoopCharacteristics(node, data.loopCharacteristics);
581
+ return;
582
+ }
625
583
 
626
- const specialProperties = [
627
- 'messageRef', 'signalRef', 'gatewayDirection', 'condition', 'allowedUsers', 'allowedGroups',
628
- ];
584
+ if (this.modeler.nodeRegistry[node.type]?.multiplayerInspectorHandler) {
585
+ this.modeler.nodeRegistry[node.type].multiplayerInspectorHandler(node, data, this.setNodeProp, this.modeler.moddle);
586
+ return;
587
+ }
629
588
 
630
- if (!specialProperties.includes(key)) {
631
- store.commit('updateNodeProp', { node, key, value });
632
- }
589
+ const keys = Object.keys(data).filter((key) => key !== 'id');
590
+ const key = keys[0];
591
+ const value = data[key];
592
+
593
+ if (key === 'condition') {
594
+ this.inspector.updateEventCondition(definition, value);
595
+ } else if (key === 'gatewayDirection') {
596
+ this.inspector.updateGatewayDirection(definition, value);
597
+ } else if (key === 'messageRef') {
598
+ this.inspector.updateMessageRef(node, value, extras);
599
+ } else if (key === 'signalRef') {
600
+ this.inspector.updateSignalRef(node, value, extras);
601
+ } else if (key === 'signalPayload') {
602
+ this.inspector.updateSignalPayload(node, value);
603
+ } else if (key === 'eventTimerDefinition') {
604
+ this.inspector.updateEventTimerDefinition(node, value);
605
+ } else if (!this.inspector.isSpecialProperty(key)) {
606
+ this.inspector.updateNodeProperty(node, key, value);
633
607
  }
634
608
  }
609
+
635
610
  /**
636
611
  * Update the shared document and emit socket sign to update the flows
637
612
  * @param {Object} data
@@ -661,27 +636,44 @@ export default class Multiplayer {
661
636
  const flow = this.getNodeById(data.id);
662
637
  if (flow && data.sourceRefId) {
663
638
  const sourceRef = this.getNodeById(data.sourceRefId);
664
- flow.definition.set('sourceRef', sourceRef.definition);
639
+
665
640
  const outgoing = sourceRef.definition.get('outgoing')
666
641
  .find((element) => element.id === flow.definition.id);
667
642
  if (!outgoing) {
668
643
  sourceRef.definition.get('outgoing').push(...[flow.definition]);
669
644
  }
645
+ flow.definition.set('sourceRef', sourceRef.definition);
670
646
  remount = true;
671
647
  }
672
648
  if (flow && data.targetRefId) {
673
649
  const targetRef = this.getNodeById(data.targetRefId);
674
- flow.definition.set('targetRef', targetRef.definition);
650
+
675
651
  const incoming = targetRef.definition.get('incoming')
676
652
  .find((element) => element.id === flow.definition.id);
677
653
  if (!incoming) {
678
654
  targetRef.definition.get('incoming').push(...[flow.definition]);
679
655
  }
656
+ flow.definition.set('targetRef', targetRef.definition);
680
657
  remount = true;
681
658
  }
659
+
660
+ // update moddle waypoints
661
+ this.refreshNodeWaypoint(this.modeler.getElementByNodeId(data.id));
682
662
  if (remount) {
683
663
  // Force Remount Flow
684
664
  flow._modelerId += '_replaced';
685
665
  }
686
666
  }
667
+ /**
668
+ * Refresh the node waypoint data
669
+ * @param {Object} element
670
+ */
671
+ refreshNodeWaypoint(element) {
672
+ const linkView = this.modeler.paper.findViewByModel(element);
673
+ const start = linkView.sourceAnchor;
674
+ const end = linkView.targetAnchor;
675
+ element.component.node.diagram.waypoint = [start,
676
+ ...element.component.shape.vertices(),
677
+ end].map(point => this.modeler.moddle.create('dc:Point', point));
678
+ }
687
679
  }