bpmn-js 8.8.0 → 9.0.0-subprocesses.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 +15 -1
- package/dist/assets/bpmn-js.css +58 -0
- package/dist/assets/diagram-js.css +1 -0
- package/dist/bpmn-modeler.development.js +1489 -827
- package/dist/bpmn-modeler.production.min.js +7 -6
- package/dist/bpmn-navigated-viewer.development.js +20890 -19973
- package/dist/bpmn-navigated-viewer.production.min.js +22 -20
- package/dist/bpmn-viewer.development.js +20091 -19174
- package/dist/bpmn-viewer.production.min.js +22 -20
- package/lib/BaseViewer.js +0 -13
- package/lib/Viewer.js +3 -1
- package/lib/draw/BpmnRenderUtil.js +6 -4
- package/lib/draw/BpmnRenderer.js +367 -296
- package/lib/features/context-pad/ContextPadProvider.js +1 -1
- package/lib/features/copy-paste/BpmnCopyPaste.js +13 -13
- package/lib/features/copy-paste/ModdleCopy.js +19 -2
- package/lib/features/di-ordering/BpmnDiOrdering.js +2 -3
- package/lib/features/label-editing/LabelEditingPreview.js +3 -3
- package/lib/features/label-editing/cmd/UpdateLabelHandler.js +2 -1
- package/lib/features/modeling/BpmnFactory.js +8 -8
- package/lib/features/modeling/BpmnUpdater.js +35 -27
- package/lib/features/modeling/ElementFactory.js +60 -37
- package/lib/features/modeling/behavior/DataStoreBehavior.js +3 -1
- package/lib/features/modeling/behavior/IsHorizontalFix.js +7 -4
- package/lib/features/modeling/behavior/LabelBehavior.js +8 -7
- package/lib/features/modeling/behavior/ResizeBehavior.js +129 -3
- package/lib/features/modeling/behavior/ToggleElementCollapseBehaviour.js +6 -6
- package/lib/features/modeling/behavior/util/ResizeUtil.js +1 -132
- package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +8 -6
- package/lib/features/modeling/cmd/UpdatePropertiesHandler.js +19 -12
- package/lib/features/modeling/cmd/UpdateSemanticParentHandler.js +5 -3
- package/lib/features/palette/PaletteProvider.js +3 -1
- package/lib/features/popup-menu/ReplaceMenuProvider.js +5 -5
- package/lib/features/popup-menu/util/TypeUtil.js +1 -1
- package/lib/features/replace/BpmnReplace.js +29 -29
- package/lib/features/subprocess-navigation/SubprocessCentering.js +55 -0
- package/lib/features/subprocess-navigation/SubprocessCompatibility.js +135 -0
- package/lib/features/subprocess-navigation/SubprocessElements.js +55 -0
- package/lib/features/subprocess-navigation/SubprocessFlows.js +109 -0
- package/lib/features/subprocess-navigation/SubprocessOverlays.js +104 -0
- package/lib/features/subprocess-navigation/index.js +18 -0
- package/lib/import/BpmnImporter.js +76 -22
- package/lib/import/BpmnTreeWalker.js +19 -17
- package/lib/import/Importer.js +17 -6
- package/lib/util/CompatibilityUtil.js +21 -1
- package/lib/util/DiUtil.js +10 -3
- package/lib/util/LabelUtil.js +2 -3
- package/lib/util/ModelUtil.js +11 -0
- package/package.json +2 -2
- package/test/helper/index.js +6 -1
- package/test/matchers/BoundsMatchers.js +10 -10
- package/test/matchers/ConnectionMatchers.js +5 -5
- package/test/util/MockEvents.js +10 -2
|
@@ -36,6 +36,7 @@ function copyProperties(source, target, properties) {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
|
|
39
40
|
var CUSTOM_PROPERTIES = [
|
|
40
41
|
'cancelActivity',
|
|
41
42
|
'instantiate',
|
|
@@ -44,8 +45,10 @@ var CUSTOM_PROPERTIES = [
|
|
|
44
45
|
'isInterrupting'
|
|
45
46
|
];
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Check if element should be collapsed or expanded.
|
|
50
|
+
*/
|
|
51
|
+
function shouldToggleCollapsed(element, targetElement) {
|
|
49
52
|
|
|
50
53
|
var oldCollapsed = (
|
|
51
54
|
element && has(element, 'collapsed') ? element.collapsed : !isExpanded(element)
|
|
@@ -53,11 +56,11 @@ function toggeling(element, target) {
|
|
|
53
56
|
|
|
54
57
|
var targetCollapsed;
|
|
55
58
|
|
|
56
|
-
if (
|
|
59
|
+
if (targetElement && (has(targetElement, 'collapsed') || has(targetElement, 'isExpanded'))) {
|
|
57
60
|
|
|
58
61
|
// property is explicitly set so use it
|
|
59
62
|
targetCollapsed = (
|
|
60
|
-
has(
|
|
63
|
+
has(targetElement, 'collapsed') ? targetElement.collapsed : !targetElement.isExpanded
|
|
61
64
|
);
|
|
62
65
|
} else {
|
|
63
66
|
|
|
@@ -66,7 +69,6 @@ function toggeling(element, target) {
|
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
if (oldCollapsed !== targetCollapsed) {
|
|
69
|
-
element.collapsed = oldCollapsed;
|
|
70
72
|
return true;
|
|
71
73
|
}
|
|
72
74
|
|
|
@@ -74,7 +76,6 @@ function toggeling(element, target) {
|
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
|
|
77
|
-
|
|
78
79
|
/**
|
|
79
80
|
* This module takes care of replacing BPMN elements
|
|
80
81
|
*/
|
|
@@ -105,15 +106,13 @@ export default function BpmnReplace(
|
|
|
105
106
|
var type = target.type,
|
|
106
107
|
oldBusinessObject = element.businessObject;
|
|
107
108
|
|
|
108
|
-
if (isSubProcess(oldBusinessObject)) {
|
|
109
|
-
if (
|
|
110
|
-
if (toggeling(element, target)) {
|
|
109
|
+
if (isSubProcess(oldBusinessObject) && type === 'bpmn:SubProcess') {
|
|
110
|
+
if (shouldToggleCollapsed(element, target)) {
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
// expanding or collapsing process
|
|
113
|
+
modeling.toggleCollapse(element);
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
}
|
|
115
|
+
return element;
|
|
117
116
|
}
|
|
118
117
|
}
|
|
119
118
|
|
|
@@ -121,9 +120,20 @@ export default function BpmnReplace(
|
|
|
121
120
|
|
|
122
121
|
var newElement = {
|
|
123
122
|
type: type,
|
|
124
|
-
businessObject: newBusinessObject
|
|
123
|
+
businessObject: newBusinessObject,
|
|
125
124
|
};
|
|
126
125
|
|
|
126
|
+
newElement.di = {};
|
|
127
|
+
|
|
128
|
+
// colors will be set to DI
|
|
129
|
+
copyProperties(element.di, newElement.di, [
|
|
130
|
+
'fill',
|
|
131
|
+
'stroke',
|
|
132
|
+
'background-color',
|
|
133
|
+
'border-color',
|
|
134
|
+
'color'
|
|
135
|
+
]);
|
|
136
|
+
|
|
127
137
|
var elementProps = getPropertyNames(oldBusinessObject.$descriptor),
|
|
128
138
|
newElementProps = getPropertyNames(newBusinessObject.$descriptor, true),
|
|
129
139
|
copyProps = intersection(elementProps, newElementProps);
|
|
@@ -183,7 +193,7 @@ export default function BpmnReplace(
|
|
|
183
193
|
if (isSubProcess(oldBusinessObject)) {
|
|
184
194
|
|
|
185
195
|
// no toggeling, so keep old state
|
|
186
|
-
newElement.isExpanded = isExpanded(
|
|
196
|
+
newElement.isExpanded = isExpanded(element);
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
// else if property is explicitly set, use it
|
|
@@ -194,7 +204,7 @@ export default function BpmnReplace(
|
|
|
194
204
|
// TODO: need also to respect min/max Size
|
|
195
205
|
// copy size, from an expanded subprocess to an expanded alternative subprocess
|
|
196
206
|
// except bpmn:Task, because Task is always expanded
|
|
197
|
-
if ((isExpanded(
|
|
207
|
+
if ((isExpanded(element) && !is(oldBusinessObject, 'bpmn:Task')) && newElement.isExpanded) {
|
|
198
208
|
newElement.width = element.width;
|
|
199
209
|
newElement.height = element.height;
|
|
200
210
|
}
|
|
@@ -219,12 +229,12 @@ export default function BpmnReplace(
|
|
|
219
229
|
|
|
220
230
|
// apply same width and default height
|
|
221
231
|
newElement.width = element.width;
|
|
222
|
-
newElement.height = elementFactory.
|
|
232
|
+
newElement.height = elementFactory.getDefaultSize(newElement).height;
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
if (!rules.allowed('shape.resize', { shape: newBusinessObject })) {
|
|
226
|
-
newElement.height = elementFactory.
|
|
227
|
-
newElement.width = elementFactory.
|
|
236
|
+
newElement.height = elementFactory.getDefaultSize(newElement).height;
|
|
237
|
+
newElement.width = elementFactory.getDefaultSize(newElement).width;
|
|
228
238
|
}
|
|
229
239
|
|
|
230
240
|
newBusinessObject.name = oldBusinessObject.name;
|
|
@@ -262,16 +272,6 @@ export default function BpmnReplace(
|
|
|
262
272
|
newElement.x = element.x + (element.width - newElement.width) / 2;
|
|
263
273
|
}
|
|
264
274
|
|
|
265
|
-
newElement.di = {};
|
|
266
|
-
|
|
267
|
-
// colors will be set to DI
|
|
268
|
-
copyProperties(oldBusinessObject.di, newElement.di, [
|
|
269
|
-
'fill',
|
|
270
|
-
'stroke',
|
|
271
|
-
'background-color',
|
|
272
|
-
'border-color',
|
|
273
|
-
'color'
|
|
274
|
-
]);
|
|
275
275
|
|
|
276
276
|
newElement = replace.replaceElement(element, newElement, hints);
|
|
277
277
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var defaultPosition = { x: 100, y: 50 };
|
|
2
|
+
|
|
3
|
+
export default function SubprocessCentering(eventBus, canvas) {
|
|
4
|
+
var currentPlane = 'base';
|
|
5
|
+
var positionMap = {};
|
|
6
|
+
|
|
7
|
+
eventBus.on('plane.set', function(event) {
|
|
8
|
+
|
|
9
|
+
var currentViewbox = canvas.viewbox();
|
|
10
|
+
positionMap[currentPlane] = {
|
|
11
|
+
x: currentViewbox.x,
|
|
12
|
+
y: currentViewbox.y,
|
|
13
|
+
zoom: currentViewbox.scale
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
var planeId = event.plane.name;
|
|
17
|
+
var storedViewbox = positionMap[planeId];
|
|
18
|
+
|
|
19
|
+
if (!storedViewbox) {
|
|
20
|
+
if (!event.plane.rootElement.isImplicit) {
|
|
21
|
+
storedViewbox = {
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0,
|
|
24
|
+
zoom: 1
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
var currentBoundingBox = canvas.getActiveLayer().getBBox();
|
|
29
|
+
storedViewbox = {
|
|
30
|
+
x: currentBoundingBox.x - defaultPosition.x,
|
|
31
|
+
y: currentBoundingBox.y - defaultPosition.y,
|
|
32
|
+
zoom: 1
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
|
|
38
|
+
dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
|
|
39
|
+
|
|
40
|
+
if (dx !== 0 || dy !== 0) {
|
|
41
|
+
canvas.scroll({
|
|
42
|
+
dx: dx,
|
|
43
|
+
dy: dy
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (storedViewbox.zoom !== currentViewbox.scale) {
|
|
48
|
+
canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
currentPlane = planeId;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
SubprocessCentering.$inject = [ 'eventBus', 'canvas' ];
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
|
|
2
|
+
import { selfAndAllChildren } from 'diagram-js/lib/util/Elements';
|
|
3
|
+
import { isExpanded } from '../../util/DiUtil';
|
|
4
|
+
import { getBusinessObject, getDi, is } from '../../util/ModelUtil';
|
|
5
|
+
|
|
6
|
+
export default function SubprocessCompatibility(eventBus, elementRegistry, canvas, moddle, elementFactory, bpmnjs) {
|
|
7
|
+
this._eventBus = eventBus;
|
|
8
|
+
this._elementRegistry = elementRegistry;
|
|
9
|
+
this._canvas = canvas;
|
|
10
|
+
this._bpmnjs = bpmnjs;
|
|
11
|
+
this._moddle = moddle;
|
|
12
|
+
this._elementFactory = elementFactory;
|
|
13
|
+
|
|
14
|
+
var self = this;
|
|
15
|
+
|
|
16
|
+
eventBus.on('import.done', 1500, function() {
|
|
17
|
+
self._handleImport();
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
SubprocessCompatibility.prototype._handleImport = function() {
|
|
22
|
+
var elementRegistry = this._elementRegistry;
|
|
23
|
+
var canvas = this._canvas;
|
|
24
|
+
var elementFactory = this._elementFactory;
|
|
25
|
+
var self = this;
|
|
26
|
+
var legacyProcesses = elementRegistry.filter(function(element) {
|
|
27
|
+
return is(element, 'bpmn:SubProcess') && !isExpanded(element) && element.children && element.children.length;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
legacyProcesses.forEach(function(oldParent) {
|
|
31
|
+
var bo = getBusinessObject(oldParent);
|
|
32
|
+
|
|
33
|
+
var newDiagram = self.createDiagram(bo);
|
|
34
|
+
|
|
35
|
+
var newParent = elementFactory.createRoot(
|
|
36
|
+
{
|
|
37
|
+
id: bo.id,
|
|
38
|
+
type: bo.$type,
|
|
39
|
+
businessObject: bo,
|
|
40
|
+
di: newDiagram.plane
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
newParent.id = newParent.id + '_plane';
|
|
45
|
+
|
|
46
|
+
canvas.createPlane(bo.id, newParent);
|
|
47
|
+
|
|
48
|
+
var elementsToChange = selfAndAllChildren(oldParent).filter(function(el) {
|
|
49
|
+
return el !== oldParent;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
self.moveElementsToRoot(elementsToChange);
|
|
53
|
+
|
|
54
|
+
elementsToChange.forEach(function(el) {
|
|
55
|
+
if (el.parent === oldParent) {
|
|
56
|
+
el.parent = newParent;
|
|
57
|
+
}
|
|
58
|
+
el.hidden = el.parent && (el.parent.hidden || el.parent.collapsed);
|
|
59
|
+
|
|
60
|
+
self.moveToDiPlane(el, newDiagram.plane);
|
|
61
|
+
|
|
62
|
+
self._eventBus.fire('elements.changed', { elements: [el] });
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
SubprocessCompatibility.prototype.moveToDiPlane = function(element, newPlane) {
|
|
69
|
+
var di = getDi(element);
|
|
70
|
+
var containingDiagram = findRootDiagram(di);
|
|
71
|
+
|
|
72
|
+
// Remove DI from old Plane and add it to the new one
|
|
73
|
+
var parentPlaneElement = containingDiagram.plane.get('planeElement');
|
|
74
|
+
parentPlaneElement.splice(parentPlaneElement.indexOf(di), 1);
|
|
75
|
+
newPlane.get('planeElement').push(di);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
SubprocessCompatibility.prototype.moveElementsToRoot = function(elements) {
|
|
79
|
+
var defaultPosition = { x: 180, y: 160 },
|
|
80
|
+
minX = Infinity,
|
|
81
|
+
minY = Infinity;
|
|
82
|
+
|
|
83
|
+
elements.forEach(function(el) {
|
|
84
|
+
minX = Math.min(minX, el.x || Infinity);
|
|
85
|
+
minY = Math.min(minY, el.y || Infinity);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
var xOffset = defaultPosition.x - minX;
|
|
89
|
+
var yOffset = defaultPosition.y - minY;
|
|
90
|
+
|
|
91
|
+
elements.forEach(function(el) {
|
|
92
|
+
if (el.waypoints) {
|
|
93
|
+
el.waypoints.forEach(function(waypoint) {
|
|
94
|
+
waypoint.x = waypoint.x + xOffset;
|
|
95
|
+
waypoint.y = waypoint.y + yOffset;
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
el.x = el.x + xOffset;
|
|
99
|
+
el.y = el.y + yOffset;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
SubprocessCompatibility.prototype.getDefinitions = function() {
|
|
105
|
+
return this._bpmnjs._definitions || [];
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
SubprocessCompatibility.prototype.getDiagrams = function() {
|
|
109
|
+
return this.getDefinitions().diagrams || [];
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
SubprocessCompatibility.prototype.createDiagram = function(bo) {
|
|
113
|
+
var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
|
|
114
|
+
var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
|
|
115
|
+
plane: plane
|
|
116
|
+
});
|
|
117
|
+
plane.$parent = diagram;
|
|
118
|
+
plane.bpmnElement = bo;
|
|
119
|
+
diagram.$parent = this.getDefinitions();
|
|
120
|
+
this.getDiagrams().push(diagram);
|
|
121
|
+
return diagram;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
SubprocessCompatibility.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'moddle', 'elementFactory', 'bpmnjs' ];
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
// Util
|
|
128
|
+
|
|
129
|
+
var findRootDiagram = function(element) {
|
|
130
|
+
if (is(element, 'bpmndi:BPMNDiagram')) {
|
|
131
|
+
return element;
|
|
132
|
+
} else {
|
|
133
|
+
return findRootDiagram(element.$parent);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getBusinessObject, is } from '../../util/ModelUtil';
|
|
2
|
+
|
|
3
|
+
export default function SubprocessElements(eventBus, elementRegistry, canvas, elementFactory) {
|
|
4
|
+
var attachBoundaries = function() {
|
|
5
|
+
var secondaryShapes = elementRegistry.filter(function(el) {
|
|
6
|
+
return is(el, 'bpmn:SubProcess') && el.isSecondary;
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
secondaryShapes.forEach(function(process) {
|
|
10
|
+
|
|
11
|
+
// Add Boundary events
|
|
12
|
+
if (process.primaryShape && process.primaryShape.attachers) {
|
|
13
|
+
process.primaryShape.attachers.forEach(function(boundary) {
|
|
14
|
+
var bo = getBusinessObject(boundary);
|
|
15
|
+
|
|
16
|
+
var primary = process.primaryShape;
|
|
17
|
+
|
|
18
|
+
var relativeXPos = (boundary.x + 15 - primary.x) / primary.width;
|
|
19
|
+
var relativeYPos = (boundary.y + 15 - primary.y) / primary.height;
|
|
20
|
+
|
|
21
|
+
var dx = process.x + (process.width * relativeXPos) - 15;
|
|
22
|
+
var dy = process.y + (process.height * relativeYPos) - 15;
|
|
23
|
+
|
|
24
|
+
var boundaryShape = elementFactory.createShape({
|
|
25
|
+
id: bo.id + '_secondary',
|
|
26
|
+
businessObject: bo,
|
|
27
|
+
type: 'bpmn:BoundaryEvent',
|
|
28
|
+
hidden: false,
|
|
29
|
+
x: dx,
|
|
30
|
+
y: dy,
|
|
31
|
+
width: 30,
|
|
32
|
+
height: 30,
|
|
33
|
+
isFrame: false,
|
|
34
|
+
isSecondary: true,
|
|
35
|
+
primaryShape: boundary,
|
|
36
|
+
di: boundary.di
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
canvas.addShape(boundaryShape, process.parent);
|
|
40
|
+
|
|
41
|
+
if (!process.attachers) {
|
|
42
|
+
process.attachers = [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
process.attachers.push(boundaryShape);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
eventBus.on('import.done', attachBoundaries);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
SubprocessElements.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'elementFactory' ];
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var FLOW_LENGTH = 50;
|
|
2
|
+
var HIGH_RENDER_PRIORITY = 2000;
|
|
3
|
+
|
|
4
|
+
export default function SubprocessFlows(eventBus, config) {
|
|
5
|
+
|
|
6
|
+
var mutedStrokeColor = (config && config.mutedStrokeColor) || '#dddddd';
|
|
7
|
+
|
|
8
|
+
function drawFakeFlows(element, parentGfx) {
|
|
9
|
+
var primary = element.primaryShape;
|
|
10
|
+
|
|
11
|
+
var drawFakeConnection = function(connection, isOutgoing) {
|
|
12
|
+
|
|
13
|
+
var segment;
|
|
14
|
+
if (isOutgoing) {
|
|
15
|
+
segment = connection.waypoints.slice(0, 2);
|
|
16
|
+
|
|
17
|
+
// Reverse order for normalizing
|
|
18
|
+
segment = segment.reverse();
|
|
19
|
+
} else {
|
|
20
|
+
segment = connection.waypoints.slice(connection.waypoints.length - 2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var endpoint = segment[1];
|
|
24
|
+
|
|
25
|
+
var relativePosition = {
|
|
26
|
+
x: (endpoint.x - primary.x) / primary.width,
|
|
27
|
+
y: (endpoint.y - primary.y) / primary.height
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
var anchorPoint = {
|
|
31
|
+
x: endpoint.x - (element.width * relativePosition.x),
|
|
32
|
+
y: endpoint.y - (element.height * relativePosition.y)
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
var newWaypoints = segment.map(function(el) {
|
|
36
|
+
return { x: el.x - anchorPoint.x, y: el.y - anchorPoint.y };
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
newWaypoints[0] = normalizeLength(newWaypoints[1], newWaypoints[0], FLOW_LENGTH);
|
|
40
|
+
|
|
41
|
+
var attrs = {
|
|
42
|
+
stroke: mutedStrokeColor
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
if (isOutgoing) {
|
|
46
|
+
|
|
47
|
+
// Reverse order again for correct end marker position
|
|
48
|
+
newWaypoints = newWaypoints.reverse();
|
|
49
|
+
} else {
|
|
50
|
+
|
|
51
|
+
// Remove start marker for incoming flows
|
|
52
|
+
attrs.markerStart = undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
eventBus.fire('render.connection', {
|
|
56
|
+
type: connection.type,
|
|
57
|
+
gfx: parentGfx,
|
|
58
|
+
element: {
|
|
59
|
+
type: connection.type,
|
|
60
|
+
waypoints: newWaypoints,
|
|
61
|
+
di: connection.di,
|
|
62
|
+
businessObject: connection.businessObject
|
|
63
|
+
},
|
|
64
|
+
attrs: attrs
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
primary.incoming && primary.incoming.forEach(function(connection) {
|
|
69
|
+
drawFakeConnection(connection, false);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
primary.outgoing && primary.outgoing.forEach(function(connection) {
|
|
73
|
+
drawFakeConnection(connection, true);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
eventBus.on([ 'render.shape' ], HIGH_RENDER_PRIORITY, function(evt, context) {
|
|
78
|
+
var element = context.element,
|
|
79
|
+
visuals = context.gfx;
|
|
80
|
+
|
|
81
|
+
if (element.isSecondary && element.primaryShape) {
|
|
82
|
+
drawFakeFlows(element, visuals);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
SubprocessFlows.$inject = [ 'eventBus', 'config' ];
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
// helpers
|
|
93
|
+
|
|
94
|
+
function normalizeLength(fixedPoint, variablePoint, length) {
|
|
95
|
+
var dx = fixedPoint.x - variablePoint.x,
|
|
96
|
+
dy = fixedPoint.y - variablePoint.y,
|
|
97
|
+
totalDistance = Math.abs(dx) + Math.abs(dy);
|
|
98
|
+
|
|
99
|
+
dx = dx / totalDistance;
|
|
100
|
+
dy = dy / totalDistance;
|
|
101
|
+
|
|
102
|
+
dx *= length;
|
|
103
|
+
dy *= length;
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
x: fixedPoint.x - dx,
|
|
107
|
+
y: fixedPoint.y - dy
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { domify } from 'min-dom';
|
|
2
|
+
|
|
3
|
+
import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
|
|
4
|
+
import { getBusinessObject, is } from '../../util/ModelUtil';
|
|
5
|
+
|
|
6
|
+
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>';
|
|
7
|
+
var ARROW_UP_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.1819805,12.4926407 L5.5003106,6.8103106 L5.5,12 L4,12 L4,4 L12,4 L12,5.5 L6.3103106,5.5003106 L12.2426407,11.4319805 C12.5355339,11.7248737 12.5355339,12.1997475 12.2426407,12.4926407 C11.9497475,12.7855339 11.4748737,12.7855339 11.1819805,12.4926407 Z"/></svg>';
|
|
8
|
+
|
|
9
|
+
export default function SubprocessOverlays(eventBus, elementRegistry, overlays, canvas) {
|
|
10
|
+
|
|
11
|
+
function createBreadcrumbs(subProcess) {
|
|
12
|
+
var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
|
|
13
|
+
var drillUp = domify('<button class="bjs-drilldown">' + ARROW_UP_SVG + '</button>');
|
|
14
|
+
drillUp.addEventListener('click', function() {
|
|
15
|
+
var plane = canvas.findPlane(getBusinessObject(subProcess).id);
|
|
16
|
+
canvas.setActivePlane(plane);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
breadcrumbs.appendChild(drillUp);
|
|
20
|
+
|
|
21
|
+
var parents = getParentChain(subProcess);
|
|
22
|
+
|
|
23
|
+
var path = parents.map(function(el) {
|
|
24
|
+
var title = escapeHTML(el.name) || el.id;
|
|
25
|
+
var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
|
|
26
|
+
|
|
27
|
+
link.addEventListener('click', function() {
|
|
28
|
+
if (canvas.getPlane(el.id)) {
|
|
29
|
+
canvas.setActivePlane(el.id);
|
|
30
|
+
} else {
|
|
31
|
+
var plane = canvas.findPlane(el.id);
|
|
32
|
+
canvas.setActivePlane(plane);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return link;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
path.forEach(function(el) {
|
|
40
|
+
breadcrumbs.appendChild(el);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
overlays.add(subProcess, {
|
|
44
|
+
position: {
|
|
45
|
+
top: -30,
|
|
46
|
+
left: -10
|
|
47
|
+
},
|
|
48
|
+
html: breadcrumbs
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var createDrilldown = function(element) {
|
|
53
|
+
var html = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
|
|
54
|
+
|
|
55
|
+
html.addEventListener('click', function() {
|
|
56
|
+
canvas.setActivePlane(element.id);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
overlays.add(element, {
|
|
60
|
+
position: {
|
|
61
|
+
bottom: -7,
|
|
62
|
+
right: -8
|
|
63
|
+
},
|
|
64
|
+
html: html
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
var addOverlays = function(elements) {
|
|
69
|
+
elements.forEach(function(element) {
|
|
70
|
+
if (is(element, 'bpmn:SubProcess')
|
|
71
|
+
&& element.collapsed
|
|
72
|
+
&& canvas.getPlane(element.id)) {
|
|
73
|
+
createDrilldown(element);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (is(element, 'bpmn:SubProcess') && element.isSecondary) {
|
|
77
|
+
createBreadcrumbs(element);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
eventBus.on('import.done', function() {
|
|
83
|
+
addOverlays(elementRegistry.filter(function(el) {
|
|
84
|
+
return is(el, 'bpmn:SubProcess');
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
SubprocessOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
var getParentChain = function(child) {
|
|
93
|
+
var bo = getBusinessObject(child);
|
|
94
|
+
|
|
95
|
+
var parents = [];
|
|
96
|
+
|
|
97
|
+
for (var element = bo; element; element = element.$parent) {
|
|
98
|
+
if (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Process')) {
|
|
99
|
+
parents.push(element);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return parents.reverse();
|
|
104
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import OverlaysModule from 'diagram-js/lib/features/overlays';
|
|
2
|
+
import ChangeSupportModule from 'diagram-js/lib/features/change-support';
|
|
3
|
+
|
|
4
|
+
import SubprocessElements from './SubprocessElements';
|
|
5
|
+
import SubprocessCentering from './SubprocessCentering';
|
|
6
|
+
import SubprocessCompatibility from './SubprocessCompatibility';
|
|
7
|
+
import SubprocessOverlays from './SubprocessOverlays';
|
|
8
|
+
import SubprocessFlows from './SubprocessFlows';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
__depends__: [ OverlaysModule, ChangeSupportModule ],
|
|
12
|
+
__init__: [ 'subprocessElements', 'subprocessOverlays', 'subprocessCompatibility', 'subprocessCentering', 'subprocessFlows' ],
|
|
13
|
+
subprocessElements: [ 'type', SubprocessElements ],
|
|
14
|
+
subprocessOverlays: [ 'type', SubprocessOverlays ],
|
|
15
|
+
subprocessCompatibility: [ 'type', SubprocessCompatibility ],
|
|
16
|
+
subprocessCentering: [ 'type', SubprocessCentering ],
|
|
17
|
+
subprocessFlows: ['type', SubprocessFlows]
|
|
18
|
+
};
|