@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.
- package/dist/modeler.common.js +1717 -1211
- package/dist/modeler.common.js.map +1 -1
- package/dist/modeler.umd.js +1717 -1211
- 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/crown/utils.js +10 -9
- package/src/components/modeler/Modeler.vue +94 -27
- package/src/components/modeler/Selection.vue +42 -15
- package/src/components/nodes/association/AssociationFlow.js +27 -0
- package/src/components/nodes/association/associationConfig.js +15 -0
- package/src/components/nodes/association/index.js +19 -12
- package/src/components/nodes/dataInputAssociation/DataInputAssociation.js +30 -0
- package/src/components/nodes/dataInputAssociation/index.js +17 -0
- package/src/components/nodes/dataOutputAssociation/index.js +15 -0
- package/src/components/nodes/genericFlow/DataOutputAssociation.js +1 -1
- package/src/components/nodes/genericFlow/genericFlow.vue +0 -10
- package/src/components/nodes/messageFlow/index.js +16 -0
- package/src/components/nodes/pool/pool.vue +40 -10
- package/src/components/nodes/poolLane/index.js +36 -0
- package/src/components/nodes/sequenceFlow/index.js +15 -0
- package/src/components/topRail/multiplayerViewUsers/MultiplayerViewUsers.vue +1 -1
- package/src/mixins/cloneSelection.js +1 -1
- package/src/mixins/linkConfig.js +35 -17
- package/src/mixins/poolLaneCrownConfig.js +0 -2
- package/src/multiplayer/multiplayer.js +139 -80
- package/src/nodeTypesStore.js +3 -3
- package/src/setup/globals.js +6 -0
|
@@ -3,6 +3,9 @@ import nameConfigSettings from '@/components/inspectors/nameConfigSettings';
|
|
|
3
3
|
import advancedAccordionConfig from '@/components/inspectors/advancedAccordionConfig';
|
|
4
4
|
import documentationAccordionConfig from '@/components/inspectors/documentationAccordionConfig';
|
|
5
5
|
import { id } from '@/components/nodes/poolLane/config';
|
|
6
|
+
import Node from '@/components/nodes/node';
|
|
7
|
+
import { elementShouldHaveFlowNodeRef } from '@/components/nodes/pool/poolUtils';
|
|
8
|
+
import { getNodeIdGenerator } from '@/NodeIdGenerator';
|
|
6
9
|
|
|
7
10
|
export default {
|
|
8
11
|
id,
|
|
@@ -49,4 +52,37 @@ export default {
|
|
|
49
52
|
],
|
|
50
53
|
},
|
|
51
54
|
],
|
|
55
|
+
|
|
56
|
+
async multiplayerClient(modeler, data) {
|
|
57
|
+
const pool = modeler.getElementByNodeId(data.poolId);
|
|
58
|
+
const definition = modeler.moddle.create('bpmn:Lane', {
|
|
59
|
+
name: data.name,
|
|
60
|
+
});
|
|
61
|
+
if (!pool.component.laneSet && pool.component.createLaneSet) {
|
|
62
|
+
pool.component.createLaneSet([data.laneSetId]);
|
|
63
|
+
/* If there are currently elements in the pool, add them to the first lane */
|
|
64
|
+
pool.component.shape.getEmbeddedCells().filter(element => elementShouldHaveFlowNodeRef(element))
|
|
65
|
+
.forEach(element => {
|
|
66
|
+
definition.get('flowNodeRef').push(element.component.node.definition);
|
|
67
|
+
});
|
|
68
|
+
const nodeIdereator = getNodeIdGenerator(modeler.definitions);
|
|
69
|
+
nodeIdereator.updateCounters();
|
|
70
|
+
}
|
|
71
|
+
const diagram = modeler.moddle.create('bpmndi:BPMNShape', {
|
|
72
|
+
bounds: modeler.moddle.create('dc:Bounds', {
|
|
73
|
+
height: data.height,
|
|
74
|
+
width: data.width,
|
|
75
|
+
x: data.x,
|
|
76
|
+
y: data.y,
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
const node = new Node(
|
|
80
|
+
data.type,
|
|
81
|
+
definition,
|
|
82
|
+
diagram,
|
|
83
|
+
);
|
|
84
|
+
await modeler.addNode(node, data.id, true);
|
|
85
|
+
modeler.setShapeStacking(pool.component.shape);
|
|
86
|
+
|
|
87
|
+
},
|
|
52
88
|
};
|
|
@@ -2,6 +2,8 @@ import component from './sequenceFlow.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 SequenceFlow from '@/components/nodes/genericFlow/SequenceFlow';
|
|
5
7
|
|
|
6
8
|
export const id = 'processmaker-modeler-sequence-flow';
|
|
7
9
|
|
|
@@ -82,4 +84,17 @@ export default {
|
|
|
82
84
|
],
|
|
83
85
|
},
|
|
84
86
|
],
|
|
87
|
+
async multiplayerClient(modeler, data) {
|
|
88
|
+
const { paper } = modeler;
|
|
89
|
+
const sourceElem = modeler.getElementByNodeId(data.sourceRefId);
|
|
90
|
+
const targetElem = modeler.getElementByNodeId(data.targetRefId);
|
|
91
|
+
if (sourceElem && targetElem) {
|
|
92
|
+
const flow = new SequenceFlow(modeler.nodeRegistry, modeler.moddle, paper);
|
|
93
|
+
const actualFlow = flow.makeFlowNode(sourceElem, targetElem, data.waypoint);
|
|
94
|
+
// add Nodes
|
|
95
|
+
modeler.addNode(actualFlow, data.id, true);
|
|
96
|
+
const nodeIdereator = getNodeIdGenerator(modeler.definitions);
|
|
97
|
+
nodeIdereator.updateCounters();
|
|
98
|
+
}
|
|
99
|
+
},
|
|
85
100
|
};
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
filteredPlayers() {
|
|
24
24
|
const allPlayers = uniqBy(this.players, 'name');
|
|
25
25
|
return allPlayers.filter(player => {
|
|
26
|
-
return player.name.toLowerCase() !== window.ProcessMaker.user
|
|
26
|
+
return player.name.toLowerCase() !== window.ProcessMaker.user?.fullName.toLowerCase();
|
|
27
27
|
});
|
|
28
28
|
},
|
|
29
29
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { id as laneId } from '../components/nodes/poolLane/config';
|
|
2
2
|
import { id as sequenceFlowId } from '../components/nodes/sequenceFlow';
|
|
3
|
-
import { id as associationId } from '../components/nodes/association';
|
|
3
|
+
import { id as associationId } from '../components/nodes/association/associationConfig';
|
|
4
4
|
import { id as messageFlowId } from '../components/nodes/messageFlow/config';
|
|
5
5
|
import { id as dataOutputAssociationFlowId } from '../components/nodes/dataOutputAssociation/config';
|
|
6
6
|
import { id as dataInputAssociationFlowId } from '../components/nodes/dataInputAssociation/config';
|
package/src/mixins/linkConfig.js
CHANGED
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
props: ['highlighted', 'paper', 'paperManager', 'isCompleted', 'isIdle'],
|
|
24
24
|
data() {
|
|
25
25
|
return {
|
|
26
|
+
linkView: null,
|
|
26
27
|
sourceShape: null,
|
|
27
28
|
target: null,
|
|
28
29
|
listeningToMouseup: false,
|
|
@@ -163,6 +164,31 @@ export default {
|
|
|
163
164
|
this.updateWaypoints();
|
|
164
165
|
await this.$nextTick();
|
|
165
166
|
|
|
167
|
+
if (this.$parent.isMultiplayer && this.linkView) {
|
|
168
|
+
// update waypoints in multiplayer mode
|
|
169
|
+
const nodeType = this.linkView.model.component.node.type;
|
|
170
|
+
const sourceRefId = this.linkView.sourceView.model.component.node.definition.id;
|
|
171
|
+
const targetRefId = this.linkView.targetView.model.component.node.definition.id;
|
|
172
|
+
|
|
173
|
+
const changes = [
|
|
174
|
+
{
|
|
175
|
+
id: this.linkView.model.component.node.definition.id,
|
|
176
|
+
properties: {
|
|
177
|
+
type: nodeType,
|
|
178
|
+
waypoint: [
|
|
179
|
+
this.linkView.sourceAnchor.toJSON(),
|
|
180
|
+
...this.shape.vertices(),
|
|
181
|
+
this.linkView.targetAnchor.toJSON(),
|
|
182
|
+
],
|
|
183
|
+
sourceRefId,
|
|
184
|
+
targetRefId,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', changes);
|
|
190
|
+
}
|
|
191
|
+
|
|
166
192
|
this.listeningToMouseleave = true;
|
|
167
193
|
this.$emit('save-state');
|
|
168
194
|
}
|
|
@@ -174,14 +200,15 @@ export default {
|
|
|
174
200
|
* @param {Object} options
|
|
175
201
|
*/
|
|
176
202
|
async onChangeTargets(link, vertices, options){
|
|
177
|
-
if (options
|
|
203
|
+
if (options?.ui) {
|
|
178
204
|
await this.$nextTick();
|
|
179
205
|
await this.waitForUpdateWaypoints();
|
|
206
|
+
this.listeningToMouseleave = false;
|
|
180
207
|
await this.storeWaypoints();
|
|
181
208
|
}
|
|
182
209
|
},
|
|
183
210
|
async onChangeVertices(link, vertices, options){
|
|
184
|
-
if (options
|
|
211
|
+
if (options?.ui) {
|
|
185
212
|
this.updateWaypoints();
|
|
186
213
|
await this.$nextTick();
|
|
187
214
|
this.listeningToMouseleave = false;
|
|
@@ -189,9 +216,9 @@ export default {
|
|
|
189
216
|
}
|
|
190
217
|
},
|
|
191
218
|
updateWaypoints() {
|
|
192
|
-
|
|
193
|
-
const start = linkView.sourceAnchor;
|
|
194
|
-
const end = linkView.targetAnchor;
|
|
219
|
+
this.linkView = this.shape.findView(this.paper);
|
|
220
|
+
const start = this.linkView.sourceAnchor;
|
|
221
|
+
const end = this.linkView.targetAnchor;
|
|
195
222
|
|
|
196
223
|
this.node.diagram.waypoint = [start,
|
|
197
224
|
...this.shape.vertices(),
|
|
@@ -239,18 +266,9 @@ export default {
|
|
|
239
266
|
if (this.updateDefinitionLinks) {
|
|
240
267
|
this.updateDefinitionLinks();
|
|
241
268
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const waypoint = [genericLink.sourceAnchor.toJSON(), genericLink.targetAnchor.toJSON()];
|
|
246
|
-
window.ProcessMaker.EventBus.$emit('multiplayer-addFlow', {
|
|
247
|
-
type: this.shape.component.node.type,
|
|
248
|
-
id: `node_${this.$parent.nodeIdGenerator.getDefinitionNumber()}`,
|
|
249
|
-
sourceRefId: this.sourceNode.definition.id,
|
|
250
|
-
targetRefId: this.targetNode.definition.id,
|
|
251
|
-
waypoint,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
269
|
+
|
|
270
|
+
if (this.linkView && ['processmaker-modeler-association', 'processmaker-modeler-data-input-association'].includes(this.shape.component.node.type)) {
|
|
271
|
+
this.$parent.multiplayerHook(this.shape.component.node, false);
|
|
254
272
|
}
|
|
255
273
|
|
|
256
274
|
this.$emit('save-state');
|
|
@@ -14,7 +14,6 @@ export default {
|
|
|
14
14
|
].includes(this.node.type)) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
17
|
if (this.node.pool) {
|
|
19
18
|
if (!this.graph.getCell(this.node.pool)) {
|
|
20
19
|
this.node.pool = this.graph.getElements().find(element => {
|
|
@@ -27,7 +26,6 @@ export default {
|
|
|
27
26
|
if (this.isLane) {
|
|
28
27
|
this.configureLaneInParentPool();
|
|
29
28
|
}
|
|
30
|
-
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
33
31
|
|
|
@@ -1,28 +1,9 @@
|
|
|
1
1
|
import { io } from 'socket.io-client';
|
|
2
2
|
import * as Y from 'yjs';
|
|
3
3
|
import { getNodeIdGenerator } from '../NodeIdGenerator';
|
|
4
|
+
import { getDefaultAnchorPoint } from '@/portsUtils';
|
|
4
5
|
import Room from './room';
|
|
5
|
-
|
|
6
|
-
import SequenceFlow from '@/components/nodes/genericFlow/SequenceFlow';
|
|
7
|
-
import DataOutputAssociation from '@/components/nodes/genericFlow/DataOutputAssociation';
|
|
8
|
-
const BpmnFlows = [
|
|
9
|
-
{
|
|
10
|
-
type: 'processmaker-modeler-text-annotation',
|
|
11
|
-
factory: DataOutputAssociation,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
type: 'processmaker-modeler-sequence-flow',
|
|
15
|
-
factory: SequenceFlow,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
type: 'processmaker-modeler-message-flow',
|
|
19
|
-
factory: MessageFlow,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
type: 'processmaker-modeler-data-input-association',
|
|
23
|
-
factory: DataOutputAssociation,
|
|
24
|
-
},
|
|
25
|
-
];
|
|
6
|
+
|
|
26
7
|
export default class Multiplayer {
|
|
27
8
|
clientIO = null;
|
|
28
9
|
yDoc = null;
|
|
@@ -44,7 +25,8 @@ export default class Multiplayer {
|
|
|
44
25
|
// Get the node id generator
|
|
45
26
|
this.#nodeIdGenerator = getNodeIdGenerator(this.modeler.definitions);
|
|
46
27
|
// Get the room name from the process id
|
|
47
|
-
|
|
28
|
+
const processId = window.ProcessMaker.modeler.process.uuid ?? window.ProcessMaker.modeler.process.id;
|
|
29
|
+
this.room = new Room(`room-${processId}`);
|
|
48
30
|
|
|
49
31
|
// Connect to websocket server
|
|
50
32
|
this.clientIO = io(window.ProcessMaker.multiplayer.host, { transports: ['websocket', 'polling']});
|
|
@@ -53,8 +35,8 @@ export default class Multiplayer {
|
|
|
53
35
|
// Join the room
|
|
54
36
|
this.clientIO.emit('joinRoom', {
|
|
55
37
|
roomName: this.room.getRoom(),
|
|
56
|
-
clientName: window.ProcessMaker.user
|
|
57
|
-
clientAvatar: window.ProcessMaker.user
|
|
38
|
+
clientName: window.ProcessMaker.user?.fullName,
|
|
39
|
+
clientAvatar: window.ProcessMaker.user?.avatar,
|
|
58
40
|
});
|
|
59
41
|
});
|
|
60
42
|
|
|
@@ -140,12 +122,13 @@ export default class Multiplayer {
|
|
|
140
122
|
window.ProcessMaker.EventBus.$on('multiplayer-addFlow', ( data ) => {
|
|
141
123
|
this.addFlow(data);
|
|
142
124
|
});
|
|
125
|
+
|
|
126
|
+
window.ProcessMaker.EventBus.$on('multiplayer-addLanes', ( lanes ) => {
|
|
127
|
+
this.addLaneNodes(lanes);
|
|
128
|
+
});
|
|
143
129
|
}
|
|
144
130
|
addNode(data) {
|
|
145
|
-
// Add the new element to the process
|
|
146
|
-
this.createShape(data);
|
|
147
131
|
// Add the new element to the shared array
|
|
148
|
-
// this.yArray.push([data]);
|
|
149
132
|
const yMapNested = new Y.Map();
|
|
150
133
|
this.doTransact(yMapNested, data);
|
|
151
134
|
this.yArray.push([yMapNested]);
|
|
@@ -154,47 +137,45 @@ export default class Multiplayer {
|
|
|
154
137
|
// Send the update to the web socket server
|
|
155
138
|
this.clientIO.emit('createElement', stateUpdate);
|
|
156
139
|
}
|
|
157
|
-
createShape(value)
|
|
158
|
-
this.modeler.
|
|
140
|
+
createShape(value){
|
|
141
|
+
if (this.modeler.nodeRegistry[value.type] && this.modeler.nodeRegistry[value.type].multiplayerClient) {
|
|
142
|
+
this.modeler.nodeRegistry[value.type].multiplayerClient(this.modeler, value);
|
|
143
|
+
} else {
|
|
144
|
+
this.modeler.addRemoteNode(value);
|
|
145
|
+
}
|
|
159
146
|
this.#nodeIdGenerator.updateCounters();
|
|
147
|
+
|
|
160
148
|
}
|
|
161
149
|
createRemoteShape(changes) {
|
|
162
|
-
const flows = [
|
|
163
|
-
'processmaker-modeler-sequence-flow',
|
|
164
|
-
'processmaker-modeler-text-annotation',
|
|
165
|
-
'processmaker-modeler-message-flow',
|
|
166
|
-
'processmaker-modeler-data-input-association',
|
|
167
|
-
];
|
|
168
150
|
return new Promise(resolve => {
|
|
169
151
|
changes.map((data) => {
|
|
170
|
-
|
|
171
|
-
this.createFlow(data);
|
|
172
|
-
} else {
|
|
173
|
-
this.createShape(data);
|
|
174
|
-
}
|
|
152
|
+
this.createShape(data);
|
|
175
153
|
});
|
|
176
154
|
resolve();
|
|
177
155
|
});
|
|
178
156
|
}
|
|
179
157
|
removeNode(data) {
|
|
180
158
|
const index = this.getIndex(data.definition.id);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
159
|
+
if (index >= 0) {
|
|
160
|
+
this.removeShape(data);
|
|
161
|
+
this.yArray.delete(index, 1); // delete one element
|
|
162
|
+
// Encode the state as an update and send it to the server
|
|
163
|
+
const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
|
|
164
|
+
// Send the update to the web socket server
|
|
165
|
+
this.clientIO.emit('removeElement', stateUpdate);
|
|
166
|
+
}
|
|
188
167
|
}
|
|
189
168
|
getIndex(id) {
|
|
190
169
|
let index = -1;
|
|
170
|
+
let found = false;
|
|
191
171
|
for (const value of this.yArray) {
|
|
192
172
|
index ++;
|
|
193
173
|
if (value.get('id') === id) {
|
|
174
|
+
found = true;
|
|
194
175
|
break ;
|
|
195
176
|
}
|
|
196
177
|
}
|
|
197
|
-
return index;
|
|
178
|
+
return found ? index : -1;
|
|
198
179
|
}
|
|
199
180
|
getNodeById(nodeId) {
|
|
200
181
|
const node = this.modeler.nodes.find((element) => element.definition && element.definition.id === nodeId);
|
|
@@ -215,7 +196,8 @@ export default class Multiplayer {
|
|
|
215
196
|
data.forEach((value) => {
|
|
216
197
|
const index = this.getIndex(value.id);
|
|
217
198
|
const nodeToUpdate = this.yArray.get(index);
|
|
218
|
-
|
|
199
|
+
const updateData = value.poolId ? { ...value.properties, ...{ poolId: value.poolId } } : value.properties;
|
|
200
|
+
this.doTransact(nodeToUpdate, updateData);
|
|
219
201
|
});
|
|
220
202
|
}
|
|
221
203
|
replaceNode(nodeData, newControl) {
|
|
@@ -224,13 +206,11 @@ export default class Multiplayer {
|
|
|
224
206
|
const nodeToUpdate = this.yArray.get(index);
|
|
225
207
|
// Update the node id in the nodeData
|
|
226
208
|
nodeData.id = `node_${this.#nodeIdGenerator.getDefinitionNumber()}`;
|
|
227
|
-
// Replace the node in the process
|
|
228
|
-
this.modeler.replaceNodeProcedure(nodeData, true);
|
|
229
209
|
// Update the node id generator
|
|
230
210
|
this.#nodeIdGenerator.updateCounters();
|
|
231
211
|
// Update the node in the shared array
|
|
232
212
|
this.yDoc.transact(() => {
|
|
233
|
-
nodeToUpdate.set('
|
|
213
|
+
nodeToUpdate.set('type', newControl);
|
|
234
214
|
nodeToUpdate.set('id', nodeData.id);
|
|
235
215
|
});
|
|
236
216
|
|
|
@@ -240,13 +220,14 @@ export default class Multiplayer {
|
|
|
240
220
|
this.clientIO.emit('updateElement', { updateDoc: stateUpdate, isReplaced: true });
|
|
241
221
|
}
|
|
242
222
|
replaceShape(updatedNode) {
|
|
223
|
+
const { x: clientX, y: clientY } = this.modeler.paper.localToClientPoint(updatedNode);
|
|
243
224
|
// Get the node to update
|
|
244
225
|
const node = this.getNodeById(updatedNode.oldNodeId);
|
|
245
226
|
// Update the node id in the nodeData
|
|
246
227
|
const nodeData = {
|
|
247
|
-
clientX
|
|
248
|
-
clientY
|
|
249
|
-
control: { type: updatedNode.
|
|
228
|
+
clientX,
|
|
229
|
+
clientY,
|
|
230
|
+
control: { type: updatedNode.type },
|
|
250
231
|
nodeThatWillBeReplaced: node,
|
|
251
232
|
id: updatedNode.id,
|
|
252
233
|
};
|
|
@@ -269,23 +250,59 @@ export default class Multiplayer {
|
|
|
269
250
|
// Send the update to the web socket server
|
|
270
251
|
this.clientIO.emit('updateElement', { updateDoc: stateUpdate, isReplaced: false });
|
|
271
252
|
}
|
|
272
|
-
updateShapes(data) {
|
|
253
|
+
async updateShapes(data) {
|
|
273
254
|
const { paper } = this.modeler;
|
|
274
|
-
const element = this.
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
255
|
+
const element = this.modeler.getElementByNodeId(data.id);
|
|
256
|
+
const newPool = this.modeler.getElementByNodeId(data.poolId);
|
|
257
|
+
|
|
258
|
+
if (this.modeler.flowTypes.includes(data.type)) {
|
|
259
|
+
// Update the element's waypoints
|
|
260
|
+
// Get the source and target elements
|
|
261
|
+
const sourceElem = this.modeler.getElementByNodeId(data.sourceRefId);
|
|
262
|
+
const targetElem = this.modeler.getElementByNodeId(data.targetRefId);
|
|
263
|
+
|
|
264
|
+
const { waypoint } = data;
|
|
265
|
+
const startWaypoint = waypoint.shift();
|
|
266
|
+
const endWaypoint = waypoint.pop();
|
|
267
|
+
|
|
268
|
+
// Update the element's waypoints
|
|
269
|
+
const newWaypoint = waypoint.map(point => this.modeler.moddle.create('dc:Point', point));
|
|
270
|
+
element.set('vertices', newWaypoint);
|
|
271
|
+
|
|
272
|
+
// Update the element's source anchor
|
|
273
|
+
element.source(sourceElem, {
|
|
274
|
+
anchor: () => {
|
|
275
|
+
return getDefaultAnchorPoint(this.getConnectionPoint(sourceElem, startWaypoint), sourceElem.findView(paper));
|
|
276
|
+
},
|
|
277
|
+
connectionPoint: { name: 'boundary' },
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Update the element's target anchor
|
|
281
|
+
element.target(targetElem, {
|
|
282
|
+
anchor: () => {
|
|
283
|
+
return getDefaultAnchorPoint(this.getConnectionPoint(targetElem, endWaypoint), targetElem.findView(paper));
|
|
284
|
+
},
|
|
285
|
+
connectionPoint: { name: 'boundary' },
|
|
286
|
+
});
|
|
287
|
+
} else {
|
|
288
|
+
// Update the element's position attribute
|
|
289
|
+
element.resize(
|
|
290
|
+
/* Add labelWidth to ensure elements don't overlap with the pool label */
|
|
291
|
+
data.width,
|
|
292
|
+
data.height,
|
|
293
|
+
);
|
|
294
|
+
element.set('position', { x: data.x, y: data.y });
|
|
295
|
+
// Trigger a rendering of the element on the paper
|
|
296
|
+
await paper.findViewByModel(element).update();
|
|
297
|
+
// validate if the parent pool was updated
|
|
298
|
+
await element.component.$nextTick();
|
|
299
|
+
await this.modeler.paperManager.awaitScheduledUpdates();
|
|
300
|
+
if (newPool && element.component.node.pool && element.component.node.pool.component.id !== data.poolId) {
|
|
301
|
+
element.component.node.pool.component.moveElementRemote(element, newPool);
|
|
285
302
|
}
|
|
286
303
|
}
|
|
287
|
-
return null; // Return null if no matching element is found
|
|
288
304
|
}
|
|
305
|
+
|
|
289
306
|
addFlow(data) {
|
|
290
307
|
const yMapNested = new Y.Map();
|
|
291
308
|
this.doTransact(yMapNested, data);
|
|
@@ -296,20 +313,62 @@ export default class Multiplayer {
|
|
|
296
313
|
this.clientIO.emit('createElement', stateUpdate);
|
|
297
314
|
this.#nodeIdGenerator.updateCounters();
|
|
298
315
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
316
|
+
|
|
317
|
+
addLaneNodes(lanes) {
|
|
318
|
+
const pool = this.getPool(lanes);
|
|
319
|
+
window.ProcessMaker.EventBus.$emit('multiplayer-updateNodes', [{
|
|
320
|
+
id: pool.component.node.definition.id,
|
|
321
|
+
properties: {
|
|
322
|
+
x: pool.component.node.diagram.bounds.x,
|
|
323
|
+
y: pool.component.node.diagram.bounds.y,
|
|
324
|
+
height: pool.component.node.diagram.bounds.height,
|
|
325
|
+
width: pool.component.node.diagram.bounds.width,
|
|
326
|
+
isAddingLaneAbove: pool.isAddingLaneAbove,
|
|
327
|
+
},
|
|
328
|
+
}]);
|
|
329
|
+
this.yDoc.transact(() => {
|
|
330
|
+
lanes.forEach((lane) => {
|
|
331
|
+
const yMapNested = new Y.Map();
|
|
332
|
+
const data = this.prepareLaneData(lane);
|
|
333
|
+
this.doTransact(yMapNested, data);
|
|
334
|
+
this.yArray.push([yMapNested]);
|
|
335
|
+
const stateUpdate = Y.encodeStateAsUpdate(this.yDoc);
|
|
336
|
+
this.clientIO.emit('createElement', stateUpdate);
|
|
306
337
|
});
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
prepareLaneData(lane) {
|
|
341
|
+
const data = {
|
|
342
|
+
type: lane.type,
|
|
343
|
+
id: lane.definition.id,
|
|
344
|
+
name: lane.definition.name,
|
|
345
|
+
x: lane.diagram.bounds.x,
|
|
346
|
+
y: lane.diagram.bounds.y,
|
|
347
|
+
width: lane.diagram.bounds.width,
|
|
348
|
+
height: lane.diagram.bounds.height,
|
|
349
|
+
poolId: lane.pool.component.node.definition.id,
|
|
350
|
+
laneSetId: lane.pool.component.laneSet.id,
|
|
351
|
+
};
|
|
352
|
+
return data;
|
|
353
|
+
}
|
|
354
|
+
getPool(lanes) {
|
|
355
|
+
if (lanes && lanes.length > 0) {
|
|
356
|
+
return lanes[0].pool;
|
|
312
357
|
}
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
getConnectionPoint(element, newPosition) {
|
|
361
|
+
const { x: elemX, y: elemY } = element.position();
|
|
362
|
+
const connectionOffset = {
|
|
363
|
+
x: newPosition.x - elemX,
|
|
364
|
+
y: newPosition.y - elemY,
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const { x, y } = element.position();
|
|
368
|
+
const { width, height } = element.size();
|
|
313
369
|
|
|
370
|
+
return connectionOffset
|
|
371
|
+
? { x: x + connectionOffset.x, y: y + connectionOffset.y }
|
|
372
|
+
: { x: x + (width / 2), y: y + (height / 2) };
|
|
314
373
|
}
|
|
315
374
|
}
|
package/src/nodeTypesStore.js
CHANGED
|
@@ -114,7 +114,7 @@ export default new Vuex.Store({
|
|
|
114
114
|
},
|
|
115
115
|
actions: {
|
|
116
116
|
getUserPinnedObjects({ commit }) {
|
|
117
|
-
if (
|
|
117
|
+
if (window.ProcessMaker?.user?.id === 'standalone') {
|
|
118
118
|
// For standalone version of Modeler
|
|
119
119
|
const pinnedNodes = localStorage.pinnedNodes ? JSON.parse(localStorage.pinnedNodes) : [] ;
|
|
120
120
|
pinnedNodes.forEach(node => {
|
|
@@ -137,7 +137,7 @@ export default new Vuex.Store({
|
|
|
137
137
|
addUserPinnedObject({ commit, state }, pinnedNode) {
|
|
138
138
|
commit('setPinnedNodes', pinnedNode);
|
|
139
139
|
const pinnedNodes = state.pinnedNodeTypes;
|
|
140
|
-
if (
|
|
140
|
+
if (window.ProcessMaker?.user?.id === 'standalone') {
|
|
141
141
|
// For standalone version of Modeler
|
|
142
142
|
localStorage.pinnedNodes = JSON.stringify(pinnedNodes);
|
|
143
143
|
return;
|
|
@@ -152,7 +152,7 @@ export default new Vuex.Store({
|
|
|
152
152
|
removeUserPinnedObject({ commit, state }, nodeToUnpin) {
|
|
153
153
|
commit('setUnpinNode', nodeToUnpin);
|
|
154
154
|
const pinnedNodes = state.pinnedNodeTypes;
|
|
155
|
-
if (
|
|
155
|
+
if (window.ProcessMaker?.user?.id === 'standalone') {
|
|
156
156
|
// For standalone version of Modeler
|
|
157
157
|
localStorage.pinnedNodes = JSON.stringify(pinnedNodes);
|
|
158
158
|
return;
|
package/src/setup/globals.js
CHANGED
|
@@ -4,6 +4,7 @@ import MockAdapter from 'axios-mock-adapter';
|
|
|
4
4
|
import mockProcesses from './mockProcesses.json';
|
|
5
5
|
import mockSignals from './mockSignals.json';
|
|
6
6
|
import mockProcessSvg from './mockProcessSvg';
|
|
7
|
+
import { faker } from '@faker-js/faker';
|
|
7
8
|
|
|
8
9
|
axios.defaults.baseURL = 'https://bpm4.local.processmaker.com/api/1.0/';
|
|
9
10
|
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
|
@@ -57,5 +58,10 @@ window.ProcessMaker = {
|
|
|
57
58
|
id: 1,
|
|
58
59
|
},
|
|
59
60
|
},
|
|
61
|
+
user: {
|
|
62
|
+
id: 'standalone',
|
|
63
|
+
fullName: faker.person.fullName(),
|
|
64
|
+
avatar: null,
|
|
65
|
+
},
|
|
60
66
|
|
|
61
67
|
};
|