-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathDrilldownBreadcrumbs.js
139 lines (107 loc) · 3.77 KB
/
DrilldownBreadcrumbs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { domify, classes } from 'min-dom';
import { find } from 'min-dash';
import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
import { getBusinessObject, is } from '../../util/ModelUtil';
import {
getPlaneIdFromShape
} from '../../util/DrilldownUtil';
/**
* @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
* @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
* @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
*
* @typedef {import('../../model/Types').Element} Element
* @typedef {import('../../model/Types').Shape} Shape
*/
var OPEN_CLASS = 'bjs-breadcrumbs-shown';
/**
* Adds overlays that allow switching planes on collapsed subprocesses.
*
* @param {EventBus} eventBus
* @param {ElementRegistry} elementRegistry
* @param {Canvas} canvas
*/
export default function DrilldownBreadcrumbs(eventBus, elementRegistry, canvas) {
var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
var container = canvas.getContainer();
var containerClasses = classes(container);
container.appendChild(breadcrumbs);
var businessObjectParents = [];
// update breadcrumbs if name or ID of the primary shape changes
eventBus.on('element.changed', function(event) {
var shape = event.element,
businessObject = getBusinessObject(shape);
var isPresent = find(businessObjectParents, function(element) {
return element === businessObject;
});
if (!isPresent) {
return;
}
updateBreadcrumbs();
});
/**
* Updates the displayed breadcrumbs. If no element is provided, only the
* labels are updated.
*
* @param {Element} [element]
*/
function updateBreadcrumbs(element) {
if (element) {
businessObjectParents = getBusinessObjectParentChain(element);
}
var path = businessObjectParents.flatMap(function(parent) {
var parentPlane =
canvas.findRoot(getPlaneIdFromShape(parent)) ||
canvas.findRoot(parent.id);
// when the root is a collaboration, the process does not have a
// corresponding element in the elementRegisty. Instead, we search
// for the corresponding participant
if (!parentPlane && is(parent, 'bpmn:Process')) {
var participant = elementRegistry.find(function(element) {
var businessObject = getBusinessObject(element);
return businessObject && businessObject.get('processRef') === parent;
});
parentPlane = participant && canvas.findRoot(participant.id);
}
if (!parentPlane) {
return [];
}
var title = escapeHTML(parent.name || parent.id);
var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
link.addEventListener('click', function() {
canvas.setRootElement(parentPlane);
});
return link;
});
breadcrumbs.innerHTML = '';
// show breadcrumbs and expose state to .djs-container
var visible = path.length > 1;
containerClasses.toggle(OPEN_CLASS, visible);
path.forEach(function(element) {
breadcrumbs.appendChild(element);
});
}
eventBus.on('root.set', function(event) {
updateBreadcrumbs(event.element);
});
}
DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'canvas' ];
// helpers //////////
/**
* Returns the parents for the element using the business object chain,
* starting with the root element.
*
* @param {Shape} child
*
* @return {Shape}
*/
function getBusinessObjectParentChain(child) {
var businessObject = getBusinessObject(child);
var parents = [];
for (var element = businessObject; element; element = element.$parent) {
if (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Process')) {
parents.push(element);
}
}
return parents.reverse();
}