bpmn-js 9.0.0-subprocesses.1 → 9.0.1
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/CHANGELOG.md +46 -0
- package/dist/assets/bpmn-js.css +69 -14
- package/dist/assets/diagram-js.css +81 -78
- package/dist/bpmn-modeler.development.js +2897 -1810
- package/dist/bpmn-modeler.production.min.js +8 -8
- package/dist/bpmn-navigated-viewer.development.js +1458 -1101
- package/dist/bpmn-navigated-viewer.production.min.js +6 -6
- package/dist/bpmn-viewer.development.js +1457 -1100
- package/dist/bpmn-viewer.production.min.js +6 -6
- package/lib/BaseViewer.js +1 -1
- package/lib/Viewer.js +2 -2
- package/lib/draw/BpmnRenderer.js +303 -373
- package/lib/features/auto-resize/BpmnAutoResizeProvider.js +6 -0
- package/lib/features/copy-paste/BpmnCopyPaste.js +1 -0
- package/lib/features/di-ordering/BpmnDiOrdering.js +15 -11
- package/lib/features/drilldown/DrilldownBreadcrumbs.js +122 -0
- package/lib/features/drilldown/DrilldownCentering.js +118 -0
- package/lib/features/drilldown/DrilldownOverlayBehavior.js +181 -0
- package/lib/features/drilldown/SubprocessCompatibility.js +201 -0
- package/lib/features/drilldown/index.js +17 -0
- package/lib/features/label-editing/LabelEditingProvider.js +1 -1
- package/lib/features/label-editing/cmd/UpdateLabelHandler.js +29 -2
- package/lib/features/modeling/BpmnFactory.js +5 -1
- package/lib/features/modeling/BpmnUpdater.js +43 -1
- package/lib/features/modeling/ElementFactory.js +4 -0
- package/lib/features/modeling/behavior/CreateParticipantBehavior.js +59 -84
- package/lib/features/modeling/behavior/DropOnFlowBehavior.js +2 -2
- package/lib/features/modeling/behavior/RemoveEmbeddedLabelBoundsBehavior.js +34 -0
- package/lib/features/modeling/behavior/SubProcessPlaneBehavior.js +557 -0
- package/lib/features/modeling/behavior/ToggleCollapseConnectionBehaviour.js +74 -0
- package/lib/features/modeling/behavior/UnclaimIdBehavior.js +3 -1
- package/lib/features/modeling/behavior/index.js +27 -18
- package/lib/features/modeling/cmd/SetColorHandler.js +23 -6
- package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +4 -2
- package/lib/features/modeling/util/ModelingUtil.js +2 -20
- package/lib/features/ordering/BpmnOrderingProvider.js +3 -3
- package/lib/features/palette/PaletteProvider.js +1 -1
- package/lib/features/popup-menu/ReplaceMenuProvider.js +1 -1
- package/lib/import/BpmnImporter.js +17 -60
- package/lib/import/Importer.js +130 -10
- package/lib/util/DrilldownUtil.js +66 -0
- package/lib/util/ModelUtil.js +19 -0
- package/package.json +2 -2
- package/test/helper/index.js +1 -6
- package/lib/features/subprocess-navigation/SubprocessCentering.js +0 -55
- package/lib/features/subprocess-navigation/SubprocessCompatibility.js +0 -135
- package/lib/features/subprocess-navigation/SubprocessElements.js +0 -55
- package/lib/features/subprocess-navigation/SubprocessFlows.js +0 -109
- package/lib/features/subprocess-navigation/SubprocessOverlays.js +0 -104
- package/lib/features/subprocess-navigation/index.js +0 -18
|
@@ -33,6 +33,12 @@ BpmnAutoResizeProvider.$inject = [
|
|
|
33
33
|
*/
|
|
34
34
|
BpmnAutoResizeProvider.prototype.canResize = function(elements, target) {
|
|
35
35
|
|
|
36
|
+
// do not resize plane elements:
|
|
37
|
+
// root elements, collapsed sub-processes
|
|
38
|
+
if (is(target.di, 'bpmndi:BPMNPlane')) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
if (!is(target, 'bpmn:Participant') && !is(target, 'bpmn:Lane') && !(is(target, 'bpmn:SubProcess'))) {
|
|
37
43
|
return false;
|
|
38
44
|
}
|
|
@@ -2,6 +2,7 @@ import { getDi } from '../../util/ModelUtil';
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
filter,
|
|
5
|
+
forEach,
|
|
5
6
|
map
|
|
6
7
|
} from 'min-dash';
|
|
7
8
|
|
|
@@ -15,21 +16,24 @@ export default function BpmnDiOrdering(eventBus, canvas) {
|
|
|
15
16
|
eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi);
|
|
16
17
|
|
|
17
18
|
function orderDi() {
|
|
18
|
-
var
|
|
19
|
-
rootDi = getDi(root),
|
|
20
|
-
elements,
|
|
21
|
-
diElements;
|
|
19
|
+
var rootElements = canvas.getRootElements();
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
forEach(rootElements, function(root) {
|
|
22
|
+
var rootDi = getDi(root),
|
|
23
|
+
elements,
|
|
24
|
+
diElements;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
elements = selfAndAllChildren([ root ], false);
|
|
27
|
+
|
|
28
|
+
// only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane
|
|
29
|
+
elements = filter(elements, function(element) {
|
|
30
|
+
return element !== root && !element.labelTarget;
|
|
31
|
+
});
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
diElements = map(elements, getDi);
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
rootDi.set('planeElement', diElements);
|
|
36
|
+
});
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { domify, classes } from 'min-dom';
|
|
2
|
+
import { find } from 'min-dash';
|
|
3
|
+
|
|
4
|
+
import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
|
|
5
|
+
import { getBusinessObject, is } from '../../util/ModelUtil';
|
|
6
|
+
import {
|
|
7
|
+
getPlaneIdFromShape
|
|
8
|
+
} from '../../util/DrilldownUtil';
|
|
9
|
+
|
|
10
|
+
var OPEN_CLASS = 'bjs-breadcrumbs-shown';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Adds overlays that allow switching planes on collapsed subprocesses.
|
|
15
|
+
*
|
|
16
|
+
* @param {eventBus} eventBus
|
|
17
|
+
* @param {elementRegistry} elementRegistry
|
|
18
|
+
* @param {overlays} overlays
|
|
19
|
+
* @param {canvas} canvas
|
|
20
|
+
*/
|
|
21
|
+
export default function DrilldownBreadcrumbs(eventBus, elementRegistry, overlays, canvas) {
|
|
22
|
+
var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
|
|
23
|
+
var container = canvas.getContainer();
|
|
24
|
+
var containerClasses = classes(container);
|
|
25
|
+
container.appendChild(breadcrumbs);
|
|
26
|
+
|
|
27
|
+
var boParents = [];
|
|
28
|
+
|
|
29
|
+
// update breadcrumbs if name or ID of the primary shape changes
|
|
30
|
+
eventBus.on('element.changed', function(e) {
|
|
31
|
+
var shape = e.element,
|
|
32
|
+
bo = getBusinessObject(shape);
|
|
33
|
+
|
|
34
|
+
var isPresent = find(boParents, function(el) {
|
|
35
|
+
return el === bo;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (!isPresent) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
updateBreadcrumbs();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Updates the displayed breadcrumbs. If no element is provided, only the
|
|
47
|
+
* labels are updated.
|
|
48
|
+
*
|
|
49
|
+
* @param {djs.model.Base} [element]
|
|
50
|
+
*/
|
|
51
|
+
function updateBreadcrumbs(element) {
|
|
52
|
+
if (element) {
|
|
53
|
+
boParents = getBoParentChain(element);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var path = boParents.map(function(parent) {
|
|
57
|
+
var title = escapeHTML(parent.name || parent.id);
|
|
58
|
+
var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
|
|
59
|
+
|
|
60
|
+
var parentPlane = canvas.findRoot(getPlaneIdFromShape(parent)) || canvas.findRoot(parent.id);
|
|
61
|
+
|
|
62
|
+
// when the root is a collaboration, the process does not have a corresponding
|
|
63
|
+
// element in the elementRegisty. Instead, we search for the corresponding participant
|
|
64
|
+
if (!parentPlane && is(parent, 'bpmn:Process')) {
|
|
65
|
+
var participant = elementRegistry.find(function(element) {
|
|
66
|
+
var bo = getBusinessObject(element);
|
|
67
|
+
return bo && bo.processRef && bo.processRef === parent;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
parentPlane = canvas.findRoot(participant.id);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
link.addEventListener('click', function() {
|
|
74
|
+
canvas.setRootElement(parentPlane);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return link;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
breadcrumbs.innerHTML = '';
|
|
81
|
+
|
|
82
|
+
// show breadcrumbs and expose state to .djs-container
|
|
83
|
+
var visible = path.length > 1;
|
|
84
|
+
containerClasses.toggle(OPEN_CLASS, visible);
|
|
85
|
+
|
|
86
|
+
path.forEach(function(el) {
|
|
87
|
+
breadcrumbs.appendChild(el);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
eventBus.on('root.set', function(event) {
|
|
92
|
+
updateBreadcrumbs(event.element);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
// helpers //////////
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns the parents for the element using the business object chain,
|
|
104
|
+
* starting with the root element.
|
|
105
|
+
*
|
|
106
|
+
* @param {djs.model.Shape} child
|
|
107
|
+
*
|
|
108
|
+
* @returns {Array<djs.model.Shape>} parents
|
|
109
|
+
*/
|
|
110
|
+
function getBoParentChain(child) {
|
|
111
|
+
var bo = getBusinessObject(child);
|
|
112
|
+
|
|
113
|
+
var parents = [];
|
|
114
|
+
|
|
115
|
+
for (var element = bo; element; element = element.$parent) {
|
|
116
|
+
if (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Process')) {
|
|
117
|
+
parents.push(element);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return parents.reverse();
|
|
122
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { is } from '../../util/ModelUtil';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Move collapsed subprocesses into view when drilling down.
|
|
5
|
+
*
|
|
6
|
+
* Zoom and scroll are saved in a session.
|
|
7
|
+
*
|
|
8
|
+
* @param {eventBus} eventBus
|
|
9
|
+
* @param {canvas} canvas
|
|
10
|
+
*/
|
|
11
|
+
export default function DrilldownCentering(eventBus, canvas) {
|
|
12
|
+
|
|
13
|
+
var currentRoot = null;
|
|
14
|
+
var positionMap = new Map();
|
|
15
|
+
|
|
16
|
+
eventBus.on('root.set', function(event) {
|
|
17
|
+
var newRoot = event.element;
|
|
18
|
+
var currentViewbox = canvas.viewbox();
|
|
19
|
+
var storedViewbox = positionMap.get(newRoot);
|
|
20
|
+
|
|
21
|
+
positionMap.set(currentRoot, {
|
|
22
|
+
x: currentViewbox.x,
|
|
23
|
+
y: currentViewbox.y,
|
|
24
|
+
zoom: currentViewbox.scale
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
currentRoot = newRoot;
|
|
28
|
+
|
|
29
|
+
// current root was replaced with a collaboration, we don't update the viewbox
|
|
30
|
+
if (is(newRoot, 'bpmn:Collaboration') && !storedViewbox) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
storedViewbox = storedViewbox || { x: 0, y: 0, zoom: 1 };
|
|
35
|
+
|
|
36
|
+
var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
|
|
37
|
+
dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
|
|
38
|
+
|
|
39
|
+
if (dx !== 0 || dy !== 0) {
|
|
40
|
+
canvas.scroll({
|
|
41
|
+
dx: dx,
|
|
42
|
+
dy: dy
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (storedViewbox.zoom !== currentViewbox.scale) {
|
|
47
|
+
canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
eventBus.on('diagram.clear', function() {
|
|
52
|
+
positionMap.clear();
|
|
53
|
+
currentRoot = null;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
DrilldownCentering.$inject = [ 'eventBus', 'canvas' ];
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* ES5 Map implementation. Works.
|
|
63
|
+
*/
|
|
64
|
+
function Map() {
|
|
65
|
+
|
|
66
|
+
this._entries = [];
|
|
67
|
+
|
|
68
|
+
this.set = function(key, value) {
|
|
69
|
+
|
|
70
|
+
var found = false;
|
|
71
|
+
|
|
72
|
+
for (var k in this._entries) {
|
|
73
|
+
if (this._entries[k][0] === key) {
|
|
74
|
+
this._entries[k][1] = value;
|
|
75
|
+
|
|
76
|
+
found = true;
|
|
77
|
+
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!found) {
|
|
83
|
+
this._entries.push([ key, value ]);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
this.get = function(key) {
|
|
88
|
+
|
|
89
|
+
for (var k in this._entries) {
|
|
90
|
+
if (this._entries[k][0] === key) {
|
|
91
|
+
return this._entries[k][1];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return null;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
this.clear = function() {
|
|
99
|
+
this._entries.length = 0;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
this.remove = function(key) {
|
|
103
|
+
|
|
104
|
+
var idx = -1;
|
|
105
|
+
|
|
106
|
+
for (var k in this._entries) {
|
|
107
|
+
if (this._entries[k][0] === key) {
|
|
108
|
+
idx = k;
|
|
109
|
+
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (idx !== -1) {
|
|
115
|
+
this._entries.splice(idx, 1);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import inherits from 'inherits';
|
|
2
|
+
|
|
3
|
+
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
|
4
|
+
import { is } from '../../util/ModelUtil';
|
|
5
|
+
import { classes, domify } from 'min-dom';
|
|
6
|
+
import { getPlaneIdFromShape } from '../../util/DrilldownUtil';
|
|
7
|
+
|
|
8
|
+
var LOW_PRIORITY = 250;
|
|
9
|
+
var ARROW_DOWN_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.81801948,3.50735931 L10.4996894,9.1896894 L10.5,4 L12,4 L12,12 L4,12 L4,10.5 L9.6896894,10.4996894 L3.75735931,4.56801948 C3.46446609,4.27512627 3.46446609,3.80025253 3.75735931,3.50735931 C4.05025253,3.21446609 4.52512627,3.21446609 4.81801948,3.50735931 Z"/></svg>';
|
|
10
|
+
|
|
11
|
+
var EMPTY_MARKER = 'bjs-drilldown-empty';
|
|
12
|
+
|
|
13
|
+
export default function DrilldownOverlayBehavior(
|
|
14
|
+
canvas, eventBus, elementRegistry, overlays
|
|
15
|
+
) {
|
|
16
|
+
CommandInterceptor.call(this, eventBus);
|
|
17
|
+
|
|
18
|
+
this._canvas = canvas;
|
|
19
|
+
this._eventBus = eventBus;
|
|
20
|
+
this._elementRegistry = elementRegistry;
|
|
21
|
+
this._overlays = overlays;
|
|
22
|
+
|
|
23
|
+
var self = this;
|
|
24
|
+
|
|
25
|
+
this.executed('shape.toggleCollapse', LOW_PRIORITY, function(context) {
|
|
26
|
+
var shape = context.shape;
|
|
27
|
+
|
|
28
|
+
// Add overlay to the collapsed shape
|
|
29
|
+
if (self.canDrillDown(shape)) {
|
|
30
|
+
self.addOverlay(shape);
|
|
31
|
+
} else {
|
|
32
|
+
self.removeOverlay(shape);
|
|
33
|
+
}
|
|
34
|
+
}, true);
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
this.reverted('shape.toggleCollapse', LOW_PRIORITY, function(context) {
|
|
38
|
+
var shape = context.shape;
|
|
39
|
+
|
|
40
|
+
// Add overlay to the collapsed shape
|
|
41
|
+
if (self.canDrillDown(shape)) {
|
|
42
|
+
self.addOverlay(shape);
|
|
43
|
+
} else {
|
|
44
|
+
self.removeOverlay(shape);
|
|
45
|
+
}
|
|
46
|
+
}, true);
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
this.executed(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
|
|
50
|
+
function(context) {
|
|
51
|
+
var oldParent = context.oldParent,
|
|
52
|
+
newParent = context.newParent || context.parent,
|
|
53
|
+
shape = context.shape;
|
|
54
|
+
|
|
55
|
+
// Add overlay to the collapsed shape
|
|
56
|
+
if (self.canDrillDown(shape)) {
|
|
57
|
+
self.addOverlay(shape);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
self.updateDrilldownOverlay(oldParent);
|
|
61
|
+
self.updateDrilldownOverlay(newParent);
|
|
62
|
+
self.updateDrilldownOverlay(shape);
|
|
63
|
+
}, true);
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
this.reverted(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
|
|
67
|
+
function(context) {
|
|
68
|
+
var oldParent = context.oldParent,
|
|
69
|
+
newParent = context.newParent || context.parent,
|
|
70
|
+
shape = context.shape;
|
|
71
|
+
|
|
72
|
+
// Add overlay to the collapsed shape
|
|
73
|
+
if (self.canDrillDown(shape)) {
|
|
74
|
+
self.addOverlay(shape);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
self.updateDrilldownOverlay(oldParent);
|
|
78
|
+
self.updateDrilldownOverlay(newParent);
|
|
79
|
+
self.updateDrilldownOverlay(shape);
|
|
80
|
+
}, true);
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
eventBus.on('import.done', function() {
|
|
84
|
+
elementRegistry.filter(function(e) {
|
|
85
|
+
return self.canDrillDown(e);
|
|
86
|
+
}).map(function(el) {
|
|
87
|
+
self.addOverlay(el);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
inherits(DrilldownOverlayBehavior, CommandInterceptor);
|
|
94
|
+
|
|
95
|
+
DrilldownOverlayBehavior.prototype.updateDrilldownOverlay = function(shape) {
|
|
96
|
+
var canvas = this._canvas;
|
|
97
|
+
|
|
98
|
+
if (!shape) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
var root = canvas.findRoot(shape);
|
|
103
|
+
if (root) {
|
|
104
|
+
this.updateOverlayVisibility(root);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
DrilldownOverlayBehavior.prototype.canDrillDown = function(element) {
|
|
110
|
+
var canvas = this._canvas;
|
|
111
|
+
return is(element, 'bpmn:SubProcess') && canvas.findRoot(getPlaneIdFromShape(element));
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Updates visibility of the drilldown overlay. If the plane has no elements,
|
|
116
|
+
* the drilldown will be only shown when the element is selected.
|
|
117
|
+
*
|
|
118
|
+
* @param {djs.model.Shape|djs.model.Root} element collapsed shape or root element
|
|
119
|
+
*/
|
|
120
|
+
DrilldownOverlayBehavior.prototype.updateOverlayVisibility = function(element) {
|
|
121
|
+
var overlays = this._overlays;
|
|
122
|
+
|
|
123
|
+
var bo = element.businessObject;
|
|
124
|
+
|
|
125
|
+
var overlay = overlays.get({ element: bo.id, type: 'drilldown' })[0];
|
|
126
|
+
|
|
127
|
+
if (!overlay) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
var hasContent = bo && bo.flowElements && bo.flowElements.length;
|
|
132
|
+
classes(overlay.html).toggle(EMPTY_MARKER, !hasContent);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Attaches a drilldown button to the given element. We assume that the plane has
|
|
137
|
+
* the same id as the element.
|
|
138
|
+
*
|
|
139
|
+
* @param {djs.model.Shape} element collapsed shape
|
|
140
|
+
*/
|
|
141
|
+
DrilldownOverlayBehavior.prototype.addOverlay = function(element) {
|
|
142
|
+
var canvas = this._canvas;
|
|
143
|
+
var overlays = this._overlays;
|
|
144
|
+
|
|
145
|
+
var existingOverlays = overlays.get({ element: element, type: 'drilldown' });
|
|
146
|
+
if (existingOverlays.length) {
|
|
147
|
+
this.removeOverlay(element);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
var button = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
|
|
151
|
+
|
|
152
|
+
button.addEventListener('click', function() {
|
|
153
|
+
canvas.setRootElement(canvas.findRoot(getPlaneIdFromShape(element)));
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
overlays.add(element, 'drilldown', {
|
|
157
|
+
position: {
|
|
158
|
+
bottom: -7,
|
|
159
|
+
right: -8
|
|
160
|
+
},
|
|
161
|
+
html: button
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
this.updateOverlayVisibility(element);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
DrilldownOverlayBehavior.prototype.removeOverlay = function(element) {
|
|
168
|
+
var overlays = this._overlays;
|
|
169
|
+
|
|
170
|
+
overlays.remove({
|
|
171
|
+
element: element,
|
|
172
|
+
type: 'drilldown'
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
DrilldownOverlayBehavior.$inject = [
|
|
177
|
+
'canvas',
|
|
178
|
+
'eventBus',
|
|
179
|
+
'elementRegistry',
|
|
180
|
+
'overlays'
|
|
181
|
+
];
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
|
|
2
|
+
import { asBounds, asTRBL } from 'diagram-js/lib/layout/LayoutUtil';
|
|
3
|
+
import { is } from '../../util/ModelUtil';
|
|
4
|
+
|
|
5
|
+
var DEFAULT_POSITION = {
|
|
6
|
+
x: 180,
|
|
7
|
+
y: 160
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Hook into `import.render.start` and create new planes for diagrams with
|
|
12
|
+
* collapsed subprocesses and all dis on the same plane.
|
|
13
|
+
*
|
|
14
|
+
* @param {eventBus} eventBus
|
|
15
|
+
* @param {moddle} moddle
|
|
16
|
+
*/
|
|
17
|
+
export default function SubprocessCompatibility(eventBus, moddle) {
|
|
18
|
+
this._eventBus = eventBus;
|
|
19
|
+
this._moddle = moddle;
|
|
20
|
+
|
|
21
|
+
var self = this;
|
|
22
|
+
|
|
23
|
+
eventBus.on('import.render.start', 1500, function(e, context) {
|
|
24
|
+
self.handleImport(context.definitions);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
SubprocessCompatibility.prototype.handleImport = function(definitions) {
|
|
29
|
+
if (!definitions.diagrams) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var self = this;
|
|
34
|
+
this._definitions = definitions;
|
|
35
|
+
this._processToDiagramMap = {};
|
|
36
|
+
|
|
37
|
+
definitions.diagrams.forEach(function(diagram) {
|
|
38
|
+
if (!diagram.plane || !diagram.plane.bpmnElement) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
self._processToDiagramMap[diagram.plane.bpmnElement.id] = diagram;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
var newDiagrams = [];
|
|
46
|
+
definitions.diagrams.forEach(function(diagram) {
|
|
47
|
+
var createdDiagrams = self.createNewDiagrams(diagram.plane);
|
|
48
|
+
Array.prototype.push.apply(newDiagrams, createdDiagrams);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
newDiagrams.forEach(function(diagram) {
|
|
52
|
+
self.movePlaneElementsToOrigin(diagram.plane);
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Moves all DI elements from collapsed subprocesses to a new plane.
|
|
59
|
+
*
|
|
60
|
+
* @param {Object} plane
|
|
61
|
+
* @return {Array} new diagrams created for the collapsed subprocesses
|
|
62
|
+
*/
|
|
63
|
+
SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
|
|
64
|
+
var self = this;
|
|
65
|
+
|
|
66
|
+
var collapsedElements = [];
|
|
67
|
+
var elementsToMove = [];
|
|
68
|
+
|
|
69
|
+
plane.get('planeElement').forEach(function(diElement) {
|
|
70
|
+
var bo = diElement.bpmnElement;
|
|
71
|
+
|
|
72
|
+
if (!bo) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var parent = bo.$parent;
|
|
77
|
+
|
|
78
|
+
if (is(bo, 'bpmn:SubProcess') && !diElement.isExpanded) {
|
|
79
|
+
collapsedElements.push(bo);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (is(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
|
|
83
|
+
|
|
84
|
+
// don't change the array while we iterate over it
|
|
85
|
+
elementsToMove.push({ diElement: diElement, parent: parent });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
var newDiagrams = [];
|
|
90
|
+
|
|
91
|
+
// create new planes for all collapsed subprocesses, even when they are empty
|
|
92
|
+
collapsedElements.forEach(function(element) {
|
|
93
|
+
if (!self._processToDiagramMap[element.id]) {
|
|
94
|
+
var diagram = self.createDiagram(element);
|
|
95
|
+
self._processToDiagramMap[element.id] = diagram;
|
|
96
|
+
newDiagrams.push(diagram);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
elementsToMove.forEach(function(element) {
|
|
101
|
+
var diElement = element.diElement;
|
|
102
|
+
var parent = element.parent;
|
|
103
|
+
|
|
104
|
+
// parent is expanded, get nearest collapsed parent
|
|
105
|
+
while (parent && collapsedElements.indexOf(parent) === -1) {
|
|
106
|
+
parent = parent.$parent;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// false positive, all parents are expanded
|
|
110
|
+
if (!parent) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var diagram = self._processToDiagramMap[parent.id];
|
|
115
|
+
self.moveToDiPlane(diElement, diagram.plane);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return newDiagrams;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
SubprocessCompatibility.prototype.movePlaneElementsToOrigin = function(plane) {
|
|
122
|
+
var elements = plane.get('planeElement');
|
|
123
|
+
|
|
124
|
+
// get bounding box of all elements
|
|
125
|
+
var planeBounds = getPlaneBounds(plane);
|
|
126
|
+
|
|
127
|
+
var offset = {
|
|
128
|
+
x: planeBounds.x - DEFAULT_POSITION.x,
|
|
129
|
+
y: planeBounds.y - DEFAULT_POSITION.y
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
elements.forEach(function(diElement) {
|
|
133
|
+
if (diElement.waypoint) {
|
|
134
|
+
diElement.waypoint.forEach(function(waypoint) {
|
|
135
|
+
waypoint.x = waypoint.x - offset.x;
|
|
136
|
+
waypoint.y = waypoint.y - offset.y;
|
|
137
|
+
});
|
|
138
|
+
} else if (diElement.bounds) {
|
|
139
|
+
diElement.bounds.x = diElement.bounds.x - offset.x;
|
|
140
|
+
diElement.bounds.y = diElement.bounds.y - offset.y;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
SubprocessCompatibility.prototype.moveToDiPlane = function(diElement, newPlane) {
|
|
147
|
+
var containingDiagram = findRootDiagram(diElement);
|
|
148
|
+
|
|
149
|
+
// remove DI from old Plane and add it to the new one
|
|
150
|
+
var parentPlaneElement = containingDiagram.plane.get('planeElement');
|
|
151
|
+
parentPlaneElement.splice(parentPlaneElement.indexOf(diElement), 1);
|
|
152
|
+
newPlane.get('planeElement').push(diElement);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
SubprocessCompatibility.prototype.createDiagram = function(bo) {
|
|
157
|
+
var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
|
|
158
|
+
var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
|
|
159
|
+
plane: plane
|
|
160
|
+
});
|
|
161
|
+
plane.$parent = diagram;
|
|
162
|
+
plane.bpmnElement = bo;
|
|
163
|
+
diagram.$parent = this._definitions;
|
|
164
|
+
this._definitions.diagrams.push(diagram);
|
|
165
|
+
return diagram;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
SubprocessCompatibility.$inject = [ 'eventBus', 'moddle' ];
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
// helpers
|
|
172
|
+
|
|
173
|
+
function findRootDiagram(element) {
|
|
174
|
+
if (is(element, 'bpmndi:BPMNDiagram')) {
|
|
175
|
+
return element;
|
|
176
|
+
} else {
|
|
177
|
+
return findRootDiagram(element.$parent);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function getPlaneBounds(plane) {
|
|
182
|
+
var planeTrbl = {
|
|
183
|
+
top: Infinity,
|
|
184
|
+
right: -Infinity,
|
|
185
|
+
bottom: -Infinity,
|
|
186
|
+
left: Infinity
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
plane.planeElement.forEach(function(element) {
|
|
190
|
+
if (!element.bounds) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
var trbl = asTRBL(element.bounds);
|
|
195
|
+
|
|
196
|
+
planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
|
|
197
|
+
planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return asBounds(planeTrbl);
|
|
201
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import OverlaysModule from 'diagram-js/lib/features/overlays';
|
|
2
|
+
import ChangeSupportModule from 'diagram-js/lib/features/change-support';
|
|
3
|
+
import RootElementsModule from 'diagram-js/lib/features/root-elements';
|
|
4
|
+
|
|
5
|
+
import DrilldownBreadcrumbs from './DrilldownBreadcrumbs';
|
|
6
|
+
import DrilldownCentering from './DrilldownCentering';
|
|
7
|
+
import SubprocessCompatibility from './SubprocessCompatibility';
|
|
8
|
+
import DrilldownOverlayBehavior from './DrilldownOverlayBehavior';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
__depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
|
|
12
|
+
__init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility'],
|
|
13
|
+
drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
|
|
14
|
+
drilldownCentering: [ 'type', DrilldownCentering ],
|
|
15
|
+
drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
|
|
16
|
+
subprocessCompatibility: [ 'type', SubprocessCompatibility ]
|
|
17
|
+
};
|