@processmaker/modeler 1.32.0 → 1.34.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.
Files changed (101) hide show
  1. package/README.md +7 -0
  2. package/babel.config.js +1 -2
  3. package/cypress.json +1 -1
  4. package/dist/img/inclusive-gateway.0f0afffd.svg +4 -0
  5. package/dist/img/inspector.42e5d40d.svg +5 -0
  6. package/dist/modeler.common.js +3220 -4350
  7. package/dist/modeler.common.js.map +1 -1
  8. package/dist/modeler.umd.js +3220 -4350
  9. package/dist/modeler.umd.js.map +1 -1
  10. package/dist/modeler.umd.min.js +4 -4
  11. package/dist/modeler.umd.min.js.map +1 -1
  12. package/package.json +1 -1
  13. package/src/.DS_Store +0 -0
  14. package/src/ModelerApp.vue +0 -13
  15. package/src/NodeIdGenerator.js +16 -1
  16. package/src/assets/inspector.svg +5 -0
  17. package/src/assets/toolpanel/inclusive-gateway.svg +2 -2
  18. package/src/components/controls/controls.vue +2 -11
  19. package/src/components/crown/crownButtons/addLaneAboveButton.vue +3 -1
  20. package/src/components/crown/crownButtons/addLaneBelowButton.vue +3 -1
  21. package/src/components/crown/crownButtons/crownBoundaryEventDropdown.vue +2 -1
  22. package/src/components/crown/crownButtons/genericFlowButton.vue +2 -1
  23. package/src/components/crown/crownButtons/icons/faAlignBottom.js +3 -3
  24. package/src/components/crown/crownButtons/icons/faAlignLeft.js +3 -3
  25. package/src/components/crown/crownButtons/icons/faAlignRight.js +3 -3
  26. package/src/components/crown/crownButtons/icons/faAlignTop.js +3 -3
  27. package/src/components/crown/crownButtons/icons/faCenterHorizontally.js +3 -3
  28. package/src/components/crown/crownButtons/icons/faCenterVertically.js +3 -3
  29. package/src/components/crown/crownButtons/icons/faDistributeHorizontally.js +3 -3
  30. package/src/components/crown/crownButtons/icons/faDistributeVertically.js +3 -3
  31. package/src/components/crown/crownMultiselect/crownAlign.vue +3 -0
  32. package/src/components/crown/crownMultiselect/crownMultiselect.vue +7 -5
  33. package/src/components/highlightColors.js +8 -0
  34. package/src/components/inspectors/InspectorPanel.vue +26 -3
  35. package/src/components/inspectors/inspector.scss +11 -0
  36. package/src/components/inspectors/inspectorButton/InspectorButton.vue +38 -0
  37. package/src/components/inspectors/inspectorButton/inspectorButton.scss +20 -0
  38. package/src/components/inspectors/process.js +1 -1
  39. package/src/components/modeler/Modeler.vue +102 -5
  40. package/src/components/modeler/Selection.vue +9 -1
  41. package/src/components/nodes/association/index.js +1 -1
  42. package/src/components/nodes/baseStartEvent/index.js +1 -1
  43. package/src/components/nodes/boundaryEvent/index.js +1 -1
  44. package/src/components/nodes/dataInputAssociation/index.js +1 -1
  45. package/src/components/nodes/dataObject/index.js +1 -1
  46. package/src/components/nodes/dataOutputAssociation/index.js +1 -1
  47. package/src/components/nodes/dataStore/index.js +1 -1
  48. package/src/components/nodes/endEvent/index.js +1 -1
  49. package/src/components/nodes/eventBasedGateway/index.js +1 -1
  50. package/src/components/nodes/exclusiveGateway/index.js +1 -1
  51. package/src/components/nodes/gateway/index.js +1 -1
  52. package/src/components/nodes/inclusiveGateway/index.js +1 -1
  53. package/src/components/nodes/index.js +0 -1
  54. package/src/components/nodes/intermediateEvent/index.js +1 -1
  55. package/src/components/nodes/intermediateMessageEvent/index.js +1 -1
  56. package/src/components/nodes/intermediateTimerEvent/index.js +1 -1
  57. package/src/components/nodes/manualTask/index.js +1 -1
  58. package/src/components/nodes/messageFlow/index.js +1 -1
  59. package/src/components/nodes/parallelGateway/index.js +1 -1
  60. package/src/components/nodes/pool/index.js +1 -1
  61. package/src/components/nodes/pool/pool.vue +10 -4
  62. package/src/components/nodes/poolLane/index.js +1 -1
  63. package/src/components/nodes/scriptTask/index.js +1 -1
  64. package/src/components/nodes/sequenceFlow/index.js +1 -1
  65. package/src/components/nodes/serviceTask/index.js +1 -1
  66. package/src/components/nodes/subProcess/index.js +1 -1
  67. package/src/components/nodes/task/index.js +1 -1
  68. package/src/components/nodes/textAnnotation/index.js +1 -1
  69. package/src/components/railBottom/RailBottom.vue +9 -0
  70. package/src/components/railBottom/controls/Controls.vue +22 -2
  71. package/src/components/railBottom/controls/SubmenuPopper/SubmenuPopper.vue +9 -7
  72. package/src/components/railBottom/controls/controls.scss +2 -0
  73. package/src/components/railBottom/miniPaperControl/miniPaperControl.scss +1 -0
  74. package/src/components/railBottom/railBottom.scss +2 -0
  75. package/src/components/railBottom/zoomControl/ZoomControl.vue +1 -3
  76. package/src/components/rails/explorer-rail/explorer-rail.scss +11 -0
  77. package/src/components/rails/explorer-rail/explorer.vue +14 -5
  78. package/src/components/rails/explorer-rail/filterNodeTypes/filterNodeTypes.vue +18 -3
  79. package/src/components/rails/explorer-rail/nodeTypesLoop/nodeTypesLoop.vue +6 -1
  80. package/src/components/rails/explorer-rail/pmBlocksLoop/pmBlocksLoop.vue +86 -0
  81. package/src/components/shapeStackUtils.js +1 -1
  82. package/src/components/toolbar/ToolBar.vue +49 -39
  83. package/src/components/toolbar/toolbar.scss +78 -15
  84. package/src/components/topRail/TopRail.vue +1 -0
  85. package/src/components/topRail/validateControl/validateButton/ValidateButton.vue +3 -0
  86. package/src/components/topRail/validateControl/validateIssue/ValidateIssue.vue +1 -0
  87. package/src/components/topRail/validateControl/validatePanel/ValidatePanel.vue +4 -1
  88. package/src/components/topRail/validateControl/validatePanel/validatePanel.scss +1 -1
  89. package/src/mixins/clickAndDrop.js +17 -10
  90. package/src/mixins/highlightConfig.js +35 -8
  91. package/src/mixins/linkConfig.js +33 -6
  92. package/src/nodeTypesStore.js +36 -1
  93. package/src/setup/registerPmBlock.js +0 -0
  94. package/src/store.js +1 -0
  95. package/vue.config.js +1 -0
  96. package/dist/.DS_Store +0 -0
  97. package/dist/img/distribute-horizontally-icon.5c513cf4.svg +0 -3
  98. package/dist/img/distribute-vertically-icon.a35fb699.svg +0 -3
  99. package/dist/img/inclusive-gateway.754cb36f.svg +0 -4
  100. package/src/components/controls/rankConstants.js +0 -1
  101. package/src/components/modeler/ModelerReadonly.vue +0 -1011
