@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.
- package/dist/modeler.common.js +450 -247
- package/dist/modeler.common.js.map +1 -1
- package/dist/modeler.umd.js +450 -247
- package/dist/modeler.umd.js.map +1 -1
- package/dist/modeler.umd.min.js +4 -4
- package/dist/modeler.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/modeler/Modeler.vue +12 -0
- package/src/components/modeler/NodeMigrator.js +15 -6
- package/src/components/modeler/Selection.vue +39 -29
- package/src/components/nodes/poolLane/index.js +9 -0
- package/src/components/nodes/subProcess/index.js +12 -4
- package/src/components/topRail/multiplayerViewUsers/MultiplayerViewUsers.vue +7 -1
- package/src/components/topRail/multiplayerViewUsers/avatar/Avatar.vue +11 -5
- package/src/multiplayer/inspector.utils.js +99 -0
- package/src/multiplayer/multiplayer.js +141 -139
|
@@ -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:
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
)
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
618
|
-
|
|
581
|
+
node = this.getNodeById(data.id);
|
|
582
|
+
if (!node) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
619
585
|
|
|
620
|
-
|
|
586
|
+
const { extras = {} } = data;
|
|
587
|
+
const { definition } = node;
|
|
621
588
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
589
|
+
if (data.loopCharacteristics) {
|
|
590
|
+
this.inspector.handleLoopCharacteristics(node, data.loopCharacteristics);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
625
593
|
|
|
626
|
-
|
|
627
|
-
|
|
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
|
-
|
|
631
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|