diff --git a/lib/features/drilldown/DrilldownBreadcrumbs.js b/lib/features/drilldown/DrilldownBreadcrumbs.js index 0fb9d54d..aec0e93a 100644 --- a/lib/features/drilldown/DrilldownBreadcrumbs.js +++ b/lib/features/drilldown/DrilldownBreadcrumbs.js @@ -1,8 +1,9 @@ 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 { planeId } from '../../util/DrilldownUtil'; +import { isPlane, planeId, primaryShape } from '../../util/DrilldownUtil'; var OPEN_CLASS = 'bjs-breadcrumbs-shown'; @@ -21,8 +22,47 @@ export default function DrilldownBreadcrumbs(eventBus, elementRegistry, overlays var containerClasses = classes(container); container.appendChild(breadcrumbs); - function updateBreadcrumbs(currentRoot) { - var boParents = getBoParentChain(currentRoot); + var boParents = []; + + // Update primary shape if Name or ID of the plane changes + eventBus.on('element.changed', function(e) { + var shape = e.element; + + if (!isPlane(shape)) { + return; + } + + var primary = elementRegistry.get(primaryShape(shape)); + + primary && eventBus.fire('element.changed', { element: primary }); + }); + + // update breadcrumbs if name/id of the primary shape changes + eventBus.on('element.changed', function(e) { + var shape = e.element, + bo = getBusinessObject(shape); + + var isPresent = find(boParents, function(el) { + return el === bo; + }); + + if (!isPresent) { + return; + } + + updateBreadcrumbs(); + }); + + /** + * Updates the displayed breadcrumbs. If no element is provided, only the + * labels are updated. + * + * @param {djs.model.Base} [element] + */ + function updateBreadcrumbs(element) { + if (element) { + boParents = getBoParentChain(element); + } var path = boParents.map(function(parent) { var title = escapeHTML(parent.name || parent.id); diff --git a/lib/util/DrilldownUtil.js b/lib/util/DrilldownUtil.js index f512a646..eb8e70c4 100644 --- a/lib/util/DrilldownUtil.js +++ b/lib/util/DrilldownUtil.js @@ -1,4 +1,4 @@ -import { is } from './ModelUtil'; +import { getDi, is } from './ModelUtil'; export var planePostfix = '_plane'; @@ -26,4 +26,25 @@ export function planeId(element) { */ export function asPlaneId(string) { return string + planePostfix; +} + +/** + * Returns wether the given element is a plane. + * + * @param {djs.model.Base|ModdleElement} element + * @returns {Boolean} + */ +export function isPlane(element) { + var di = getDi(element); + return is(di, 'bpmndi:BPMNPlane'); +} + +/** + * Returns the ID of the primary Shape for a plane. + * + * @param {djs.model.Base|ModdleElement} element + * @returns {String} + */ +export function primaryShape(element) { + return element.id.replace(planePostfix, ''); } \ No newline at end of file diff --git a/test/spec/features/drilldown/DrilldownIntegrationSpec.js b/test/spec/features/drilldown/DrilldownIntegrationSpec.js index 6f0f7b85..78274b7a 100644 --- a/test/spec/features/drilldown/DrilldownIntegrationSpec.js +++ b/test/spec/features/drilldown/DrilldownIntegrationSpec.js @@ -108,6 +108,51 @@ describe('features - drilldown', function() { }); + + describe('Breadcrumbs - Name changes', function() { + + it('should update on plane name change', + inject(function(canvas, modeling) { + + // given + canvas.setRootElement(canvas.findRoot('collapsedProcess_2_plane')); + + // when + modeling.updateProperties(canvas.getRootElement(), { name: 'new name' }); + + // then + expectBreadcrumbs([ + 'Root', + 'Collapsed Process', + 'Expanded Process', + 'new name' + ]); + }) + ); + + + it('should update on element name change', + inject(function(canvas, elementRegistry, modeling) { + + // given + canvas.setRootElement(canvas.findRoot('collapsedProcess_2_plane')); + var shape = elementRegistry.get('collapsedProcess_2'); + + // when + modeling.updateProperties(shape, { name: 'new name' }); + + // then + expectBreadcrumbs([ + 'Root', + 'Collapsed Process', + 'Expanded Process', + 'new name' + ]); + }) + ); + + }); + }); @@ -122,4 +167,20 @@ function expectViewbox(expectedViewbox) { expect(viewbox.y).to.eql(expectedViewbox.y); expect(viewbox.scale).to.eql(expectedViewbox.scale); }); +} + +function getBreadcrumbs() { + return getBpmnJS().invoke(function(canvas) { + return canvas.getContainer().querySelector('.bjs-breadcrumbs'); + }); +} + +function expectBreadcrumbs(expected) { + var breadcrumbs = getBreadcrumbs(); + + var crumbs = Array.from(breadcrumbs.children).map(function(element) { + return element.innerText; + }); + + expect(crumbs).to.eql(expected); } \ No newline at end of file