mirror of
https://github.com/sartography/bpmn-js.git
synced 2025-01-23 23:38:59 +00:00
feat(drilldown): make overlays react to diagram changes
This commit is contained in:
parent
d3ecd92dcd
commit
4bd64e45e4
@ -103,3 +103,11 @@
|
|||||||
fill: var(--drilldown-fill-color);
|
fill: var(--drilldown-fill-color);
|
||||||
background-color: var(--drilldown-background-color);
|
background-color: var(--drilldown-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bjs-drilldown-empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected .bjs-drilldown-empty {
|
||||||
|
display: inherit;
|
||||||
|
}
|
@ -2,8 +2,7 @@ import { domify, classes } from 'min-dom';
|
|||||||
|
|
||||||
import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
|
import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
|
||||||
import { getBusinessObject, is } from '../../util/ModelUtil';
|
import { getBusinessObject, is } from '../../util/ModelUtil';
|
||||||
|
import { planeId } from '../../util/DrilldownUtil';
|
||||||
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>';
|
|
||||||
|
|
||||||
var OPEN_CLASS = 'bjs-breadcrumbs-shown';
|
var OPEN_CLASS = 'bjs-breadcrumbs-shown';
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ var OPEN_CLASS = 'bjs-breadcrumbs-shown';
|
|||||||
* @param {overlays} overlays
|
* @param {overlays} overlays
|
||||||
* @param {canvas} canvas
|
* @param {canvas} canvas
|
||||||
*/
|
*/
|
||||||
export default function DrilldownOverlays(eventBus, elementRegistry, overlays, canvas) {
|
export default function DrilldownBreadcrumbs(eventBus, elementRegistry, overlays, canvas) {
|
||||||
var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
|
var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
|
||||||
var container = canvas.getContainer();
|
var container = canvas.getContainer();
|
||||||
var containerClasses = classes(container);
|
var containerClasses = classes(container);
|
||||||
@ -51,41 +50,9 @@ export default function DrilldownOverlays(eventBus, elementRegistry, overlays, c
|
|||||||
updateBreadcrumbs(event.element);
|
updateBreadcrumbs(event.element);
|
||||||
});
|
});
|
||||||
|
|
||||||
var createOverlay = function(element) {
|
|
||||||
var html = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
|
|
||||||
|
|
||||||
html.addEventListener('click', function() {
|
|
||||||
canvas.setRootElement(canvas.findRoot(planeId(element)));
|
|
||||||
});
|
|
||||||
|
|
||||||
overlays.add(element, {
|
|
||||||
position: {
|
|
||||||
bottom: -7,
|
|
||||||
right: -8
|
|
||||||
},
|
|
||||||
html: html
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var addOverlays = function(elements) {
|
|
||||||
elements.forEach(function(element) {
|
|
||||||
|
|
||||||
if (is(element, 'bpmn:SubProcess')
|
|
||||||
&& element.collapsed
|
|
||||||
&& canvas.findRoot(planeId(element))) {
|
|
||||||
createOverlay(element);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
eventBus.on('import.done', function() {
|
|
||||||
addOverlays(elementRegistry.filter(function(el) {
|
|
||||||
return is(el, 'bpmn:SubProcess');
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrilldownOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
|
DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
|
||||||
|
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
@ -101,13 +68,4 @@ function getParentChain(child) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return parents.reverse();
|
return parents.reverse();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function planeId(element) {
|
|
||||||
if (is(element, 'bpmn:SubProcess')) {
|
|
||||||
return element.id + '_plane';
|
|
||||||
}
|
|
||||||
|
|
||||||
return element.id;
|
|
||||||
}
|
}
|
176
lib/features/drilldown/DrilldownOverlayBehavior.js
Normal file
176
lib/features/drilldown/DrilldownOverlayBehavior.js
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import inherits from 'inherits';
|
||||||
|
|
||||||
|
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
||||||
|
import { is } from '../../util/ModelUtil';
|
||||||
|
import { classes, domify } from 'min-dom';
|
||||||
|
import { planeId } from '../../util/DrilldownUtil';
|
||||||
|
|
||||||
|
var LOW_PRIORITY = 250;
|
||||||
|
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>';
|
||||||
|
|
||||||
|
var EMPTY_MARKER = 'bjs-drilldown-empty';
|
||||||
|
|
||||||
|
export default function DrilldownOverlayBehavior(
|
||||||
|
canvas, eventBus, elementRegistry, overlays
|
||||||
|
) {
|
||||||
|
CommandInterceptor.call(this, eventBus);
|
||||||
|
|
||||||
|
this._canvas = canvas;
|
||||||
|
this._eventBus = eventBus;
|
||||||
|
this._elementRegistry = elementRegistry;
|
||||||
|
this._overlays = overlays;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.executed('shape.toggleCollapse', LOW_PRIORITY, function(context) {
|
||||||
|
var shape = context.shape;
|
||||||
|
|
||||||
|
// Add overlay to the collapsed shape
|
||||||
|
if (self.canDrillDown(shape)) {
|
||||||
|
self.addOverlay(shape);
|
||||||
|
} else {
|
||||||
|
self.removeOverlay(shape);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
|
||||||
|
this.reverted('shape.toggleCollapse', LOW_PRIORITY, function(context) {
|
||||||
|
var shape = context.shape;
|
||||||
|
|
||||||
|
// Add overlay to the collapsed shape
|
||||||
|
if (self.canDrillDown(shape)) {
|
||||||
|
self.addOverlay(shape);
|
||||||
|
} else {
|
||||||
|
self.removeOverlay(shape);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
|
||||||
|
this.executed(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
|
||||||
|
function(context) {
|
||||||
|
var oldParent = context.oldParent,
|
||||||
|
newParent = context.newParent || context.parent,
|
||||||
|
shape = context.shape;
|
||||||
|
|
||||||
|
// Add overlay to the collapsed shape
|
||||||
|
if (self.canDrillDown(shape)) {
|
||||||
|
self.addOverlay(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateDrilldownOverlay(oldParent);
|
||||||
|
self.updateDrilldownOverlay(newParent);
|
||||||
|
self.updateDrilldownOverlay(shape);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
|
||||||
|
this.reverted(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
|
||||||
|
function(context) {
|
||||||
|
var oldParent = context.oldParent,
|
||||||
|
newParent = context.newParent || context.parent,
|
||||||
|
shape = context.shape;
|
||||||
|
|
||||||
|
// Add overlay to the collapsed shape
|
||||||
|
if (self.canDrillDown(shape)) {
|
||||||
|
self.addOverlay(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateDrilldownOverlay(oldParent);
|
||||||
|
self.updateDrilldownOverlay(newParent);
|
||||||
|
self.updateDrilldownOverlay(shape);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
|
||||||
|
eventBus.on('import.done', function() {
|
||||||
|
elementRegistry.filter(function(e) {
|
||||||
|
return self.canDrillDown(e);
|
||||||
|
}).map(function(el) {
|
||||||
|
self.addOverlay(el);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inherits(DrilldownOverlayBehavior, CommandInterceptor);
|
||||||
|
|
||||||
|
DrilldownOverlayBehavior.prototype.updateDrilldownOverlay = function(shape) {
|
||||||
|
var canvas = this._canvas;
|
||||||
|
|
||||||
|
if (!shape) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var root = canvas.findRoot(shape);
|
||||||
|
if (root) {
|
||||||
|
this.updateOverlayVisibility(root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DrilldownOverlayBehavior.prototype.canDrillDown = function(element) {
|
||||||
|
var canvas = this._canvas;
|
||||||
|
return is(element, 'bpmn:SubProcess') && canvas.findRoot(planeId(element));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates visibility of the drilldown overlay. If the plane has no elements,
|
||||||
|
* the drilldown will be only shown when the element is selected.
|
||||||
|
*
|
||||||
|
* @param {djs.model.Shape|djs.model.Root} element collapsed shape or root element
|
||||||
|
*/
|
||||||
|
DrilldownOverlayBehavior.prototype.updateOverlayVisibility = function(element) {
|
||||||
|
var overlays = this._overlays;
|
||||||
|
|
||||||
|
var bo = element.businessObject;
|
||||||
|
|
||||||
|
var overlay = overlays.get({ element: bo.id, type: 'drilldown' })[0];
|
||||||
|
|
||||||
|
if (!overlay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasContent = bo && bo.flowElements && bo.flowElements.length;
|
||||||
|
classes(overlay.html).toggle(EMPTY_MARKER, !hasContent);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a drilldown button to the given element. We assume that the plane has
|
||||||
|
* the same id as the element.
|
||||||
|
*
|
||||||
|
* @param {djs.model.Shape} element collapsed shape
|
||||||
|
*/
|
||||||
|
DrilldownOverlayBehavior.prototype.addOverlay = function(element) {
|
||||||
|
var canvas = this._canvas;
|
||||||
|
var overlays = this._overlays;
|
||||||
|
|
||||||
|
var button = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
|
||||||
|
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
canvas.setRootElement(canvas.findRoot(planeId(element)));
|
||||||
|
});
|
||||||
|
|
||||||
|
overlays.add(element, 'drilldown', {
|
||||||
|
position: {
|
||||||
|
bottom: -7,
|
||||||
|
right: -8
|
||||||
|
},
|
||||||
|
html: button
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateOverlayVisibility(element);
|
||||||
|
};
|
||||||
|
|
||||||
|
DrilldownOverlayBehavior.prototype.removeOverlay = function(element) {
|
||||||
|
var overlays = this._overlays;
|
||||||
|
|
||||||
|
overlays.remove({
|
||||||
|
element: element,
|
||||||
|
type: 'drilldown'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DrilldownOverlayBehavior.$inject = [
|
||||||
|
'canvas',
|
||||||
|
'eventBus',
|
||||||
|
'elementRegistry',
|
||||||
|
'overlays'
|
||||||
|
];
|
@ -1,14 +1,17 @@
|
|||||||
import OverlaysModule from 'diagram-js/lib/features/overlays';
|
import OverlaysModule from 'diagram-js/lib/features/overlays';
|
||||||
import ChangeSupportModule from 'diagram-js/lib/features/change-support';
|
import ChangeSupportModule from 'diagram-js/lib/features/change-support';
|
||||||
|
import RootElementsModule from 'diagram-js/lib/features/root-elements';
|
||||||
|
|
||||||
import DrilldownOverlays from './DrilldownOverlays';
|
import DrilldownBreadcrumbs from './DrilldownBreadcrumbs';
|
||||||
import DrilldownCentering from './DrilldownCentering';
|
import DrilldownCentering from './DrilldownCentering';
|
||||||
import SubprocessCompatibility from './SubprocessCompatibility';
|
import SubprocessCompatibility from './SubprocessCompatibility';
|
||||||
|
import DrilldownOverlayBehavior from './DrilldownOverlayBehavior';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
__depends__: [ OverlaysModule, ChangeSupportModule ],
|
__depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
|
||||||
__init__: [ 'drilldownOverlays', 'drilldownCentering', 'subprocessCompatibility'],
|
__init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility'],
|
||||||
drilldownOverlays: [ 'type', DrilldownOverlays ],
|
drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
|
||||||
drilldownCentering: [ 'type', DrilldownCentering ],
|
drilldownCentering: [ 'type', DrilldownCentering ],
|
||||||
|
drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
|
||||||
subprocessCompatibility: [ 'type', SubprocessCompatibility ]
|
subprocessCompatibility: [ 'type', SubprocessCompatibility ]
|
||||||
};
|
};
|
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_007va6i" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.2.0-dev">
|
||||||
|
<bpmn:process id="Process_1giw3j5" isExecutable="true">
|
||||||
|
<bpmn:subProcess id="Subprocess_with_content">
|
||||||
|
<bpmn:startEvent id="StartEvent_embedded" />
|
||||||
|
</bpmn:subProcess>
|
||||||
|
<bpmn:subProcess id="Subprocess_empty" />
|
||||||
|
<bpmn:subProcess id="Subprocess_expanded">
|
||||||
|
<bpmn:startEvent id="Event_14hgp9z" />
|
||||||
|
</bpmn:subProcess>
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1giw3j5">
|
||||||
|
<bpmndi:BPMNShape id="Activity_175iapo_di" bpmnElement="Subprocess_with_content">
|
||||||
|
<dc:Bounds x="300" y="81" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1vrbgo0_di" bpmnElement="Subprocess_empty">
|
||||||
|
<dc:Bounds x="140" y="81" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Subprocess_expanded_di" bpmnElement="Subprocess_expanded" isExpanded="true">
|
||||||
|
<dc:Bounds x="140" y="220" width="350" height="200" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Event_14hgp9z_di" bpmnElement="Event_14hgp9z">
|
||||||
|
<dc:Bounds x="180" y="302" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1widlc2">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_0epf6vs" bpmnElement="Subprocess_with_content">
|
||||||
|
<bpmndi:BPMNShape id="StartEvent_embedded_di" bpmnElement="StartEvent_embedded">
|
||||||
|
<dc:Bounds x="132" y="112" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1res3mc">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_0iznbzu" bpmnElement="Subprocess_empty" />
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
391
test/spec/features/drilldown/DrilldownOverlaysBehaviorSpec.js
Normal file
391
test/spec/features/drilldown/DrilldownOverlaysBehaviorSpec.js
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
import {
|
||||||
|
bootstrapModeler,
|
||||||
|
inject
|
||||||
|
} from 'test/TestHelper';
|
||||||
|
|
||||||
|
import coreModule from 'lib/core';
|
||||||
|
import modelingModule from 'lib/features/modeling';
|
||||||
|
import replaceModule from 'lib/features/replace';
|
||||||
|
import drilldownModule from 'lib/features/drilldown';
|
||||||
|
import { classes } from 'min-dom';
|
||||||
|
|
||||||
|
describe('features/modeling/behavior - subprocess planes', function() {
|
||||||
|
|
||||||
|
var diagramXML = require('./DrilldownOverlayBehaviorSpec.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(diagramXML, {
|
||||||
|
modules: [
|
||||||
|
coreModule,
|
||||||
|
modelingModule,
|
||||||
|
replaceModule,
|
||||||
|
drilldownModule
|
||||||
|
]
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
describe('create new drilldowns', function() {
|
||||||
|
|
||||||
|
it('should create drilldown for new process',
|
||||||
|
inject(function(elementFactory, modeling, canvas, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementFactory.createShape({
|
||||||
|
type: 'bpmn:SubProcess',
|
||||||
|
isExpanded: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(subProcess, { x: 300, y: 300 }, canvas.getRootElement());
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.be.empty;
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should not create drilldown for expanded subprocess',
|
||||||
|
inject(function(elementFactory, modeling, canvas, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementFactory.createShape({
|
||||||
|
type: 'bpmn:SubProcess',
|
||||||
|
isExpanded: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(subProcess, { x: 300, y: 300 }, canvas.getRootElement());
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.be.empty;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo',
|
||||||
|
inject(function(elementFactory, modeling, commandStack, canvas, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementFactory.createShape({
|
||||||
|
type: 'bpmn:SubProcess',
|
||||||
|
isExpanded: false
|
||||||
|
});
|
||||||
|
modeling.createShape(subProcess, { x: 300, y: 300 }, canvas.getRootElement());
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.be.empty;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo',
|
||||||
|
inject(function(elementFactory, modeling, commandStack, canvas, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementFactory.createShape({
|
||||||
|
type: 'bpmn:SubProcess',
|
||||||
|
isExpanded: false
|
||||||
|
});
|
||||||
|
modeling.createShape(subProcess, { x: 300, y: 300 }, canvas.getRootElement());
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.be.empty;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should recreate drilldown on undo delete',
|
||||||
|
inject(function(elementRegistry, modeling, commandStack, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
modeling.removeShape(subProcess);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.be.empty;
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('overlay visibility', function() {
|
||||||
|
|
||||||
|
describe('empty subprocess', function() {
|
||||||
|
|
||||||
|
it('should hide drilldown', inject(function(elementRegistry, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_empty');
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.true;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should show when content is added',
|
||||||
|
inject(function(elementRegistry, overlays, elementFactory, modeling, canvas) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_empty');
|
||||||
|
var task = elementFactory.createShape({ type: 'bpmn:Task' });
|
||||||
|
var planeRoot = canvas.findRoot('Subprocess_empty_plane');
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(task, { x: 300, y: 300 }, planeRoot);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo',
|
||||||
|
inject(function(elementRegistry, overlays, elementFactory,
|
||||||
|
modeling, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_empty');
|
||||||
|
var task = elementFactory.createShape({ type: 'bpmn:Task' });
|
||||||
|
var planeRoot = canvas.findRoot('Subprocess_empty_plane');
|
||||||
|
|
||||||
|
modeling.createShape(task, { x: 300, y: 300 }, planeRoot);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo',
|
||||||
|
inject(function(elementRegistry, overlays, elementFactory,
|
||||||
|
modeling, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_empty');
|
||||||
|
var task = elementFactory.createShape({ type: 'bpmn:Task' });
|
||||||
|
var planeRoot = canvas.findRoot('Subprocess_empty_plane');
|
||||||
|
modeling.createShape(task, { x: 300, y: 300 }, planeRoot);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('subprocess with content', function() {
|
||||||
|
|
||||||
|
it('should show drilldown', inject(function(elementRegistry, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should hide when content is removed',
|
||||||
|
inject(function(elementRegistry, overlays, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
var startEvent = elementRegistry.get('StartEvent_embedded');
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.removeShape(startEvent);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo',
|
||||||
|
inject(function(elementRegistry, overlays, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
var startEvent = elementRegistry.get('StartEvent_embedded');
|
||||||
|
modeling.removeShape(startEvent);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo',
|
||||||
|
inject(function(elementRegistry, overlays, modeling, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
var startEvent = elementRegistry.get('StartEvent_embedded');
|
||||||
|
modeling.removeShape(startEvent);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var overlay = overlays.get({ element: subProcess })[0];
|
||||||
|
|
||||||
|
expect(classes(overlay.html).contains('bjs-drilldown-empty')).to.be.true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('expand/collapse', function() {
|
||||||
|
|
||||||
|
describe('collapse', function() {
|
||||||
|
|
||||||
|
it('should create new overlay on collapse',
|
||||||
|
inject(function(elementRegistry, modeling, canvas, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_expanded');
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.be.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo',
|
||||||
|
inject(function(elementRegistry, modeling, overlays, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_expanded');
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.be.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo',
|
||||||
|
inject(function(elementRegistry, modeling, overlays, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_expanded');
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.be.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('expand', function() {
|
||||||
|
|
||||||
|
it('should remove overlay on expand',
|
||||||
|
inject(function(elementRegistry, modeling, overlays) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.be.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should undo',
|
||||||
|
inject(function(elementRegistry, modeling, overlays, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.not.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should redo',
|
||||||
|
inject(function(elementRegistry, modeling, overlays, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var subProcess = elementRegistry.get('Subprocess_with_content');
|
||||||
|
modeling.toggleCollapse(subProcess);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
commandStack.redo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
var elementOverlays = overlays.get({ element: subProcess });
|
||||||
|
expect(elementOverlays).to.be.empty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user