@@ -1,1011 +0,0 @@
1
- <template>
2
- <span data-test="body-container">
3
- <div class="modeler h-100">
4
- <controls
5
- v-if="showControls"
6
- class="controls h-100 rounded-0 border-top-0 border-bottom-0 border-left-0"
7
- :nodeTypes="nodeTypes"
8
- :compressed="panelsCompressed"
9
- :parent-height="parentHeight"
10
- :allowDrop="allowDrop"
11
- :canvas-drag-position="canvasDragPosition"
12
- @drag="validateDropTarget"
13
- @handleDrop="handleDrop"
14
- />
15
- <b-col
16
- ref="paper-container"
17
- class="paper-container h-100 pr-4"
18
- :class="[cursor, { 'grabbing-cursor' : isGrabbing }]"
19
- :style="{ width: parentWidth, height: parentHeight }"
20
- >
21
-
22
- <div ref="paper" data-test="paper" class="main-paper" />
23
- </b-col>
24
-
25
- <component
26
- ref="nodeComponent"
27
- v-for="node in nodes"
28
- :is="node.type"
29
- :key="node._modelerId"
30
- :graph="graph"
31
- :paper="paper"
32
- :node="node"
33
- :id="node.id"
34
- :border-outline="borderOutline(node.id)"
35
- :collaboration="collaboration"
36
- :process-node="processNode"
37
- :processes="processes"
38
- :plane-elements="planeElements"
39
- :moddle="moddle"
40
- :nodeRegistry="nodeRegistry"
41
- :root-elements="definitions.get('rootElements')"
42
- :paperManager="paperManager"
43
- :auto-validate="autoValidate"
44
- :node-id-generator="nodeIdGenerator"
45
- :highlighted="highlightedNodes.includes(node)"
46
- :is-active="node === activeNode"
47
- :is-rendering="isRendering"
48
- :is-completed="requestCompletedNodes.includes(node.definition.id)"
49
- :is-in-progress="requestInProgressNodes.includes(node.definition.id)"
50
- @add-node="addNode"
51
- @set-cursor="cursor = $event"
52
- @set-pool-target="poolTarget = $event"
53
- @unset-pools="unsetPools"
54
- @clearSelection="clearSelection"
55
- @set-pools="setPools"
56
- @set-shape-stacking="setShapeStacking"
57
- @default-flow="toggleDefaultFlow"
58
- />
59
-
60
- <div class="rail-container">
61
- <div class="rail-left">
62
- <ZoomControl
63
- :paper-manager="paperManager"
64
- />
65
- </div>
66
- </div>
67
-
68
- <Selection
69
- v-if="paper"
70
- ref="selector"
71
- :graph="graph"
72
- :paperManager="paperManager"
73
- :useModelGeometry="false"
74
- :processNode="processNode"
75
- />
76
- </div>
77
- </span>
78
- </template>
79
-
80
- <script>
81
- import Vue from 'vue';
82
- import _ from 'lodash';
83
- import { dia } from 'jointjs';
84
- import boundaryEventConfig from '../nodes/boundaryEvent';
85
- import BpmnModdle from 'bpmn-moddle';
86
- import controls from '../controls/controls';
87
- import pull from 'lodash/pull';
88
- import remove from 'lodash/remove';
89
- import store from '@/store';
90
- import undoRedoStore from '@/undoRedoStore';
91
- import { Linter } from 'bpmnlint';
92
- import linterConfig from '../../../.bpmnlintrc';
93
- import { getNodeIdGenerator } from '../../NodeIdGenerator';
94
- import Process from '../inspectors/process';
95
- import runningInCypressTest from '@/runningInCypressTest';
96
- import getValidationProperties from '@/targetValidationUtils';
97
- import { id as laneId } from '@/components/nodes/poolLane/config';
98
- import { id as sequenceFlowId } from '../nodes/sequenceFlow';
99
- import { id as associationId } from '../nodes/association';
100
- import { id as messageFlowId } from '../nodes/messageFlow/config';
101
- import { id as dataOutputAssociationFlowId } from '../nodes/dataOutputAssociation/config';
102
- import { id as dataInputAssociationFlowId } from '../nodes/dataInputAssociation/config';
103
- import { id as genericFlowId } from '@/components/nodes/genericFlow/config';
104
-
105
- import PaperManager from '../paperManager';
106
- import registerInspectorExtension from '@/components/InspectorExtensionManager';
107
-
108
- import ensureShapeIsNotCovered from '@/components/shapeStackUtils';
109
- import Node from '@/components/nodes/node';
110
- import { addNodeToProcess } from '@/components/nodeManager';
111
- import TimerEventNode from '@/components/nodes/timerEventNode';
112
- import focusNameInputAndHighlightLabel from '@/components/modeler/focusNameInputAndHighlightLabel';
113
- import XMLManager from '@/components/modeler/XMLManager';
114
- import { NodeMigrator } from '@/components/modeler/NodeMigrator';
115
- import addLoopCharacteristics from '@/setup/addLoopCharacteristics';
116
- import Selection from './Selection';
117
- import ZoomControl from '@/components/railBottom/zoomControl/ZoomControl.vue';
118
-
119
- export default {
120
- components: {
121
- controls,
122
- Selection,
123
- ZoomControl,
124
- },
125
- props: {
126
- owner: Object,
127
- decorations: {
128
- type: Object,
129
- default() {
130
- return {};
131
- },
132
- },
133
- readOnly: {
134
- type: Boolean,
135
- default: true,
136
- },
137
- requestCompletedNodes: {
138
- type: Array,
139
- default: () => [],
140
- },
141
- requestInProgressNodes: {
142
- type: Array,
143
- default: () => [],
144
- },
145
- },
146
- data() {
147
- return {
148
- pasteInProgress: false,
149
- cloneInProgress: false,
150
- internalClipboard: [],
151
-
152
- /* Custom parsers for handling certain bpmn node types */
153
- parsers: {},
154
-
155
- // What bpmn moddle extensions should we register
156
- extensions: [],
157
- // Our node types, keyed by the id
158
- nodeRegistry: {},
159
-
160
- // Our jointjs data graph model
161
- graph: null,
162
- paper: null,
163
- paperManager: null,
164
-
165
- definitions: null,
166
- nodeIdGenerator: null,
167
- planeElements: null,
168
- canvasDragPosition: null,
169
- processNode: null,
170
- collaboration: null,
171
- moddle: null,
172
- allowDrop: true,
173
- poolTarget: null,
174
- processes: [],
175
- cursor: null,
176
- parentHeight: null,
177
- parentWidth: null,
178
- linter: null,
179
- validationErrors: {},
180
- miniMapOpen: false,
181
- panelsCompressed: false,
182
- isGrabbing: false,
183
- isRendering: false,
184
- allWarnings: [],
185
- nodeTypes: [],
186
- activeNode: null,
187
- xmlManager: null,
188
- previouslyStackedShape: null,
189
- canvasScale: 1,
190
- initialScale: 1,
191
- minimumScale: 0.2,
192
- scaleStep: 0.1,
193
- isDragging: false,
194
- isSelecting: false,
195
- isIntoTheSelection: false,
196
- dragStart: null,
197
- };
198
- },
199
- watch: {
200
- isRendering() {
201
- const loadingMessage = 'Loading process, please be patient.';
202
-
203
- if (this.isRendering) {
204
- window.ProcessMaker.alert(loadingMessage, 'warning');
205
- document.body.style.cursor = 'wait !important';
206
- this.cursor = 'wait';
207
- return;
208
- }
209
-
210
- window.ProcessMaker.navbar.alerts = window.ProcessMaker.navbar.alerts.filter(alert => {
211
- return alert.alertText !== loadingMessage;
212
- });
213
- document.body.style.cursor = 'auto';
214
- this.cursor = null;
215
- },
216
- currentXML() {
217
- this.validateIfAutoValidateIsOn();
218
- },
219
- definitions() {
220
- this.validateIfAutoValidateIsOn();
221
- },
222
- autoValidate() {
223
- this.validateIfAutoValidateIsOn();
224
- },
225
- canvasScale(canvasScale) {
226
- this.paperManager.scale = canvasScale;
227
- },
228
- },
229
- computed: {
230
- showControls() {
231
- return !this.readOnly;
232
- },
233
- autoValidate: () => store.getters.autoValidate,
234
- nodes: () => store.getters.nodes,
235
- currentXML() {
236
- return undoRedoStore.getters.currentState;
237
- },
238
- /* connectors expect a highlightedNode property */
239
- highlightedNode: () => store.getters.highlightedNodes[0],
240
- highlightedNodes: () => store.getters.highlightedNodes,
241
- },
242
- methods: {
243
- toggleDefaultFlow(flow) {
244
- const source = flow.definition.sourceRef;
245
- if (source.default && source.default.id === flow.id) {
246
- flow = null;
247
- }
248
- source.set('default', flow);
249
- },
250
- borderOutline(nodeId) {
251
- return this.decorations.borderOutline && this.decorations.borderOutline[nodeId];
252
- },
253
- cleanPlaneElements() {
254
- remove(this.planeElements, diagram => !diagram.bpmnElement);
255
- },
256
- validateIfAutoValidateIsOn() {
257
- if (this.autoValidate) {
258
- this.validateBpmnDiagram();
259
- }
260
- },
261
- translateConfig(inspectorConfig) {
262
- if (inspectorConfig.config) {
263
- const config = inspectorConfig.config;
264
-
265
- config.label = this.$t(config.label);
266
- config.helper = this.$t(config.helper);
267
- }
268
-
269
- if (inspectorConfig.items) {
270
- inspectorConfig.items.forEach(this.translateConfig);
271
- }
272
- },
273
- getXmlFromDiagram() {
274
- return new Promise((resolve, reject) => {
275
- this.toXML((error, xml) => {
276
- if (error) {
277
- reject(error);
278
- } else {
279
- resolve(xml);
280
- }
281
- });
282
- });
283
- },
284
- async validateBpmnDiagram() {
285
- if (!store.getters.globalProcesses || store.getters.globalProcesses.length === 0) {
286
- await store.dispatch('fetchGlobalProcesses');
287
- }
288
- this.validationErrors = await this.linter.lint(this.definitions);
289
- this.$emit('validate', this.validationErrors);
290
- },
291
- setPools(poolDefinition) {
292
- if (!this.collaboration) {
293
- this.collaboration = this.moddle.create('bpmn:Collaboration');
294
- this.definitions.get('rootElements').push(this.collaboration);
295
- this.collaboration.set('id', 'collaboration_0');
296
- this.plane.set('bpmnElement', this.collaboration);
297
- }
298
-
299
- if (poolDefinition.get('processRef')) {
300
- if (!this.collaboration.get('participants').includes(poolDefinition)) {
301
- this.collaboration.get('participants').push(poolDefinition);
302
- }
303
-
304
- return;
305
- }
306
-
307
- let process;
308
- if (this.collaboration.get('participants').length === 0) {
309
- process = this.processNode.definition;
310
- } else {
311
- process = this.moddle.create('bpmn:Process');
312
- this.processes.push(process);
313
- process.set('id', `process_${this.processes.length}`);
314
-
315
- this.definitions.get('rootElements').push(process);
316
- }
317
-
318
- poolDefinition.set('processRef', process);
319
- this.collaboration.get('participants').push(poolDefinition);
320
- },
321
- unsetPools() {
322
- pull(this.definitions.get('rootElements'), this.collaboration);
323
- this.plane.set('bpmnElement', this.processNode.definition);
324
- this.collaboration = null;
325
- },
326
- highlightNode(node, event) {
327
- if (!node || !this.highlightedNode) {
328
- return;
329
- }
330
-
331
- if (event && event.shiftKey) {
332
- store.commit('addToHighlightedNodes', [node]);
333
- return;
334
- }
335
-
336
- let isSameHighlightedNode = _.isEqual(node.id, this.highlightedNode.id);
337
-
338
- if (!isSameHighlightedNode) {
339
- store.commit('highlightNode', node);
340
- }
341
-
342
- return;
343
- },
344
- blurFocusedScreenBuilderElement() {
345
- const elementsToBlur = ['INPUT', 'SELECT'];
346
- if (elementsToBlur.includes(document.activeElement && document.activeElement.tagName)) {
347
- document.activeElement.blur();
348
- }
349
- },
350
- registerStatusBar(component) {
351
- this.owner.validationBar.push(component);
352
- },
353
- /**
354
- * Register a mixin into a node component.
355
- * Used during "modeler-before-init"
356
- *
357
- */
358
- registerComponentMixin(component, mixin) {
359
- if (!component.mixins) {
360
- component.mixins = [];
361
- }
362
- component.mixins.push(mixin);
363
- },
364
- /**
365
- * Register a BPMN Moddle extension in order to support extensions to the bpmn xml format.
366
- * This is used to support new attributes and elements that would be needed for specific
367
- * bpmn execution environments.
368
- */
369
- registerBpmnExtension(namespace, extension) {
370
- this.extensions[namespace] = extension;
371
- },
372
- registerNode(nodeType, customParser) {
373
- const defaultParser = () => nodeType.id;
374
- const implementationParser = definition => {
375
- if (definition.get('implementation') === nodeType.implementation) {
376
- return nodeType.id;
377
- }
378
- return undefined;
379
- };
380
-
381
- this.translateConfig(nodeType.inspectorConfig[0]);
382
- addLoopCharacteristics(nodeType);
383
- this.nodeRegistry[nodeType.id] = nodeType;
384
-
385
- Vue.component(nodeType.id, nodeType.component);
386
- this.nodeTypes.push(nodeType);
387
-
388
- const types = Array.isArray(nodeType.bpmnType)
389
- ? nodeType.bpmnType
390
- : [nodeType.bpmnType];
391
-
392
- types.forEach(bpmnType => {
393
- if (!this.parsers[bpmnType]) {
394
- this.parsers[bpmnType] = { custom: [], implementation: [], default: []};
395
- }
396
-
397
- if (customParser) {
398
- this.parsers[bpmnType].custom.push(customParser);
399
- return;
400
- }
401
-
402
- if (nodeType.implementation) {
403
- this.parsers[bpmnType].implementation.push(implementationParser);
404
- return;
405
- }
406
-
407
- this.parsers[bpmnType].default.push(defaultParser);
408
- });
409
- },
410
- addMessageFlows() {
411
- if (this.collaboration) {
412
- this.collaboration
413
- .get('messageFlows')
414
- .filter(this.hasSourceAndTarget)
415
- .forEach(this.setNode);
416
- }
417
- },
418
- loadAssociations(flowElements, artifacts) {
419
- artifacts
420
- .filter(definition => definition.$type === 'bpmn:Association' && this.hasSourceAndTarget(definition))
421
- .forEach(definition => this.setNode(definition, flowElements, artifacts));
422
- },
423
- loadDataAssociations(flowElements) {
424
- const tasksThatHaveDataOutputAssociations = flowElements.filter(task => task.get('dataOutputAssociations') &&
425
- task.get('dataOutputAssociations').length > 0);
426
-
427
- tasksThatHaveDataOutputAssociations.forEach(task => {
428
- task.get('dataOutputAssociations').forEach(dataAssociationLink => {
429
- this.setNode(dataAssociationLink, flowElements);
430
- });
431
- });
432
-
433
- const tasksThatHaveDataInputAssociations = flowElements.filter(task => task.get('dataInputAssociations') &&
434
- task.get('dataInputAssociations').length > 0);
435
-
436
- tasksThatHaveDataInputAssociations.forEach(task => {
437
- task.get('dataInputAssociations').forEach(dataAssociationLink => {
438
- this.setNode(dataAssociationLink, flowElements);
439
- });
440
- });
441
- },
442
- loadArtifacts(flowElements, artifacts) {
443
- artifacts
444
- .filter(definition => definition.$type !== 'bpmn:Association')
445
- .forEach(definition => this.setNode(definition, flowElements, artifacts));
446
- },
447
- loadSequenceFlows(flowElements, artifacts) {
448
- flowElements
449
- .filter(definition => definition.$type === 'bpmn:SequenceFlow' && this.hasSourceAndTarget(definition))
450
- .forEach(definition => this.setNode(definition, flowElements, artifacts));
451
- },
452
- loadFlowElements(flowElements, artifacts) {
453
- flowElements
454
- .filter(definition => definition.$type !== 'bpmn:SequenceFlow')
455
- .forEach(definition => this.setNode(definition, flowElements, artifacts));
456
- },
457
- addLanes(process) {
458
- if (process.get('laneSets')[0]) {
459
- process.laneSets[0].lanes.forEach(this.setNode);
460
- }
461
- },
462
- addPools() {
463
- if (!this.collaboration) {
464
- return;
465
- }
466
- this.collaboration.get('participants').forEach(this.setNode);
467
- },
468
- setUpDiagram() {
469
- this.processes.forEach(process => {
470
- this.ensureCancelActivityIsAddedToBoundaryEvents(process);
471
-
472
- this.addLanes(process);
473
-
474
- const flowElements = process.get('flowElements');
475
- const artifacts = process.get('artifacts');
476
-
477
- this.loadFlowElements(flowElements, artifacts);
478
- this.loadSequenceFlows(flowElements, artifacts);
479
- this.loadArtifacts(flowElements, artifacts);
480
- this.loadAssociations(flowElements, artifacts);
481
- this.loadDataAssociations(flowElements);
482
- });
483
-
484
- store.commit('setRootElements', this.definitions.rootElements);
485
-
486
- this.addMessageFlows();
487
-
488
- store.commit('highlightNode', this.processNode);
489
- },
490
- getCollaboration() {
491
- return this.definitions.rootElements.find(({ $type }) => $type === 'bpmn:Collaboration');
492
- },
493
- getProcesses() {
494
- return this.definitions.rootElements.filter(({ $type }) => $type === 'bpmn:Process');
495
- },
496
- getPlane() {
497
- return this.definitions.diagrams[0].plane;
498
- },
499
- getPlaneElements() {
500
- return this.plane.get('planeElement');
501
- },
502
- parse() {
503
- this.collaboration = this.getCollaboration();
504
- this.processes = this.getProcesses();
505
- this.plane = this.getPlane();
506
- this.planeElements = this.getPlaneElements();
507
-
508
- this.cleanPlaneElements();
509
-
510
- this.processNode = new Node(
511
- 'processmaker-modeler-process',
512
- this.processes[0],
513
- this.planeElements.find(diagram => diagram.bpmnElement.id === this.processes[0].id),
514
- );
515
- },
516
- removeUnsupportedElementAttributes(definition) {
517
- const unsupportedElements = ['extensionElements'];
518
-
519
- unsupportedElements.filter(name => definition.get(name))
520
- .forEach(name => definition.set(name, undefined));
521
- },
522
- getCustomParser(definition) {
523
- const parsers = this.parsers[(definition.$type)];
524
-
525
- if (!parsers) {
526
- return;
527
- }
528
-
529
- const customParser = parsers.custom.find(parser => parser(definition, this.moddle));
530
- const implementationParser = parsers.implementation.find(parser => parser(definition, this.moddle));
531
- const defaultParser = parsers.default.find(parser => parser(definition, this.moddle));
532
-
533
- return customParser || implementationParser || defaultParser;
534
- },
535
- handleUnsupportedElement(bpmnType, flowElements, definition, artifacts, diagram) {
536
- pull(flowElements, definition);
537
- pull(artifacts, definition);
538
- pull(this.planeElements, diagram);
539
- if (this.collaboration) {
540
- pull(this.collaboration.get('messageFlows'), definition);
541
- }
542
-
543
- const incomingFlows = definition.get('incoming');
544
- if (incomingFlows) {
545
- pull(flowElements, incomingFlows);
546
- }
547
-
548
- const outgoingFlows = definition.get('outgoing');
549
- if (outgoingFlows) {
550
- pull(flowElements, outgoingFlows);
551
- }
552
- },
553
- setNode(definition, flowElements, artifacts) {
554
- const diagram = this.planeElements.find(diagram => diagram.bpmnElement.id === definition.id);
555
- const bpmnType = definition.$type;
556
- const parser = this.getCustomParser(definition);
557
-
558
- if (!parser) {
559
- this.handleUnsupportedElement(bpmnType, flowElements, definition, artifacts, diagram);
560
- return;
561
- }
562
-
563
- this.removeUnsupportedElementAttributes(definition);
564
- const type = parser(definition, this.moddle);
565
-
566
- const unnamedElements = ['bpmn:TextAnnotation', 'bpmn:Association', 'bpmn:DataOutputAssociation', 'bpmn:DataInputAssociation'];
567
- const requireName = unnamedElements.indexOf(bpmnType) === -1;
568
- if (requireName && !definition.get('name')) {
569
- definition.set('name', '');
570
- }
571
-
572
- const node = this.createNode(type, definition, diagram);
573
-
574
- store.commit('addNode', node);
575
- },
576
- createNode(type, definition, diagram) {
577
- if (Node.isTimerType(type)) {
578
- return new TimerEventNode(type, definition, diagram);
579
- }
580
- // Remove undefined or null properties
581
- Object.keys(definition).forEach(key => {
582
- if (definition[key] === undefined || definition[key] === null) {
583
- delete definition[key];
584
- }
585
- });
586
- return new Node(type, definition, diagram);
587
- },
588
- hasSourceAndTarget(definition) {
589
- const hasSource = definition.sourceRef && this.parsers[definition.sourceRef.$type];
590
- const hasTarget = definition.targetRef && this.parsers[definition.targetRef.$type];
591
-
592
- return hasSource && hasTarget;
593
- },
594
- async waitForCursorToChange() {
595
- const cursorWaitTime = 300;
596
- await this.$nextTick();
597
- return new Promise(resolve => setTimeout(resolve, cursorWaitTime));
598
- },
599
- async renderPaper() {
600
- this.isRendering = true;
601
- await this.paperManager.performAtomicAction(async() => {
602
- await this.waitForCursorToChange();
603
- this.parse();
604
- this.addPools();
605
- this.setUpDiagram();
606
- });
607
- await this.paperManager.awaitScheduledUpdates();
608
- this.isRendering = false;
609
- this.$emit('parsed');
610
- },
611
- async loadXML(xml = null) {
612
- let emitChangeEvent = false;
613
- if (xml === null) {
614
- xml = this.currentXML;
615
- emitChangeEvent = true;
616
- }
617
- this.definitions = await this.xmlManager.getDefinitionsFromXml(xml);
618
- this.xmlManager.definitions = this.definitions;
619
- this.nodeIdGenerator = getNodeIdGenerator(this.definitions);
620
- store.commit('clearNodes');
621
- await this.renderPaper();
622
- if (emitChangeEvent) {
623
- window.ProcessMaker.EventBus.$emit('modeler-change');
624
- }
625
- },
626
- getBoundaryEvents(process) {
627
- return process.get('flowElements').filter(({ $type }) => $type === 'bpmn:BoundaryEvent');
628
- },
629
- createBoundaryEvent(definition) {
630
- const boundaryEvent = boundaryEventConfig.definition(this.moddle, this.$t);
631
- boundaryEvent.set('id', definition.get('id'));
632
- boundaryEvent.set('name', definition.get('name'));
633
- boundaryEvent.set('eventDefinitions', definition.get('eventDefinitions'));
634
- boundaryEvent.set('cancelActivity', definition.get('cancelActivity'));
635
- boundaryEvent.set('attachedToRef', definition.get('attachedToRef'));
636
- boundaryEvent.set('color', definition.get('color'));
637
- boundaryEvent.$parent = definition.$parent;
638
- if (definition.get('outgoing').length > 0) {
639
- boundaryEvent.set('outgoing', definition.get('outgoing'));
640
- }
641
- return boundaryEvent;
642
- },
643
- ensureCancelActivityIsAddedToBoundaryEvents(process) {
644
- this.getBoundaryEvents(process).forEach(definition => {
645
- const boundaryEvent = this.createBoundaryEvent(definition);
646
- definition.get('outgoing').forEach(outgoing => outgoing.set('sourceRef', boundaryEvent));
647
- this.replaceDefinition(definition, boundaryEvent, process);
648
- });
649
- },
650
- replaceDefinition(definition, boundaryEvent, process) {
651
- const definitionIndex = process.get('flowElements').indexOf(definition);
652
- process.flowElements[definitionIndex] = boundaryEvent;
653
- const boundaryEventDiagram = this.planeElements.find((diagram) => {
654
- return diagram.bpmnElement === definition;
655
- });
656
- boundaryEventDiagram.bpmnElement = boundaryEvent;
657
- },
658
- toXML(cb) {
659
- this.moddle.toXML(this.definitions, { format: true }, cb);
660
- },
661
- async handleDrop({ clientX, clientY, control, nodeThatWillBeReplaced }) {
662
- this.validateDropTarget({ clientX, clientY, control });
663
-
664
- if (!this.allowDrop) {
665
- return;
666
- }
667
-
668
- const definition = this.nodeRegistry[control.type].definition(this.moddle, this.$t);
669
-
670
- const diagram = this.nodeRegistry[control.type].diagram(this.moddle);
671
-
672
- const { x, y } = this.paperManager.clientToGridPoint(clientX, clientY);
673
- diagram.bounds.x = x;
674
- diagram.bounds.y = y;
675
-
676
- const newNode = this.createNode(control.type, definition, diagram);
677
-
678
- if (newNode.isBpmnType('bpmn:BoundaryEvent')) {
679
- this.setShapeCenterUnderCursor(diagram);
680
- }
681
-
682
- this.highlightNode(newNode);
683
- await this.addNode(newNode);
684
- if (!nodeThatWillBeReplaced) {
685
- return;
686
- }
687
-
688
- const nodeMigrator = new NodeMigrator(
689
- nodeThatWillBeReplaced,
690
- definition,
691
- this.graph,
692
- newNode,
693
- this.processes,
694
- this.collaboration,
695
- );
696
- nodeMigrator.migrate();
697
-
698
- return newNode;
699
- },
700
- setShapeCenterUnderCursor(diagram) {
701
- diagram.bounds.x -= (diagram.bounds.width / 2);
702
- diagram.bounds.y -= (diagram.bounds.height / 2);
703
- },
704
- async selectNewNode(node) {
705
- await this.$nextTick();
706
- await this.paperManager.awaitScheduledUpdates();
707
- const newNodeComponent = this.$refs.nodeComponent.find(component => component.node === node);
708
- const view = newNodeComponent.shapeView;
709
- await this.$refs.selector.selectElement(view);
710
- },
711
- async addNode(node) {
712
- if (!node.pool) {
713
- node.pool = this.poolTarget;
714
- }
715
-
716
- const targetProcess = node.getTargetProcess(this.processes, this.processNode);
717
- addNodeToProcess(node, targetProcess);
718
- node.setIds(this.nodeIdGenerator);
719
-
720
- this.planeElements.push(node.diagram);
721
- store.commit('addNode', node);
722
- this.poolTarget = null;
723
-
724
- // add processmaker-modeler-generic-flow
725
- if ([
726
- sequenceFlowId,
727
- laneId,
728
- associationId,
729
- messageFlowId,
730
- dataOutputAssociationFlowId,
731
- dataInputAssociationFlowId,
732
- genericFlowId,
733
- ].includes(node.type)) {
734
- return;
735
- }
736
-
737
- // Select the node after it has been added to the store (does not apply to flows)
738
- this.selectNewNode(node);
739
- },
740
- async addClonedNodes(nodes) {
741
- nodes.forEach(node => {
742
- if (!node.pool) {
743
- node.pool = this.poolTarget;
744
- }
745
-
746
- const targetProcess = node.getTargetProcess(this.processes, this.processNode);
747
- addNodeToProcess(node, targetProcess);
748
-
749
- this.planeElements.push(node.diagram);
750
- store.commit('addNode', node);
751
- this.poolTarget = null;
752
- });
753
- },
754
- handleResize() {
755
- const { clientWidth, clientHeight } = this.$el.parentElement;
756
- this.parentWidth = clientWidth + 'px';
757
- this.parentHeight = clientHeight + 'px';
758
-
759
- this.paperManager.setPaperDimensions(clientWidth, clientHeight);
760
- },
761
- validateDropTarget({ clientX, clientY, control }) {
762
- const { allowDrop, poolTarget } = getValidationProperties(clientX, clientY, control, this.paperManager.paper, this.graph, this.collaboration, this.$refs['paper-container']);
763
- this.allowDrop = allowDrop;
764
- this.poolTarget = poolTarget;
765
- },
766
- isBpmnNode(shape) {
767
- return shape.component != null;
768
- },
769
- setShapeStacking(shape) {
770
- if (this.isRendering || (!shape.component.node.isType('processmaker-modeler-pool') && shape === this.previouslyStackedShape)) {
771
- return;
772
- }
773
-
774
- this.previouslyStackedShape = shape;
775
- this.paperManager.performAtomicAction(() => ensureShapeIsNotCovered(shape, this.graph));
776
- },
777
- clearSelection(){
778
- this.$refs.selector.clearSelection();
779
- },
780
- isPointInSelection(event) {
781
- const selector = this.$refs.selector.$el;
782
- if (typeof selector.getBoundingClientRect === 'function') {
783
- // check if mouse was clicked inside the selector
784
- const { x: sx, y: sy, width:swidth, height: sheight } = selector.getBoundingClientRect();
785
- if (event.clientX >= sx && event.clientX <= sx + swidth && event.clientY >= sy && event.clientY <= sy + sheight) {
786
- return true;
787
- }
788
- }
789
- return false;
790
- },
791
- async pointerDownInShape(event, element) {
792
- const { clientX: x, clientY: y } = event;
793
- const shapeView = this.paper.findViewByModel(element);
794
- this.isDragging = false;
795
- this.isSelecting = false;
796
- this.isIntoTheSelection = false;
797
- this.dragStart = { x, y };
798
- // Verify if is in the selection box
799
- if (this.isPointInSelection(event)) {
800
- this.isIntoTheSelection = true;
801
- } else {
802
- if (!event.shiftKey) {
803
- await this.$refs.selector.selectElement(shapeView);
804
- await this.$nextTick();
805
- }
806
- }
807
- this.$refs.selector.startDrag({
808
- clientX: event.clientX,
809
- clientY: event.clientY,
810
- });
811
- },
812
- pointerUpHandler(event, cellView) {
813
- // is clicked over the shape
814
- if (cellView) {
815
- this.$refs.selector.selectElement(cellView);
816
- } else {
817
- this.clearSelection();
818
- }
819
-
820
- this.isDragging = false;
821
- this.dragStart = null;
822
- this.isSelecting = false;
823
- },
824
- },
825
- created() {
826
- if (runningInCypressTest()) {
827
- /* Add reference to store on window; this is used in testing to verify rendered nodes */
828
- window.store = store;
829
- }
830
-
831
- this.$t = this.$t.bind(this);
832
- /**
833
- * Before Initialize the BpmnModdle and its extensions.
834
- * In this stage the node components were not yet registered,
835
- * so they could be extended.
836
- */
837
- window.ProcessMaker.EventBus.$emit('modeler-before-init', {
838
- registerComponentMixin: this.registerComponentMixin,
839
- });
840
-
841
- this.registerNode(Process);
842
- /* Initialize the BpmnModdle and its extensions */
843
- window.ProcessMaker.EventBus.$emit('modeler-init', {
844
- registerInspectorExtension,
845
- registerBpmnExtension: this.registerBpmnExtension,
846
- registerNode: this.registerNode,
847
- registerStatusBar: this.registerStatusBar,
848
- });
849
-
850
- this.moddle = new BpmnModdle(this.extensions);
851
- this.linter = new Linter(linterConfig);
852
- this.xmlManager = new XMLManager(this.moddle);
853
- this.$emit('set-xml-manager', this.xmlManager);
854
- },
855
- mounted() {
856
- store.commit('setReadOnly', this.readOnly);
857
-
858
- this.graph = new dia.Graph();
859
- store.commit('setGraph', this.graph);
860
- this.graph.set('interactiveFunc', cellView => {
861
- const isPoolEdge = cellView.model.get('type') === 'standard.EmbeddedImage';
862
- return {
863
- elementMove: isPoolEdge,
864
- labelMove: false,
865
- };
866
- });
867
-
868
- this.paperManager = PaperManager.factory(this.$refs.paper, this.graph.get('interactiveFunc'), this.graph);
869
- this.paper = this.paperManager.paper;
870
-
871
- this.paperManager.addEventHandler('cell:pointerdblclick', focusNameInputAndHighlightLabel);
872
-
873
- this.handleResize();
874
- window.addEventListener('resize', this.handleResize);
875
-
876
- store.commit('setPaper', this.paperManager.paper);
877
-
878
- this.paperManager.addEventHandler('element:pointerclick', this.blurFocusedScreenBuilderElement, this);
879
-
880
- this.paperManager.addEventHandler('blank:pointerdown', (event, x, y) => {
881
- const scale = this.paperManager.scale;
882
- this.canvasDragPosition = { x: x * scale.sx, y: y * scale.sy };
883
- this.isGrabbing = true;
884
- }, this);
885
-
886
- this.paperManager.addEventHandler('cell:mouseover element:mouseover', ({ model: shape }) => {
887
- if (this.isBpmnNode(shape) && shape.attr('body/cursor') !== 'default' && !this.isGrabbing) {
888
- shape.attr('body/cursor', 'move');
889
- }
890
- // If the user is panning the Paper while hovering an element, ignore the default move cursor
891
- if (this.isGrabbing && this.isBpmnNode(shape)) {
892
- shape.attr('body/cursor', 'grabbing');
893
- }
894
- });
895
- this.paperManager.addEventHandler('blank:pointerup', (event) => {
896
- this.canvasDragPosition = null;
897
- this.isGrabbing = false;
898
- this.activeNode = null;
899
- this.pointerUpHandler(event);
900
- }, this);
901
-
902
- this.paperManager.addEventHandler('cell:pointerup', (cellView, event) => {
903
- this.canvasDragPosition = null;
904
- this.activeNode = null;
905
- this.pointerUpHandler(event, cellView);
906
- }, this);
907
-
908
- this.$el.addEventListener('mousemove', event => {
909
- if (this.canvasDragPosition) {
910
- this.paperManager.translate(
911
- event.offsetX - this.canvasDragPosition.x,
912
- event.offsetY - this.canvasDragPosition.y,
913
- );
914
- }
915
- }, this);
916
-
917
- this.$el.addEventListener('mouseenter', () => {
918
- store.commit('setClientLeftPaper', false);
919
- });
920
-
921
- this.$el.addEventListener('mouseleave', () => {
922
- this.paperManager.removeEventHandler('blank:pointermove');
923
- store.commit('setClientLeftPaper', true);
924
- });
925
-
926
- this.paperManager.addEventHandler('cell:pointerclick', (cellView, evt, x, y) => {
927
- const clickHandler = cellView.model.get('onClick');
928
- if (clickHandler) {
929
- clickHandler(cellView, evt, x, y);
930
- }
931
- });
932
-
933
- this.paperManager.addEventHandler('cell:pointerclick', ({ model: shape }, event) => {
934
- if (!this.isBpmnNode(shape)) {
935
- return;
936
- }
937
-
938
- // ignore click event if the user is grabbing the paper.
939
- if (this.isGrabbing) {
940
- return;
941
- }
942
-
943
- shape.component.$emit('click', event);
944
- this.$emit('click', {
945
- event,
946
- node: this.highlightedNode.definition,
947
- });
948
- });
949
-
950
- this.paperManager.addEventHandler('cell:pointerdown', ({ model: shape }, event) => {
951
- if (!this.isBpmnNode(shape)) {
952
- return;
953
- }
954
- // If the user is pressing Space (grabbing) and clicking on a Cell, return
955
- if (this.isGrabbing) {
956
- return;
957
- }
958
- this.setShapeStacking(shape);
959
- this.activeNode = shape.component.node;
960
- this.isOverShape = true;
961
- this.pointerDownInShape(event, shape);
962
- });
963
- // If the user is grabbing the paper while he clicked in a cell, move the paper and not the cell
964
- this.paperManager.addEventHandler('cell:pointermove', (_, event, x, y) => {
965
- if (this.isGrabbing) {
966
- if (!this.canvasDragPosition) {
967
- const scale = this.paperManager.scale;
968
- this.canvasDragPosition = { x: x * scale.sx, y: y * scale.sy };
969
- }
970
- if (this.canvasDragPosition && !this.clientLeftPaper) {
971
- this.paperManager.translate(
972
- event.offsetX - this.canvasDragPosition.x,
973
- event.offsetY - this.canvasDragPosition.y
974
- );
975
- }
976
- }
977
- });
978
-
979
- /* Register custom nodes */
980
- window.ProcessMaker.EventBus.$emit('modeler-start', {
981
- loadXML: async(xml) => {
982
- await this.loadXML(xml);
983
- },
984
- });
985
- },
986
- };
987
- </script>
988
- <style lang="scss" src="./modeler.scss" />
989
- <style lang="scss">
990
- svg {
991
- overflow: visible !important;
992
- }
993
-
994
- .rail {
995
- &-container {
996
- position: relative;
997
- bottom: 60px;
998
- display: inline-block;
999
- height: 48px;
1000
- max-height: 48px;
1001
- z-index: 2;
1002
- }
1003
-
1004
- &-left {
1005
- position: absolute;
1006
- display: inline;
1007
- width: auto;
1008
- padding: 0 12px;
1009
- }
1010
- }
1011
- </style>