bpmn-js 18.13.0 → 18.13.2
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/assets/diagram-js.css +4 -0
- package/dist/bpmn-modeler.development.js +316 -140
- package/dist/bpmn-modeler.production.min.js +45 -45
- package/dist/bpmn-navigated-viewer.development.js +76 -91
- package/dist/bpmn-navigated-viewer.production.min.js +5 -5
- package/dist/bpmn-viewer.development.js +76 -91
- package/dist/bpmn-viewer.production.min.js +5 -5
- package/lib/features/copy-paste/BpmnCopyPaste.js +17 -0
- package/lib/features/modeling/BpmnLayouter.js +21 -4
- package/lib/features/modeling/behavior/SubProcessPlaneBehavior.js +140 -30
- package/lib/features/modeling/behavior/ToggleCollapseConnectionBehaviour.js +8 -1
- package/lib/util/AnnotationUtil.d.ts +26 -0
- package/lib/util/AnnotationUtil.js +55 -0
- package/package.json +3 -3
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
is
|
|
5
5
|
} from '../../util/ModelUtil';
|
|
6
6
|
|
|
7
|
+
import { collectElementsAnnotations } from '../../util/AnnotationUtil';
|
|
8
|
+
|
|
7
9
|
import {
|
|
8
10
|
forEach,
|
|
9
11
|
isArray,
|
|
@@ -170,6 +172,21 @@ export default function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) {
|
|
|
170
172
|
}
|
|
171
173
|
});
|
|
172
174
|
|
|
175
|
+
eventBus.on('copyPaste.createTree', function(context) {
|
|
176
|
+
var element = context.element,
|
|
177
|
+
children = context.children;
|
|
178
|
+
|
|
179
|
+
if (!is(element, 'bpmn:SubProcess')) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// add TextAnnotations to copy the closure,
|
|
184
|
+
// since by default they are children of a global process, not subprocess
|
|
185
|
+
forEach(collectElementsAnnotations(children), (entry) => {
|
|
186
|
+
children.push(entry.annotation);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
173
190
|
// resolve references
|
|
174
191
|
|
|
175
192
|
eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function(context) {
|
|
@@ -467,17 +467,34 @@ function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, atta
|
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
-
// attached to either top-right, top-left, bottom-right or bottom-left corner
|
|
471
|
-
//
|
|
470
|
+
// attached to either top-right, top-left, bottom-right or bottom-left corner,
|
|
471
|
+
// or strictly above/below or left/right of the target. In the corner case,
|
|
472
|
+
// the orientation is compared on the counter-axis to decide the layout.
|
|
473
|
+
|
|
474
|
+
var verticalAttachOrientation = getVerticalOrientation(attachOrientation),
|
|
475
|
+
horizontalAttachOrientation = getHorizontalOrientation(attachOrientation),
|
|
476
|
+
verticalTargetOrientation = getVerticalOrientation(targetOrientation),
|
|
477
|
+
horizontalTargetOrientation = getHorizontalOrientation(targetOrientation);
|
|
478
|
+
|
|
479
|
+
// If the target is strictly above/below (no horizontal orientation)
|
|
480
|
+
if (verticalTargetOrientation && !horizontalTargetOrientation) {
|
|
481
|
+
return 'v';
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// If the target is strictly left/right (no vertical orientation)
|
|
485
|
+
if (horizontalTargetOrientation && !verticalTargetOrientation) {
|
|
486
|
+
return 'h';
|
|
487
|
+
}
|
|
488
|
+
|
|
472
489
|
|
|
473
490
|
if (isHorizontal) {
|
|
474
|
-
if (isSame(
|
|
491
|
+
if (isSame(verticalAttachOrientation, verticalTargetOrientation)) {
|
|
475
492
|
return 'h';
|
|
476
493
|
} else {
|
|
477
494
|
return 'v';
|
|
478
495
|
}
|
|
479
496
|
} else {
|
|
480
|
-
if (isSame(
|
|
497
|
+
if (isSame(horizontalAttachOrientation, horizontalTargetOrientation)) {
|
|
481
498
|
return 'v';
|
|
482
499
|
} else {
|
|
483
500
|
return 'h';
|
|
@@ -2,15 +2,20 @@ import inherits from 'inherits-browser';
|
|
|
2
2
|
|
|
3
3
|
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
|
4
4
|
|
|
5
|
-
import { find } from 'min-dash';
|
|
5
|
+
import { find, forEach } from 'min-dash';
|
|
6
6
|
|
|
7
7
|
import { isExpanded } from '../../../util/DiUtil';
|
|
8
8
|
|
|
9
|
+
import {
|
|
10
|
+
collectElementsAnnotations,
|
|
11
|
+
getElementAnnotations
|
|
12
|
+
} from '../../../util/AnnotationUtil';
|
|
13
|
+
|
|
9
14
|
import { getBusinessObject, getDi, is } from '../../../util/ModelUtil';
|
|
10
15
|
|
|
11
16
|
import { getMid } from 'diagram-js/lib/layout/LayoutUtil';
|
|
12
17
|
|
|
13
|
-
import { getBBox } from 'diagram-js/lib/util/Elements';
|
|
18
|
+
import { getBBox, selfAndChildren } from 'diagram-js/lib/util/Elements';
|
|
14
19
|
|
|
15
20
|
import {
|
|
16
21
|
getPlaneIdFromShape,
|
|
@@ -41,7 +46,6 @@ var DEFAULT_POSITION = {
|
|
|
41
46
|
y: 160
|
|
42
47
|
};
|
|
43
48
|
|
|
44
|
-
|
|
45
49
|
/**
|
|
46
50
|
* Creates bpmndi:BPMNPlane elements and canvas planes when collapsed subprocesses are created.
|
|
47
51
|
*
|
|
@@ -107,17 +111,26 @@ export default function SubProcessPlaneBehavior(
|
|
|
107
111
|
}, true);
|
|
108
112
|
|
|
109
113
|
|
|
110
|
-
this.postExecuted('
|
|
111
|
-
var
|
|
112
|
-
rootElement = context.newRootElement;
|
|
114
|
+
this.postExecuted('elements.create', function(context) {
|
|
115
|
+
var elements = context.elements;
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
forEach(elements, function(element) {
|
|
118
|
+
if (!isCollapsedSubProcess(element)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var rootElement = elementRegistry.get(getPlaneIdFromShape(element));
|
|
123
|
+
|
|
124
|
+
if (!rootElement || !element.children || !element.children.length) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
117
127
|
|
|
118
|
-
|
|
128
|
+
var children = getSubProcessChildren(element);
|
|
119
129
|
|
|
120
|
-
|
|
130
|
+
self._showRecursively(children);
|
|
131
|
+
|
|
132
|
+
self._moveChildrenToShape(children, rootElement);
|
|
133
|
+
});
|
|
121
134
|
}, true);
|
|
122
135
|
|
|
123
136
|
|
|
@@ -131,6 +144,20 @@ export default function SubProcessPlaneBehavior(
|
|
|
131
144
|
}, true);
|
|
132
145
|
|
|
133
146
|
|
|
147
|
+
// remove annotations connected to elements inside the subprocess
|
|
148
|
+
this.preExecute('shape.delete', function(context) {
|
|
149
|
+
var shape = context.shape;
|
|
150
|
+
|
|
151
|
+
if (!is(shape, 'bpmn:SubProcess') || !isExpanded(shape)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
forEach(collectElementsAnnotations([ shape ]), (entry) => {
|
|
156
|
+
modeling.removeShape(entry.annotation);
|
|
157
|
+
});
|
|
158
|
+
}, true);
|
|
159
|
+
|
|
160
|
+
|
|
134
161
|
this.preExecuted('shape.delete', function(context) {
|
|
135
162
|
var shape = context.shape;
|
|
136
163
|
if (!isCollapsedSubProcess(shape)) {
|
|
@@ -336,11 +363,27 @@ export default function SubProcessPlaneBehavior(
|
|
|
336
363
|
|
|
337
364
|
if (!isExpanded(shape)) {
|
|
338
365
|
|
|
339
|
-
//
|
|
340
|
-
|
|
366
|
+
// if an annotation is attached to both the sub-process and elements inside it,
|
|
367
|
+
// remove the inner associations, keeping only connections at the sub-process level,
|
|
368
|
+
// since we can't keep both after collapsing
|
|
369
|
+
self._disconnectSharedAnnotations(shape);
|
|
370
|
+
|
|
371
|
+
var children = getSubProcessChildren(shape);
|
|
372
|
+
|
|
373
|
+
self._moveChildrenToShape(children, rootElement);
|
|
341
374
|
|
|
342
375
|
} else {
|
|
343
|
-
self._moveChildrenToShape(rootElement, shape);
|
|
376
|
+
self._moveChildrenToShape(rootElement.children.slice(), shape);
|
|
377
|
+
|
|
378
|
+
// annotations live at process level by design;
|
|
379
|
+
// move them back from the sub-process to the process root
|
|
380
|
+
forEach(collectElementsAnnotations(shape.children), (entry) => {
|
|
381
|
+
modeling.moveShape(entry.annotation, { x: 0, y: 0 }, shape.parent);
|
|
382
|
+
|
|
383
|
+
forEach(entry.associations, (association) => {
|
|
384
|
+
modeling.moveConnection(association, { x: 0, y: 0 }, shape.parent);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
344
387
|
}
|
|
345
388
|
}, true);
|
|
346
389
|
|
|
@@ -410,33 +453,21 @@ export default function SubProcessPlaneBehavior(
|
|
|
410
453
|
inherits(SubProcessPlaneBehavior, CommandInterceptor);
|
|
411
454
|
|
|
412
455
|
/**
|
|
413
|
-
* Moves the
|
|
456
|
+
* Moves the given elements to the target.
|
|
414
457
|
*
|
|
415
458
|
* If the target is a plane, the children are moved to the top left corner.
|
|
416
459
|
* Otherwise, the center of the target is used.
|
|
417
460
|
*
|
|
418
|
-
* @param {
|
|
461
|
+
* @param {Element[]} children
|
|
419
462
|
* @param {Root} target
|
|
420
463
|
*/
|
|
421
|
-
SubProcessPlaneBehavior.prototype._moveChildrenToShape = function(
|
|
464
|
+
SubProcessPlaneBehavior.prototype._moveChildrenToShape = function(children, target) {
|
|
422
465
|
var modeling = this._modeling;
|
|
423
466
|
|
|
424
|
-
|
|
425
|
-
var offset;
|
|
426
|
-
|
|
427
|
-
if (!children) {
|
|
467
|
+
if (!children.length) {
|
|
428
468
|
return;
|
|
429
469
|
}
|
|
430
470
|
|
|
431
|
-
// add external labels that weren't children of sub process
|
|
432
|
-
children = children.concat(children.reduce(function(labels, child) {
|
|
433
|
-
if (child.label && child.label.parent !== source) {
|
|
434
|
-
return labels.concat(child.label);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return labels;
|
|
438
|
-
}, []));
|
|
439
|
-
|
|
440
471
|
// only change plane if there are no visible children, but don't move them
|
|
441
472
|
var visibleChildren = children.filter(function(child) {
|
|
442
473
|
return !child.hidden;
|
|
@@ -448,6 +479,7 @@ SubProcessPlaneBehavior.prototype._moveChildrenToShape = function(source, target
|
|
|
448
479
|
}
|
|
449
480
|
|
|
450
481
|
var childrenBounds = getBBox(visibleChildren);
|
|
482
|
+
var offset;
|
|
451
483
|
|
|
452
484
|
// target is a plane
|
|
453
485
|
if (!target.x) {
|
|
@@ -473,6 +505,32 @@ SubProcessPlaneBehavior.prototype._moveChildrenToShape = function(source, target
|
|
|
473
505
|
modeling.moveElements(children, offset, target, { autoResize: false });
|
|
474
506
|
};
|
|
475
507
|
|
|
508
|
+
/**
|
|
509
|
+
* Remove all associations between inner elements and annotations that are
|
|
510
|
+
* also connected to the sub-process itself.
|
|
511
|
+
*
|
|
512
|
+
* @param {Element} shape
|
|
513
|
+
*/
|
|
514
|
+
SubProcessPlaneBehavior.prototype._disconnectSharedAnnotations = function(shape) {
|
|
515
|
+
var modeling = this._modeling;
|
|
516
|
+
|
|
517
|
+
var sharedAnnotations = new Set(
|
|
518
|
+
getElementAnnotations(shape).map((entry) => entry.annotation)
|
|
519
|
+
);
|
|
520
|
+
|
|
521
|
+
if (!sharedAnnotations.size) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
forEach(collectElementsAnnotations(shape.children), (entry) => {
|
|
526
|
+
if (sharedAnnotations.has(entry.annotation)) {
|
|
527
|
+
forEach(entry.associations, (association) => {
|
|
528
|
+
modeling.removeConnection(association);
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
};
|
|
533
|
+
|
|
476
534
|
/**
|
|
477
535
|
* Sets `hidden` property on all children of the given shape.
|
|
478
536
|
*
|
|
@@ -586,3 +644,55 @@ SubProcessPlaneBehavior.$inject = [
|
|
|
586
644
|
'bpmnjs',
|
|
587
645
|
'elementRegistry'
|
|
588
646
|
];
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Collect text annotations and their associations connected to the given elements.
|
|
650
|
+
*
|
|
651
|
+
* @param {Element[]} elements
|
|
652
|
+
*
|
|
653
|
+
* @return {Element[]}
|
|
654
|
+
*/
|
|
655
|
+
function collectAnnotationElements(elements) {
|
|
656
|
+
var result = [];
|
|
657
|
+
|
|
658
|
+
forEach(collectElementsAnnotations(elements), (entry) => {
|
|
659
|
+
result.push(entry.annotation);
|
|
660
|
+
result.push.apply(result, entry.associations);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
return result;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Collect all children of a collapsed subprocess that need to be moved
|
|
668
|
+
* to or from its plane, including annotations and external labels that
|
|
669
|
+
* live at the process level by design(ref: https://github.com/camunda/camunda-modeler/issues/5163#issuecomment-3946571271)
|
|
670
|
+
*
|
|
671
|
+
* @param {Element} element
|
|
672
|
+
*
|
|
673
|
+
* @return {Element[]}
|
|
674
|
+
*/
|
|
675
|
+
function getSubProcessChildren(element) {
|
|
676
|
+
return element.children.slice()
|
|
677
|
+
.concat(collectAnnotationElements(element.children))
|
|
678
|
+
.concat(getExternalLabels(element));
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Returns external labels of the given element's children and their descendants
|
|
683
|
+
* that are not direct children of the element (i.e. parented elsewhere).
|
|
684
|
+
*
|
|
685
|
+
* @param {Element} element
|
|
686
|
+
*
|
|
687
|
+
* @return {Element[]}
|
|
688
|
+
*/
|
|
689
|
+
function getExternalLabels(element) {
|
|
690
|
+
return selfAndChildren(element.children || [], true, -1)
|
|
691
|
+
.reduce(function(labels, child) {
|
|
692
|
+
if (child.label && child.label.parent !== element) {
|
|
693
|
+
labels.push(child.label);
|
|
694
|
+
}
|
|
695
|
+
return labels;
|
|
696
|
+
}, []);
|
|
697
|
+
}
|
|
698
|
+
|
|
@@ -12,6 +12,8 @@ import { selfAndAllChildren } from 'diagram-js/lib/util/Elements';
|
|
|
12
12
|
|
|
13
13
|
import { isExpanded } from '../../../util/DiUtil';
|
|
14
14
|
|
|
15
|
+
import { is } from '../../../util/ModelUtil';
|
|
16
|
+
|
|
15
17
|
/**
|
|
16
18
|
* @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
|
|
17
19
|
* @typedef {import('../Modeling').default} Modeling
|
|
@@ -34,7 +36,6 @@ export default function ToggleCollapseConnectionBehaviour(
|
|
|
34
36
|
|
|
35
37
|
this.postExecuted('shape.toggleCollapse', 1500, function(context) {
|
|
36
38
|
|
|
37
|
-
// var shape = context.shape;
|
|
38
39
|
var shape = context.shape;
|
|
39
40
|
|
|
40
41
|
// only change connections when collapsing
|
|
@@ -65,6 +66,12 @@ export default function ToggleCollapseConnectionBehaviour(
|
|
|
65
66
|
return;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
// don't reconnect TextAnnotation connections,
|
|
70
|
+
// since they should stay connected and moved with its element to the subprocess plane
|
|
71
|
+
if (is(c, 'bpmn:Association') && (is(c.source, 'bpmn:TextAnnotation') || is(c.target, 'bpmn:TextAnnotation'))) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
68
75
|
if (incoming) {
|
|
69
76
|
modeling.reconnectEnd(c, shape, getMid(shape));
|
|
70
77
|
} else {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get text annotations connected to the given element.
|
|
3
|
+
*
|
|
4
|
+
* @param element
|
|
5
|
+
*
|
|
6
|
+
* @return
|
|
7
|
+
*/
|
|
8
|
+
export function getElementAnnotations(element: Element): {
|
|
9
|
+
annotation: Element;
|
|
10
|
+
association: Element;
|
|
11
|
+
}[];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Recursively collect text annotations connected to the given elements and their descendants.
|
|
15
|
+
* De-duplicates by annotation, collecting all associations per annotation.
|
|
16
|
+
*
|
|
17
|
+
* @param elements
|
|
18
|
+
*
|
|
19
|
+
* @return
|
|
20
|
+
*/
|
|
21
|
+
export function collectElementsAnnotations(elements: Element[]): {
|
|
22
|
+
annotation: Element;
|
|
23
|
+
associations: Element[];
|
|
24
|
+
}[];
|
|
25
|
+
|
|
26
|
+
type Element = import("../model/Types").Element;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { forEach } from 'min-dash';
|
|
2
|
+
import { selfAndChildren } from 'diagram-js/lib/util/Elements';
|
|
3
|
+
import { is } from './ModelUtil';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef { import('../model/Types').Element } Element
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get text annotations connected to the given element.
|
|
11
|
+
*
|
|
12
|
+
* @param {Element} element
|
|
13
|
+
*
|
|
14
|
+
* @return { { annotation: Element, association: Element }[] }
|
|
15
|
+
*/
|
|
16
|
+
export function getElementAnnotations(element) {
|
|
17
|
+
let result = [];
|
|
18
|
+
|
|
19
|
+
forEach(element.incoming, (connection) => {
|
|
20
|
+
if (is(connection, 'bpmn:Association') && is(connection.source, 'bpmn:TextAnnotation')) {
|
|
21
|
+
result.push({ annotation: connection.source, association: connection });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
forEach(element.outgoing, (connection) => {
|
|
26
|
+
if (is(connection, 'bpmn:Association') && is(connection.target, 'bpmn:TextAnnotation')) {
|
|
27
|
+
result.push({ annotation: connection.target, association: connection });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Recursively collect text annotations connected to the given elements and their descendants.
|
|
36
|
+
* De-duplicates by annotation, collecting all associations per annotation.
|
|
37
|
+
*
|
|
38
|
+
* @param {Element[]} elements
|
|
39
|
+
*
|
|
40
|
+
* @return { { annotation: Element, associations: Element[] }[] }
|
|
41
|
+
*/
|
|
42
|
+
export function collectElementsAnnotations(elements) {
|
|
43
|
+
const result = new Map();
|
|
44
|
+
|
|
45
|
+
forEach(selfAndChildren(elements, true, -1), (element) => {
|
|
46
|
+
forEach(getElementAnnotations(element), (entry) => {
|
|
47
|
+
if (!result.has(entry.annotation)) {
|
|
48
|
+
result.set(entry.annotation, { annotation: entry.annotation, associations: [] });
|
|
49
|
+
}
|
|
50
|
+
result.get(entry.annotation).associations.push(entry.association);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return [ ...result.values() ];
|
|
55
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bpmn-js",
|
|
3
|
-
"version": "18.13.
|
|
3
|
+
"version": "18.13.2",
|
|
4
4
|
"description": "A bpmn 2.0 toolkit and web modeler",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@rollup/plugin-json": "^6.1.0",
|
|
70
70
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
71
71
|
"@rollup/plugin-replace": "^6.0.3",
|
|
72
|
-
"@rollup/plugin-terser": "^0.
|
|
72
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
73
73
|
"babel-loader": "^10.0.0",
|
|
74
74
|
"babel-plugin-istanbul": "^7.0.1",
|
|
75
75
|
"bio-dts": "^0.11.0",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
},
|
|
112
112
|
"dependencies": {
|
|
113
113
|
"bpmn-moddle": "^10.0.0",
|
|
114
|
-
"diagram-js": "^15.
|
|
114
|
+
"diagram-js": "^15.10.0",
|
|
115
115
|
"diagram-js-direct-editing": "^3.3.0",
|
|
116
116
|
"ids": "^3.0.0",
|
|
117
117
|
"inherits-browser": "^0.1.0",
|