@processmaker/modeler 1.27.0 → 1.29.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 +1519 -822
- package/dist/modeler.common.js.map +1 -1
- package/dist/modeler.umd.js +1519 -822
- package/dist/modeler.umd.js.map +1 -1
- package/dist/modeler.umd.min.js +3 -3
- package/dist/modeler.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/NodeIdGenerator.js +55 -22
- package/src/NodeInspector.js +2 -2
- package/src/components/crown/crownButtons/{duplicateButton.vue → cloneButton.vue} +10 -9
- package/src/components/crown/crownConfig/crownConfig.vue +3 -4
- package/src/components/crown/crownMultiselect/crownMultiselect.vue +20 -7
- package/src/components/crown/utils.js +12 -1
- package/src/components/hotkeys/copyPaste.js +7 -4
- package/src/components/hotkeys/main.js +6 -1
- package/src/components/inspectors/DocumentationFormTextArea.vue +6 -2
- package/src/components/inspectors/LoopCharacteristics.vue +5 -2
- package/src/components/inspectors/process.js +5 -1
- package/src/components/modeler/Modeler.vue +92 -99
- package/src/components/modeler/Selection.vue +40 -29
- package/src/components/nodes/association/index.js +3 -0
- package/src/components/nodes/dataInputAssociation/dataInputAssociation.vue +36 -26
- package/src/components/nodes/genericFlow/DataOutputAssociation.js +54 -2
- package/src/components/nodes/genericFlow/genericFlow.vue +0 -17
- package/src/components/nodes/node.js +81 -8
- package/src/components/nodes/pool/poolEventHandlers.js +0 -9
- package/src/components/toolbar/ToolBar.vue +21 -9
- package/src/components/toolbar/toolbar.scss +2 -1
- package/src/mixins/cloneSelection.js +153 -0
- package/src/mixins/linkConfig.js +4 -1
- package/src/store.js +7 -11
- package/src/undoRedoStore.js +4 -19
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
@toggle-panels-compressed="panelsCompressed = !panelsCompressed"
|
|
12
12
|
@toggle-mini-map-open="miniMapOpen = $event"
|
|
13
13
|
@saveBpmn="saveBpmn"
|
|
14
|
+
@publishTemplate="publishTemplate"
|
|
14
15
|
@close="close"
|
|
15
16
|
@save-state="pushToUndoStack"
|
|
16
17
|
@clearSelection="clearSelection"
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
:parent-height="parentHeight"
|
|
64
65
|
:canvas-drag-position="canvasDragPosition"
|
|
65
66
|
:compressed="panelsCompressed && noElementsSelected"
|
|
66
|
-
@shape-resize="shapeResize"
|
|
67
|
+
@shape-resize="shapeResize(false)"
|
|
67
68
|
/>
|
|
68
69
|
|
|
69
70
|
<component
|
|
@@ -105,8 +106,8 @@
|
|
|
105
106
|
@copy-element="copyElement"
|
|
106
107
|
@copy-selection="copyElement"
|
|
107
108
|
@paste-element="pasteElements"
|
|
108
|
-
@
|
|
109
|
-
@
|
|
109
|
+
@clone-element="cloneElement"
|
|
110
|
+
@clone-selection="cloneSelection"
|
|
110
111
|
@default-flow="toggleDefaultFlow"
|
|
111
112
|
@shape-resize="shapeResize"
|
|
112
113
|
/>
|
|
@@ -116,7 +117,7 @@
|
|
|
116
117
|
:graph="graph"
|
|
117
118
|
:paperManager="paperManager"
|
|
118
119
|
:useModelGeometry="false"
|
|
119
|
-
@
|
|
120
|
+
@clone-selection="cloneSelection"
|
|
120
121
|
@remove-nodes="removeNodes"
|
|
121
122
|
:processNode="processNode"
|
|
122
123
|
@save-state="pushToUndoStack"
|
|
@@ -139,12 +140,13 @@ import InspectorPanel from '@/components/inspectors/InspectorPanel';
|
|
|
139
140
|
import undoRedoStore from '@/undoRedoStore';
|
|
140
141
|
import { Linter } from 'bpmnlint';
|
|
141
142
|
import linterConfig from '../../../.bpmnlintrc';
|
|
142
|
-
import
|
|
143
|
+
import { getNodeIdGenerator } from '../../NodeIdGenerator';
|
|
143
144
|
import Process from '../inspectors/process';
|
|
144
145
|
import runningInCypressTest from '@/runningInCypressTest';
|
|
145
146
|
import getValidationProperties from '@/targetValidationUtils';
|
|
146
147
|
import MiniPaper from '@/components/miniPaper/MiniPaper';
|
|
147
148
|
import { id as laneId } from '@/components/nodes/poolLane/config';
|
|
149
|
+
import { id as processId } from '@/components/inspectors/process';
|
|
148
150
|
import { id as sequenceFlowId } from '../nodes/sequenceFlow';
|
|
149
151
|
import { id as associationId } from '../nodes/association';
|
|
150
152
|
import { id as messageFlowId } from '../nodes/messageFlow/config';
|
|
@@ -167,6 +169,7 @@ import { removeNodeFlows, removeNodeMessageFlows, removeNodeAssociations, remove
|
|
|
167
169
|
import { getInvalidNodes } from '@/components/modeler/modelerUtils';
|
|
168
170
|
import { NodeMigrator } from '@/components/modeler/NodeMigrator';
|
|
169
171
|
import addLoopCharacteristics from '@/setup/addLoopCharacteristics';
|
|
172
|
+
import cloneSelection from '../../mixins/cloneSelection';
|
|
170
173
|
|
|
171
174
|
import ProcessmakerModelerGenericFlow from '@/components/nodes/genericFlow/genericFlow';
|
|
172
175
|
|
|
@@ -190,9 +193,11 @@ export default {
|
|
|
190
193
|
},
|
|
191
194
|
},
|
|
192
195
|
},
|
|
193
|
-
mixins: [hotkeys],
|
|
196
|
+
mixins: [hotkeys, cloneSelection],
|
|
194
197
|
data() {
|
|
195
198
|
return {
|
|
199
|
+
pasteInProgress: false,
|
|
200
|
+
cloneInProgress: false,
|
|
196
201
|
internalClipboard: [],
|
|
197
202
|
tooltipTarget: null,
|
|
198
203
|
|
|
@@ -303,10 +308,10 @@ export default {
|
|
|
303
308
|
isAppleOS() {
|
|
304
309
|
return typeof navigator !== 'undefined' && /Mac|iPad|iPhone/.test(navigator.platform);
|
|
305
310
|
},
|
|
306
|
-
async shapeResize() {
|
|
311
|
+
async shapeResize(clearIfEmpty=true) {
|
|
307
312
|
await this.$nextTick();
|
|
308
313
|
await this.paperManager.awaitScheduledUpdates();
|
|
309
|
-
this.$refs.selector.updateSelectionBox(true);
|
|
314
|
+
this.$refs.selector.updateSelectionBox(true, clearIfEmpty);
|
|
310
315
|
},
|
|
311
316
|
toggleDefaultFlow(flow) {
|
|
312
317
|
const source = flow.definition.sourceRef;
|
|
@@ -315,7 +320,7 @@ export default {
|
|
|
315
320
|
}
|
|
316
321
|
source.set('default', flow);
|
|
317
322
|
},
|
|
318
|
-
|
|
323
|
+
cloneElement(node, copyCount) {
|
|
319
324
|
const clonedNode = node.clone(this.nodeRegistry, this.moddle, this.$t);
|
|
320
325
|
const yOffset = (node.diagram.bounds.height + 30) * copyCount;
|
|
321
326
|
|
|
@@ -329,90 +334,61 @@ export default {
|
|
|
329
334
|
dataOutputAssociationFlowId,
|
|
330
335
|
dataInputAssociationFlowId,
|
|
331
336
|
genericFlowId,
|
|
337
|
+
processId,
|
|
332
338
|
];
|
|
333
339
|
if (this.highlightedNodes.length === 1 && flows.includes(this.highlightedNodes[0].type)) return;
|
|
334
|
-
store.commit('setCopiedElements', this.
|
|
340
|
+
store.commit('setCopiedElements', this.cloneNodesSelection());
|
|
335
341
|
this.$bvToast.toast(this.$t('Object(s) have been copied'), { noCloseButton:true, variant: 'success', solid: true, toaster: 'b-toaster-top-center' });
|
|
336
342
|
},
|
|
343
|
+
publishTemplate() {
|
|
344
|
+
this.$emit('publishTemplate');
|
|
345
|
+
},
|
|
337
346
|
async pasteElements() {
|
|
338
|
-
if (this.copiedElements) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
347
|
+
if (this.copiedElements.length > 0 && !this.pasteInProgress) {
|
|
348
|
+
this.pasteInProgress = true;
|
|
349
|
+
try {
|
|
350
|
+
await this.addClonedNodes(this.copiedElements);
|
|
351
|
+
await this.$nextTick();
|
|
352
|
+
await this.paperManager.awaitScheduledUpdates();
|
|
353
|
+
await this.$refs.selector.selectElements(this.findViewElementsFromNodes(this.copiedElements), true);
|
|
354
|
+
await this.$nextTick();
|
|
355
|
+
await store.commit('setCopiedElements', this.cloneNodesSelection());
|
|
356
|
+
this.scrollToSelection();
|
|
357
|
+
} finally {
|
|
358
|
+
this.pasteInProgress = false;
|
|
359
|
+
await this.pushToUndoStack();
|
|
360
|
+
}
|
|
342
361
|
}
|
|
343
362
|
},
|
|
344
|
-
cloneSelection() {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// Check node type to clone
|
|
365
|
-
if ([
|
|
366
|
-
sequenceFlowId,
|
|
367
|
-
laneId,
|
|
368
|
-
associationId,
|
|
369
|
-
messageFlowId,
|
|
370
|
-
dataOutputAssociationFlowId,
|
|
371
|
-
dataInputAssociationFlowId,
|
|
372
|
-
genericFlowId,
|
|
373
|
-
].includes(node.type)) {
|
|
374
|
-
// Add offset for all waypoints on cloned flow
|
|
375
|
-
const clonedFlow = node.cloneFlow(this.nodeRegistry, this.moddle, this.$t);
|
|
376
|
-
clonedFlow.setIds(this.nodeIdGenerator);
|
|
377
|
-
clonedFlows.push(clonedFlow);
|
|
378
|
-
clonedNodes.push(clonedFlow);
|
|
379
|
-
} else {
|
|
380
|
-
// Clone node and calculate offset
|
|
381
|
-
const clonedNode = node.clone(this.nodeRegistry, this.moddle, this.$t);
|
|
382
|
-
const yOffset = sheight;
|
|
383
|
-
clonedNode.diagram.bounds.y += yOffset;
|
|
384
|
-
// Set cloned node id
|
|
385
|
-
clonedNode.setIds(this.nodeIdGenerator);
|
|
386
|
-
clonedNodes.push(clonedNode);
|
|
387
|
-
}
|
|
388
|
-
});
|
|
363
|
+
async cloneSelection() {
|
|
364
|
+
const clonedNodes = this.cloneNodesSelection();
|
|
365
|
+
if (clonedNodes && clonedNodes.length === 0) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
try {
|
|
369
|
+
this.cloneInProgress = true;
|
|
370
|
+
this.$refs.selector.clearSelection();
|
|
371
|
+
await this.addClonedNodes(clonedNodes);
|
|
372
|
+
await this.$nextTick();
|
|
373
|
+
await this.paperManager.awaitScheduledUpdates();
|
|
374
|
+
await this.$refs.selector.selectElements(this.findViewElementsFromNodes(clonedNodes));
|
|
375
|
+
this.scrollToSelection();
|
|
376
|
+
} finally {
|
|
377
|
+
this.cloneInProgress = false;
|
|
378
|
+
await this.pushToUndoStack();
|
|
389
379
|
}
|
|
390
|
-
// Connect flows
|
|
391
|
-
clonedFlows.forEach(flow => {
|
|
392
|
-
// Look up the original flow
|
|
393
|
-
const flowClonedFrom = { definition: originalFlows.find(el => el.id === flow.definition.cloneOf) };
|
|
394
|
-
// Get the id's of the sourceRef and targetRef of original flow
|
|
395
|
-
const src = flowClonedFrom.definition.sourceRef;
|
|
396
|
-
const target = flowClonedFrom.definition.targetRef;
|
|
397
|
-
const srcClone = clonedNodes.find(node => node.definition.cloneOf === src.id);
|
|
398
|
-
const targetClone = clonedNodes.find(node => node.definition.cloneOf === target.id);
|
|
399
|
-
// Reference the elements to the flow that connects them
|
|
400
|
-
flow.definition.sourceRef = srcClone.definition;
|
|
401
|
-
flow.definition.targetRef = targetClone.definition;
|
|
402
|
-
// Reference the flow to the elements that are connected by it
|
|
403
|
-
srcClone.definition.outgoing ? srcClone.definition.outgoing.push(flow.definition) : srcClone.definition.outgoing = [flow.definition];
|
|
404
|
-
targetClone.definition.incoming ? targetClone.definition.incoming.push(flow.definition) : targetClone.definition.incoming = [flow.definition];
|
|
405
|
-
// Translate flow waypoints to where they should be
|
|
406
|
-
flow.diagram.waypoint.forEach(point => {
|
|
407
|
-
point.y += sheight;
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
return clonedNodes;
|
|
411
380
|
},
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
381
|
+
scrollToSelection() {
|
|
382
|
+
const containerRect = this.$refs['paper-container'].getBoundingClientRect();
|
|
383
|
+
const selector = this.$refs.selector;
|
|
384
|
+
const selectorRect = selector.$el.getBoundingClientRect();
|
|
385
|
+
// Scroll to the cloned elements only when they are not visible on the screen.
|
|
386
|
+
if (selectorRect.right > containerRect.right || selectorRect.bottom > containerRect.bottom || selectorRect.left < containerRect.left || selectorRect.top < containerRect.top) {
|
|
387
|
+
const currentPosition = this.paper.translate();
|
|
388
|
+
const newTy = currentPosition.ty - (selectorRect.top - containerRect.top - selectorRect.height);
|
|
389
|
+
this.paper.translate(currentPosition.tx, newTy);
|
|
390
|
+
selector.updateSelectionBox(true);
|
|
391
|
+
}
|
|
416
392
|
},
|
|
417
393
|
findViewElementsFromNodes(nodes) {
|
|
418
394
|
return nodes.map(node => {
|
|
@@ -476,9 +452,12 @@ export default {
|
|
|
476
452
|
}
|
|
477
453
|
},
|
|
478
454
|
async pushToUndoStack() {
|
|
455
|
+
if (this.pasteInProgress || this.cloneInProgress) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
479
458
|
try {
|
|
480
459
|
const xml = await this.getXmlFromDiagram();
|
|
481
|
-
undoRedoStore.dispatch('pushState', xml);
|
|
460
|
+
await undoRedoStore.dispatch('pushState', xml);
|
|
482
461
|
window.ProcessMaker.EventBus.$emit('modeler-change');
|
|
483
462
|
} catch (invalidXml) {
|
|
484
463
|
// eslint-disable-next-line no-console
|
|
@@ -829,12 +808,20 @@ export default {
|
|
|
829
808
|
this.isRendering = false;
|
|
830
809
|
this.$emit('parsed');
|
|
831
810
|
},
|
|
832
|
-
async loadXML(xml =
|
|
811
|
+
async loadXML(xml = null) {
|
|
812
|
+
let emitChangeEvent = false;
|
|
813
|
+
if (xml === null) {
|
|
814
|
+
xml = this.currentXML;
|
|
815
|
+
emitChangeEvent = true;
|
|
816
|
+
}
|
|
833
817
|
this.definitions = await this.xmlManager.getDefinitionsFromXml(xml);
|
|
834
818
|
this.xmlManager.definitions = this.definitions;
|
|
835
|
-
this.nodeIdGenerator =
|
|
819
|
+
this.nodeIdGenerator = getNodeIdGenerator(this.definitions);
|
|
836
820
|
store.commit('clearNodes');
|
|
837
|
-
this.renderPaper();
|
|
821
|
+
await this.renderPaper();
|
|
822
|
+
if (emitChangeEvent) {
|
|
823
|
+
window.ProcessMaker.EventBus.$emit('modeler-change');
|
|
824
|
+
}
|
|
838
825
|
},
|
|
839
826
|
getBoundaryEvents(process) {
|
|
840
827
|
return process.get('flowElements').filter(({ $type }) => $type === 'bpmn:BoundaryEvent');
|
|
@@ -970,11 +957,14 @@ export default {
|
|
|
970
957
|
store.commit('addNode', node);
|
|
971
958
|
this.poolTarget = null;
|
|
972
959
|
});
|
|
973
|
-
|
|
974
|
-
await this.pushToUndoStack();
|
|
975
960
|
},
|
|
976
961
|
async removeNode(node, { removeRelationships = true } = {}) {
|
|
962
|
+
if (!node) {
|
|
963
|
+
// already removed
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
977
966
|
if (removeRelationships) {
|
|
967
|
+
|
|
978
968
|
removeNodeFlows(node, this);
|
|
979
969
|
removeNodeMessageFlows(node, this);
|
|
980
970
|
removeNodeAssociations(node, this);
|
|
@@ -989,10 +979,10 @@ export default {
|
|
|
989
979
|
store.commit('highlightNode', this.processNode);
|
|
990
980
|
this.$refs.selector.clearSelection();
|
|
991
981
|
await this.$nextTick();
|
|
992
|
-
this.pushToUndoStack();
|
|
982
|
+
await this.pushToUndoStack();
|
|
993
983
|
},
|
|
994
984
|
async removeNodes() {
|
|
995
|
-
this.performSingleUndoRedoTransaction(async() => {
|
|
985
|
+
await this.performSingleUndoRedoTransaction(async() => {
|
|
996
986
|
await this.paperManager.performAtomicAction(async() => {
|
|
997
987
|
const waitPromises = [];
|
|
998
988
|
this.highlightedNodes.forEach((node) =>
|
|
@@ -1035,7 +1025,7 @@ export default {
|
|
|
1035
1025
|
undoRedoStore.commit('disableSavingState');
|
|
1036
1026
|
await cb();
|
|
1037
1027
|
undoRedoStore.commit('enableSavingState');
|
|
1038
|
-
this.pushToUndoStack();
|
|
1028
|
+
await this.pushToUndoStack();
|
|
1039
1029
|
},
|
|
1040
1030
|
removeNodesFromLane(node) {
|
|
1041
1031
|
const containingLane = node.pool && node.pool.component.laneSet &&
|
|
@@ -1274,14 +1264,17 @@ export default {
|
|
|
1274
1264
|
this.pointerUpHandler(event, cellView);
|
|
1275
1265
|
}, this);
|
|
1276
1266
|
|
|
1267
|
+
this.$el.addEventListener('mouseenter', () => {
|
|
1268
|
+
store.commit('setClientLeftPaper', false);
|
|
1269
|
+
});
|
|
1270
|
+
|
|
1277
1271
|
this.$el.addEventListener('mousemove', event => {
|
|
1278
|
-
const { clientX, clientY } = event;
|
|
1279
1272
|
this.pointerMoveHandler(event);
|
|
1280
|
-
store.commit('setClientMousePosition', { clientX, clientY });
|
|
1281
1273
|
});
|
|
1282
1274
|
|
|
1283
1275
|
this.$el.addEventListener('mouseleave', () => {
|
|
1284
|
-
|
|
1276
|
+
this.paperManager.removeEventHandler('blank:pointermove');
|
|
1277
|
+
store.commit('setClientLeftPaper', true);
|
|
1285
1278
|
});
|
|
1286
1279
|
|
|
1287
1280
|
this.paperManager.addEventHandler('cell:pointerclick', (cellView, evt, x, y) => {
|
|
@@ -1311,9 +1304,9 @@ export default {
|
|
|
1311
1304
|
|
|
1312
1305
|
/* Register custom nodes */
|
|
1313
1306
|
window.ProcessMaker.EventBus.$emit('modeler-start', {
|
|
1314
|
-
loadXML: xml => {
|
|
1315
|
-
this.loadXML(xml);
|
|
1316
|
-
undoRedoStore.dispatch('pushState', xml);
|
|
1307
|
+
loadXML: async(xml) => {
|
|
1308
|
+
await this.loadXML(xml);
|
|
1309
|
+
await undoRedoStore.dispatch('pushState', xml);
|
|
1317
1310
|
},
|
|
1318
1311
|
addWarnings: warnings => this.$emit('warnings', warnings),
|
|
1319
1312
|
addBreadcrumbs: breadcrumbs => this.breadcrumbData.push(breadcrumbs),
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
:plane-elements="$parent.planeElements"
|
|
17
17
|
:is-rendering="$parent.isRendering"
|
|
18
18
|
:dropdown-data="[]"
|
|
19
|
+
:has-pools="hasPoolsOrLanesSelected"
|
|
19
20
|
v-on="$listeners"
|
|
20
21
|
/>
|
|
21
22
|
</div>
|
|
@@ -28,14 +29,13 @@ import CrownMultiselect from '@/components/crown/crownMultiselect/crownMultisele
|
|
|
28
29
|
import { id as poolId } from '@/components/nodes/pool/config';
|
|
29
30
|
import { id as laneId } from '@/components/nodes/poolLane/config';
|
|
30
31
|
import { id as genericFlowId } from '@/components/nodes/genericFlow/config';
|
|
32
|
+
import { id as sequenceFlowId } from '@/components/nodes/sequenceFlow';
|
|
33
|
+
import { id as associationId } from '@/components/nodes/association';
|
|
34
|
+
import { id as messageFlowId } from '@/components/nodes/messageFlow/config';
|
|
35
|
+
import { id as dataOutputAssociationFlowId } from '@/components/nodes/dataOutputAssociation/config';
|
|
36
|
+
import { id as dataInputAssociationFlowId } from '@/components/nodes/dataInputAssociation/config';
|
|
31
37
|
import { labelWidth, poolPadding } from '../nodes/pool/poolSizes';
|
|
32
|
-
|
|
33
|
-
'processmaker-modeler-boundary-timer-event',
|
|
34
|
-
'processmaker-modeler-boundary-error-event',
|
|
35
|
-
'processmaker-modeler-boundary-signal-event',
|
|
36
|
-
'processmaker-modeler-boundary-conditional-event',
|
|
37
|
-
'processmaker-modeler-boundary-message-event',
|
|
38
|
-
];
|
|
38
|
+
|
|
39
39
|
export default {
|
|
40
40
|
name: 'Selection',
|
|
41
41
|
components: {
|
|
@@ -85,6 +85,14 @@ export default {
|
|
|
85
85
|
this.paperManager.paper.on('scale:changed ', this.updateSelectionBox);
|
|
86
86
|
this.paperManager.paper.on('translate:changed ', this.translateChanged);
|
|
87
87
|
},
|
|
88
|
+
computed: {
|
|
89
|
+
hasPoolsOrLanesSelected() {
|
|
90
|
+
return this.selected.some((view) => {
|
|
91
|
+
return view.model.component.node.type === poolId ||
|
|
92
|
+
view.model.component.node.type === laneId;
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
},
|
|
88
96
|
watch: {
|
|
89
97
|
// whenever selected changes
|
|
90
98
|
selected(newSelected) {
|
|
@@ -318,7 +326,7 @@ export default {
|
|
|
318
326
|
/**
|
|
319
327
|
* Update the selection Box
|
|
320
328
|
*/
|
|
321
|
-
updateSelectionBox(force=false) {
|
|
329
|
+
updateSelectionBox(force=false, clearIfEmpty=true) {
|
|
322
330
|
if (force || this.isSelecting && this.style) {
|
|
323
331
|
if (this.selected.length > 0) {
|
|
324
332
|
const box = this.getSelectionVertex(this.selected, false, true);
|
|
@@ -330,7 +338,7 @@ export default {
|
|
|
330
338
|
// Set the dimensions of the element
|
|
331
339
|
this.style.width = `${box.maxX - box.minX}px`;
|
|
332
340
|
this.style.height = `${box.maxY - box.minY}px`;
|
|
333
|
-
} else {
|
|
341
|
+
} else if (clearIfEmpty) {
|
|
334
342
|
this.clearSelection();
|
|
335
343
|
}
|
|
336
344
|
}
|
|
@@ -339,6 +347,13 @@ export default {
|
|
|
339
347
|
* Filter the selected elements
|
|
340
348
|
*/
|
|
341
349
|
filterSelected() {
|
|
350
|
+
const flowTypes = [
|
|
351
|
+
sequenceFlowId,
|
|
352
|
+
dataOutputAssociationFlowId,
|
|
353
|
+
dataInputAssociationFlowId,
|
|
354
|
+
associationId,
|
|
355
|
+
messageFlowId,
|
|
356
|
+
];
|
|
342
357
|
// Get the selected pools IDs
|
|
343
358
|
const selectedPoolsIds = this.selected
|
|
344
359
|
.filter(shape => shape.model.component)
|
|
@@ -349,26 +364,15 @@ export default {
|
|
|
349
364
|
if (shape.model.component && shape.model.component.node.pool) {
|
|
350
365
|
return shape.model.component.node.pool && !selectedPoolsIds.includes(shape.model.component.node.pool.component.node.id);
|
|
351
366
|
}
|
|
367
|
+
// remove from selection the selected flows that belongs to a selected pools
|
|
368
|
+
if (shape.model.component && flowTypes.includes(shape.model.component.node.type)) {
|
|
369
|
+
const parent = shape.model.getParentCell();
|
|
370
|
+
if (parent.component && parent.component.node.pool) {
|
|
371
|
+
return !selectedPoolsIds.includes(parent.component.node.pool.component.node.id);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
352
374
|
return true;
|
|
353
375
|
});
|
|
354
|
-
// A boundary event could only be selected alone
|
|
355
|
-
const firstSelectedBoundary = this.selected.find(shape => {
|
|
356
|
-
return shape.model.component &&
|
|
357
|
-
boundaryElements.includes(shape.model.component.node.type);
|
|
358
|
-
});
|
|
359
|
-
const firstSelectedElement = this.selected[0];
|
|
360
|
-
if (firstSelectedBoundary) {
|
|
361
|
-
this.selected = this.selected.filter(shape => {
|
|
362
|
-
if (firstSelectedElement === firstSelectedBoundary) {
|
|
363
|
-
// boundary event selected alone
|
|
364
|
-
return shape.model.component &&
|
|
365
|
-
shape === firstSelectedBoundary;
|
|
366
|
-
}
|
|
367
|
-
// do not allow to select a boundary event with another element
|
|
368
|
-
return shape.model.component &&
|
|
369
|
-
!boundaryElements.includes(shape.model.component.node.type);
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
376
|
},
|
|
373
377
|
/**
|
|
374
378
|
* Pan paper handler
|
|
@@ -475,6 +479,9 @@ export default {
|
|
|
475
479
|
this.$emit('save-state');
|
|
476
480
|
this.dragging = false;
|
|
477
481
|
this.stopForceMove = false;
|
|
482
|
+
// Readjusts the selection box, taking into consideration elements
|
|
483
|
+
// that are anchored and did not move, such as boundary events.
|
|
484
|
+
this.updateSelectionBox();
|
|
478
485
|
},
|
|
479
486
|
/**
|
|
480
487
|
* Translate the Selected shapes adding some custom validations
|
|
@@ -636,7 +643,7 @@ export default {
|
|
|
636
643
|
/**
|
|
637
644
|
* Rollback drag an element outside it's pool parent
|
|
638
645
|
*/
|
|
639
|
-
rollbackSelection(){
|
|
646
|
+
async rollbackSelection(){
|
|
640
647
|
const deltaX = this.initialPosition.left - this.left;
|
|
641
648
|
const deltaY = this.initialPosition.top - this.top;
|
|
642
649
|
this.style.left = `${this.initialPosition.left}px`;
|
|
@@ -645,14 +652,18 @@ export default {
|
|
|
645
652
|
const shapesToNotTranslate = [
|
|
646
653
|
'PoolLane',
|
|
647
654
|
'standard.Link',
|
|
655
|
+
'processmaker.components.nodes.boundaryEvent.Shape',
|
|
648
656
|
];
|
|
649
657
|
this.selected.filter(shape => !shapesToNotTranslate.includes(shape.model.get('type')))
|
|
650
658
|
.forEach(shape => {
|
|
651
659
|
shape.model.translate(deltaX/scale.sx, deltaY/scale.sy);
|
|
652
660
|
});
|
|
653
661
|
this.isOutOfThePool = false;
|
|
654
|
-
store.commit('allowSavingElementPosition');
|
|
662
|
+
await store.commit('allowSavingElementPosition');
|
|
655
663
|
this.paperManager.setStateValid();
|
|
664
|
+
await this.$nextTick();
|
|
665
|
+
await this.paperManager.awaitScheduledUpdates();
|
|
666
|
+
this.updateSelectionBox(true);
|
|
656
667
|
},
|
|
657
668
|
/**
|
|
658
669
|
* Expand and fit the pool container
|
|
@@ -21,7 +21,7 @@ import linkConfig from '@/mixins/linkConfig';
|
|
|
21
21
|
import get from 'lodash/get';
|
|
22
22
|
import associationHead from '!!url-loader!@/assets/association-head.svg';
|
|
23
23
|
import CrownConfig from '@/components/crown/crownConfig/crownConfig';
|
|
24
|
-
import { getOrFindDataInput, removeDataInput } from '@/components/crown/utils';
|
|
24
|
+
import { getOrFindDataInput, removeDataInput, findIOSpecificationOwner } from '@/components/crown/utils';
|
|
25
25
|
import { pull } from 'lodash';
|
|
26
26
|
|
|
27
27
|
export default {
|
|
@@ -50,20 +50,38 @@ export default {
|
|
|
50
50
|
},
|
|
51
51
|
computed: {
|
|
52
52
|
isValidConnection() {
|
|
53
|
-
const targetType = get(this.target, 'component.node.type');
|
|
53
|
+
const targetType = get(this.target, 'component.node.definition.$type');
|
|
54
54
|
|
|
55
55
|
if (!targetType) {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const dataStoreValidTargets = [
|
|
60
|
+
'bpmn:Task',
|
|
61
|
+
'bpmn:SubProcess',
|
|
62
|
+
'bpmn:CallActivity',
|
|
63
|
+
'bpmn:ManualTask',
|
|
64
|
+
'bpmn:ScriptTask',
|
|
65
|
+
'bpmn:ServiceTask',
|
|
66
|
+
];
|
|
67
|
+
const dataObjectValidTargets = [
|
|
68
|
+
'bpmn:Task',
|
|
69
|
+
'bpmn:SubProcess',
|
|
70
|
+
'bpmn:CallActivity',
|
|
71
|
+
'bpmn:ManualTask',
|
|
72
|
+
'bpmn:ScriptTask',
|
|
73
|
+
'bpmn:ServiceTask',
|
|
74
|
+
'bpmn:IntermediateThrowEvent',
|
|
75
|
+
'bpmn:EndEvent',
|
|
76
|
+
];
|
|
61
77
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
78
|
+
const sourceIsDataStore = this.sourceNode.definition.$type === 'bpmn:DataStoreReference';
|
|
79
|
+
const sourceIsDataObject = this.sourceNode.definition.$type === 'bpmn:DataObjectReference';
|
|
65
80
|
|
|
66
|
-
|
|
81
|
+
if (sourceIsDataStore && dataStoreValidTargets.includes(targetType)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return (sourceIsDataObject && dataObjectValidTargets.includes(targetType));
|
|
67
85
|
},
|
|
68
86
|
},
|
|
69
87
|
methods: {
|
|
@@ -71,29 +89,16 @@ export default {
|
|
|
71
89
|
if (this.node.dataAssociationProps) {
|
|
72
90
|
return this.node.dataAssociationProps.sourceShape;
|
|
73
91
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const dataObjectDefinition = taskWithInputAssociation.component.node.definition.get('dataInputAssociations')[0].sourceRef[0];
|
|
81
|
-
|
|
82
|
-
return this.graph.getElements().find(element => {
|
|
83
|
-
return element.component && element.component.node.definition === dataObjectDefinition;
|
|
84
|
-
});
|
|
92
|
+
const source = this.node.definition.sourceRef[0];
|
|
93
|
+
// find shape
|
|
94
|
+
const shape = this.graph.getElements().find(e=>e.component.node.definition === source);
|
|
95
|
+
return shape;
|
|
85
96
|
},
|
|
86
97
|
getTargetRef() {
|
|
87
98
|
if (this.node.dataAssociationProps) {
|
|
88
99
|
return this.node.dataAssociationProps.targetCoords;
|
|
89
100
|
}
|
|
90
|
-
|
|
91
|
-
const taskWithInputAssociation = this.graph.getElements().find(element => {
|
|
92
|
-
return element.component && element.component.node.definition.get('dataInputAssociations') &&
|
|
93
|
-
element.component.node.definition.get('dataInputAssociations')[0] === this.node.definition;
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
return taskWithInputAssociation.component.node.definition;
|
|
101
|
+
return findIOSpecificationOwner(this.node.definition.targetRef.$parent, this.$parent);
|
|
97
102
|
},
|
|
98
103
|
updateRouter() {
|
|
99
104
|
this.shape.router('normal', { elementPadding: this.elementPadding });
|
|
@@ -102,6 +107,7 @@ export default {
|
|
|
102
107
|
const targetShape = this.shape.getTargetElement();
|
|
103
108
|
const dataInput = getOrFindDataInput(this.moddle, targetShape.component.node, this.sourceNode.definition);
|
|
104
109
|
this.node.definition.set('targetRef', dataInput);
|
|
110
|
+
// @todo Review why this needs to be and array. When saving the BPMN, if this is not an array the sourceRef is not stored
|
|
105
111
|
this.node.definition.set('sourceRef', [this.sourceNode.definition]);
|
|
106
112
|
targetShape.component.node.definition.set('dataInputAssociations', [this.node.definition]);
|
|
107
113
|
},
|
|
@@ -129,6 +135,10 @@ export default {
|
|
|
129
135
|
this.shape.component = this;
|
|
130
136
|
},
|
|
131
137
|
destroyed() {
|
|
138
|
+
// when a association was not completed this.targetNode will be undefined
|
|
139
|
+
if (!this.targetNode) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
132
142
|
removeDataInput(this.targetNode, this.sourceNode.definition);
|
|
133
143
|
pull(this.targetNode.definition.get('dataInputAssociations'), this.node.definition);
|
|
134
144
|
},
|
|
@@ -12,8 +12,60 @@ export default class DataOutputAssociation extends DataAssociation {
|
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const dataStoreValidSources = [
|
|
16
|
+
'bpmn:Task',
|
|
17
|
+
'bpmn:SubProcess',
|
|
18
|
+
'bpmn:CallActivity',
|
|
19
|
+
'bpmn:ManualTask',
|
|
20
|
+
'bpmn:ScriptTask',
|
|
21
|
+
'bpmn:ServiceTask',
|
|
22
|
+
];
|
|
23
|
+
const dataStoreValidTargets = [
|
|
24
|
+
'bpmn:Task',
|
|
25
|
+
'bpmn:SubProcess',
|
|
26
|
+
'bpmn:CallActivity',
|
|
27
|
+
'bpmn:ManualTask',
|
|
28
|
+
'bpmn:ScriptTask',
|
|
29
|
+
'bpmn:ServiceTask',
|
|
30
|
+
];
|
|
31
|
+
const dataObjectValidSources = [
|
|
32
|
+
'bpmn:Task',
|
|
33
|
+
'bpmn:SubProcess',
|
|
34
|
+
'bpmn:CallActivity',
|
|
35
|
+
'bpmn:ManualTask',
|
|
36
|
+
'bpmn:ScriptTask',
|
|
37
|
+
'bpmn:ServiceTask',
|
|
38
|
+
'bpmn:IntermediateCatchEvent',
|
|
39
|
+
'bpmn:StartEvent',
|
|
40
|
+
];
|
|
41
|
+
const dataObjectValidTargets = [
|
|
42
|
+
'bpmn:Task',
|
|
43
|
+
'bpmn:SubProcess',
|
|
44
|
+
'bpmn:CallActivity',
|
|
45
|
+
'bpmn:ManualTask',
|
|
46
|
+
'bpmn:ScriptTask',
|
|
47
|
+
'bpmn:ServiceTask',
|
|
48
|
+
'bpmn:IntermediateThrowEvent',
|
|
49
|
+
'bpmn:EndEvent',
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const sourceType = sourceNode.definition.$type;
|
|
53
|
+
const targetType = targetNode.definition.$type;
|
|
54
|
+
const sourceIsDataStore = sourceNode.definition.$type === 'bpmn:DataStoreReference';
|
|
55
|
+
const sourceIsDataObject = sourceNode.definition.$type === 'bpmn:DataObjectReference';
|
|
56
|
+
const targetIsDataStore = targetNode.definition.$type === 'bpmn:DataStoreReference';
|
|
57
|
+
const targetIsDataObject = targetNode.definition.$type === 'bpmn:DataObjectReference';
|
|
58
|
+
|
|
59
|
+
if (sourceIsDataStore && dataStoreValidTargets.includes(targetType)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (sourceIsDataObject && dataObjectValidTargets.includes(targetType)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (targetIsDataStore && dataStoreValidSources.includes(sourceType)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return (targetIsDataObject && dataObjectValidSources.includes(sourceType));
|
|
17
69
|
}
|
|
18
70
|
|
|
19
71
|
makeFlowNode(sourceShape, targetShape, genericLink) {
|