feat(replace): properly collapse / expand SubProcess(es)
* correctly toggle collapse / expand state * update children visibility Closes #575 Closes #510 review(collapse-expand)
This commit is contained in:
parent
4714a7279d
commit
226a0d76ed
|
@ -0,0 +1,139 @@
|
|||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
|
||||
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'),
|
||||
getBusinessObject = require('../../../util/ModelUtil').getBusinessObject,
|
||||
is = require('../../../util/ModelUtil').is,
|
||||
computeChildrenBBox = require('diagram-js/lib/features/resize/ResizeUtil').computeChildrenBBox;
|
||||
|
||||
|
||||
var LOW_PRIORITY = 500;
|
||||
|
||||
|
||||
function ToggleElementCollapseBehaviour(eventBus, elementFactory, modeling, resize) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
|
||||
function hideEmptyLables(children) {
|
||||
if (children.length) {
|
||||
children.forEach(function(child) {
|
||||
if (child.type === 'label' && !child.businessObject.name) {
|
||||
child.hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function expandedBounds(shape, defaultSize) {
|
||||
var children = shape.children,
|
||||
newBounds = defaultSize,
|
||||
visibleElements,
|
||||
visibleBBox;
|
||||
|
||||
visibleElements = filterVisible(children).concat([ shape ]);
|
||||
|
||||
visibleBBox = computeChildrenBBox(visibleElements);
|
||||
|
||||
if (visibleBBox) {
|
||||
// center to visibleBBox with max(defaultSize, childrenBounds)
|
||||
newBounds.width = Math.max(visibleBBox.width, newBounds.width);
|
||||
newBounds.height = Math.max(visibleBBox.height, newBounds.height);
|
||||
|
||||
newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2;
|
||||
newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2;
|
||||
} else {
|
||||
// center to collapsed shape with defaultSize
|
||||
newBounds.x = shape.x + (shape.width - newBounds.width) / 2;
|
||||
newBounds.y = shape.y + (shape.height - newBounds.height) / 2;
|
||||
}
|
||||
|
||||
return newBounds;
|
||||
}
|
||||
|
||||
function collapsedBounds(shape, defaultSize) {
|
||||
|
||||
return {
|
||||
x: shape.x + (shape.width - defaultSize.width) / 2,
|
||||
y: shape.y + (shape.height - defaultSize.height) / 2,
|
||||
width: defaultSize.width,
|
||||
height: defaultSize.height
|
||||
};
|
||||
}
|
||||
|
||||
this.executed([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
|
||||
|
||||
var context = e.context,
|
||||
shape = context.shape;
|
||||
|
||||
if (!is(shape, 'bpmn:SubProcess')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shape.collapsed) {
|
||||
// all children got made visible through djs, hide empty labels
|
||||
hideEmptyLables(shape.children);
|
||||
|
||||
// remove collapsed marker
|
||||
getBusinessObject(shape).di.isExpanded = true;
|
||||
} else {
|
||||
// place collapsed marker
|
||||
getBusinessObject(shape).di.isExpanded = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.reverted([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
|
||||
|
||||
var context = e.context;
|
||||
var shape = context.shape;
|
||||
|
||||
|
||||
// revert removing/placing collapsed marker
|
||||
if (!shape.collapsed) {
|
||||
getBusinessObject(shape).di.isExpanded = true;
|
||||
|
||||
} else {
|
||||
getBusinessObject(shape).di.isExpanded = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.postExecuted([ 'shape.toggleCollapse' ], LOW_PRIORITY, function(e) {
|
||||
var shape = e.context.shape,
|
||||
defaultSize = elementFactory._getDefaultSize(shape),
|
||||
newBounds;
|
||||
|
||||
if (shape.collapsed) {
|
||||
|
||||
// resize to default size of collapsed shapes
|
||||
newBounds = collapsedBounds(shape, defaultSize);
|
||||
} else {
|
||||
|
||||
// resize to bounds of max(visible children, defaultSize)
|
||||
newBounds = expandedBounds(shape, defaultSize);
|
||||
}
|
||||
|
||||
modeling.resizeShape(shape, newBounds);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
inherits(ToggleElementCollapseBehaviour, CommandInterceptor);
|
||||
|
||||
ToggleElementCollapseBehaviour.$inject = [
|
||||
'eventBus',
|
||||
'elementFactory',
|
||||
'modeling'
|
||||
];
|
||||
|
||||
module.exports = ToggleElementCollapseBehaviour;
|
||||
|
||||
|
||||
|
||||
/////// helpers ///////////////////////////
|
||||
|
||||
function filterVisible(elements) {
|
||||
return elements.filter(function(e) {
|
||||
return !e.hidden;
|
||||
});
|
||||
}
|
|
@ -18,7 +18,8 @@ module.exports = {
|
|||
'unsetDefaultFlowBehavior',
|
||||
'updateFlowNodeRefsBehavior',
|
||||
'removeElementBehavior',
|
||||
'unclaimIdBehavior'
|
||||
'unclaimIdBehavior',
|
||||
'toggleElementCollapseBehaviour'
|
||||
],
|
||||
appendBehavior: [ 'type', require('./AppendBehavior') ],
|
||||
copyPasteBehavior: [ 'type', require('./CopyPasteBehavior') ],
|
||||
|
@ -38,5 +39,6 @@ module.exports = {
|
|||
unsetDefaultFlowBehavior: [ 'type', require('./UnsetDefaultFlowBehavior') ],
|
||||
updateFlowNodeRefsBehavior: [ 'type', require('./UpdateFlowNodeRefsBehavior') ],
|
||||
removeElementBehavior: [ 'type', require('./RemoveElementBehavior') ],
|
||||
unclaimIdBehavior: [ 'type', require('./UnclaimIdBehavior') ]
|
||||
unclaimIdBehavior: [ 'type', require('./UnclaimIdBehavior') ],
|
||||
toggleElementCollapseBehaviour : [ 'type', require('./ToggleElementCollapseBehaviour') ]
|
||||
};
|
||||
|
|
|
@ -7,7 +7,8 @@ var is = require('../../util/ModelUtil').is,
|
|||
isDifferentType = require('./util/TypeUtil').isDifferentType;
|
||||
|
||||
var forEach = require('lodash/collection/forEach'),
|
||||
filter = require('lodash/collection/filter');
|
||||
filter = require('lodash/collection/filter'),
|
||||
reject = require('lodash/collection/reject');
|
||||
|
||||
var replaceOptions = require ('../replace/ReplaceOptions');
|
||||
|
||||
|
@ -210,6 +211,13 @@ ReplaceMenuProvider.prototype.getEntries = function(element) {
|
|||
});
|
||||
}
|
||||
|
||||
// collapsed SubProcess can not be replaced with itself
|
||||
if (is(businessObject, 'bpmn:SubProcess') && !isExpanded(businessObject)) {
|
||||
entries = reject(entries, function(entry) {
|
||||
return entry.label === 'Sub Process (collapsed)';
|
||||
});
|
||||
}
|
||||
|
||||
return this._createEntries(element, entries);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
var pick = require('lodash/object/pick'),
|
||||
assign = require('lodash/object/assign');
|
||||
assign = require('lodash/object/assign'),
|
||||
has = require('lodash/object/has');
|
||||
|
||||
var is = require('../../util/ModelUtil').is,
|
||||
isExpanded = require('../../util/DiUtil').isExpanded,
|
||||
|
@ -15,6 +16,30 @@ var CUSTOM_PROPERTIES = [
|
|||
'isInterrupting'
|
||||
];
|
||||
|
||||
function toggeling(element, target) {
|
||||
|
||||
var oldCollapsed = has(element, 'collapsed') ?
|
||||
element.collapsed : !isExpanded(element);
|
||||
|
||||
var targetCollapsed;
|
||||
|
||||
if (has(target, 'collapsed') || has(target, 'isExpanded')) {
|
||||
// property is explicitly set so use it
|
||||
targetCollapsed = has(target, 'collapsed') ?
|
||||
target.collapsed : !target.isExpanded;
|
||||
} else {
|
||||
// keep old state
|
||||
targetCollapsed = oldCollapsed;
|
||||
}
|
||||
|
||||
if (oldCollapsed !== targetCollapsed) {
|
||||
element.collapsed = oldCollapsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This module takes care of replacing BPMN elements
|
||||
|
@ -36,8 +61,23 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
hints = hints || {};
|
||||
|
||||
var type = target.type,
|
||||
oldBusinessObject = element.businessObject,
|
||||
newBusinessObject = bpmnFactory.create(type);
|
||||
oldBusinessObject = element.businessObject;
|
||||
|
||||
|
||||
|
||||
if (is(oldBusinessObject, 'bpmn:SubProcess')) {
|
||||
if (type === 'bpmn:SubProcess') {
|
||||
if (toggeling(element, target)) {
|
||||
// expanding or collapsing process
|
||||
modeling.toggleCollapse(element);
|
||||
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var newBusinessObject = bpmnFactory.create(type);
|
||||
|
||||
var newElement = {
|
||||
type: type,
|
||||
|
@ -52,21 +92,16 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
// initialize special properties defined in target definition
|
||||
assign(newBusinessObject, pick(target, CUSTOM_PROPERTIES));
|
||||
|
||||
if (is(oldBusinessObject, 'bpmn:SubProcess')) {
|
||||
|
||||
newElement.isExpanded = isExpanded(oldBusinessObject);
|
||||
}
|
||||
|
||||
// preserve adhoc state while switching collapsed/expanded subprocess
|
||||
if (is(oldBusinessObject, 'bpmn:AdHocSubProcess') && target.isExpanded) {
|
||||
newElement.businessObject = bpmnFactory.create('bpmn:AdHocSubProcess');
|
||||
}
|
||||
|
||||
if (is(oldBusinessObject, 'bpmn:Activity')) {
|
||||
|
||||
// switch collapsed/expanded subprocesses
|
||||
if (target.isExpanded === true) {
|
||||
newElement.isExpanded = true;
|
||||
if (is(oldBusinessObject, 'bpmn:SubProcess')) {
|
||||
// no toggeling, so keep old state
|
||||
newElement.isExpanded = isExpanded(oldBusinessObject);
|
||||
}
|
||||
// else if property is explicitly set, use it
|
||||
else if (has(target, 'isExpanded')) {
|
||||
newElement.isExpanded = target.isExpanded;
|
||||
}
|
||||
|
||||
// TODO: need also to respect min/max Size
|
||||
|
|
|
@ -357,6 +357,15 @@ module.exports.SUBPROCESS_EXPANDED = [
|
|||
triggeredByEvent: true,
|
||||
isExpanded: true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Sub Process (collapsed)',
|
||||
actionName: 'replace-with-collapsed-subprocess',
|
||||
className: 'bpmn-icon-subprocess-collapsed',
|
||||
target: {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -1,149 +1,273 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_U0Z10NLzEeSKyddZMwwjAA" exporter="camunda modeler" exporterVersion="2.7.0" targetNamespace="http://activiti.org/bpmn">
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_U0Z10NLzEeSKyddZMwwjAA" targetNamespace="http://camunda.org/schema/1.0/bpmn" exporter="Camunda Modeler" exporterVersion="0.7.0-dev" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
|
||||
<bpmn2:process id="Process_1" isExecutable="false">
|
||||
<bpmn2:subProcess id="SubProcess_1">
|
||||
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
|
||||
<bpmn2:startEvent id="StartEvent_2">
|
||||
<bpmn2:startEvent id="StartEvent_2" name="StartEvent_2">
|
||||
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="StartEvent_2" targetRef="ExclusiveGateway_1"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="StartEvent_2" targetRef="ExclusiveGateway_1" />
|
||||
<bpmn2:exclusiveGateway id="ExclusiveGateway_1">
|
||||
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ExclusiveGateway_1" targetRef="Task_1"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="ExclusiveGateway_1" targetRef="ScriptTask_1"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ExclusiveGateway_1" targetRef="Task_1" />
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="ExclusiveGateway_1" targetRef="ScriptTask_1" />
|
||||
<bpmn2:scriptTask id="ScriptTask_1">
|
||||
<bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
|
||||
</bpmn2:scriptTask>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_7" name="" sourceRef="ScriptTask_1" targetRef="EndEvent_3"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_7" name="" sourceRef="ScriptTask_1" targetRef="EndEvent_3" />
|
||||
<bpmn2:task id="Task_1">
|
||||
<bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="Task_1" targetRef="EndEvent_1"/>
|
||||
<bpmn2:endEvent id="EndEvent_1">
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="Task_1" targetRef="EndEvent_1" />
|
||||
<bpmn2:endEvent id="EndEvent_1" name="EndEvent_1">
|
||||
<bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:endEvent id="EndEvent_3">
|
||||
<bpmn2:endEvent id="EndEvent_3" name="EndEvent_3">
|
||||
<bpmn2:incoming>SequenceFlow_7</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
</bpmn2:subProcess>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_4" name="" sourceRef="SubProcess_1" targetRef="EndEvent_2"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_4" name="" sourceRef="SubProcess_1" targetRef="EndEvent_2" />
|
||||
<bpmn2:startEvent id="StartEvent_1">
|
||||
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="SubProcess_1"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="SubProcess_1" />
|
||||
<bpmn2:endEvent id="EndEvent_2">
|
||||
<bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:startEvent id="StartEvent_4">
|
||||
<bpmn2:outgoing>SequenceFlow_9</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_9" sourceRef="StartEvent_4" targetRef="SubProcess_2" />
|
||||
<bpmn2:endEvent id="EndEvent_5">
|
||||
<bpmn2:incoming>SequenceFlow_8</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="SubProcess_2" targetRef="EndEvent_5" />
|
||||
<bpmn2:subProcess id="SubProcess_3" />
|
||||
<bpmn2:adHocSubProcess id="SubProcess_4">
|
||||
<bpmn2:multiInstanceLoopCharacteristics />
|
||||
<bpmn2:startEvent id="StartEvent_5" />
|
||||
</bpmn2:adHocSubProcess>
|
||||
<bpmn2:adHocSubProcess id="SubProcess_2">
|
||||
<bpmn2:incoming>SequenceFlow_9</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_8</bpmn2:outgoing>
|
||||
<bpmn2:multiInstanceLoopCharacteristics />
|
||||
<bpmn2:startEvent id="StartEvent_3">
|
||||
<bpmn2:outgoing>SequenceFlow_10</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:task id="Task_2">
|
||||
<bpmn2:incoming>SequenceFlow_10</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_11</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:endEvent id="EndEvent_4">
|
||||
<bpmn2:incoming>SequenceFlow_11</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_10" sourceRef="StartEvent_3" targetRef="Task_2" />
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_11" sourceRef="Task_2" targetRef="EndEvent_4" />
|
||||
</bpmn2:adHocSubProcess>
|
||||
<bpmn2:subProcess id="SubProcess_5">
|
||||
<bpmn2:startEvent id="StartEvent_6" />
|
||||
</bpmn2:subProcess>
|
||||
<bpmn2:subProcess id="SubProcess_6" />
|
||||
</bpmn2:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_26" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="300.0" y="229.0"/>
|
||||
<dc:Bounds x="300" y="176" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="318.0" y="270.0"/>
|
||||
<dc:Bounds x="273" y="217" width="90" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_8" bpmnElement="SubProcess_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="532.0" y="207.0"/>
|
||||
<dc:Bounds x="532" y="154" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_26" targetElement="_BPMNShape_SubProcess_8">
|
||||
<di:waypoint xsi:type="dc:Point" x="336.0" y="247.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="532.0" y="247.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="336" y="194" />
|
||||
<di:waypoint xsi:type="dc:Point" x="532" y="194" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="364.0" y="247.0"/>
|
||||
<dc:Bounds x="364" y="194" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_27" bpmnElement="StartEvent_2">
|
||||
<dc:Bounds height="36.0" width="36.0" x="396.0" y="144.0"/>
|
||||
<dc:Bounds x="396" y="91" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="414.0" y="185.0"/>
|
||||
<dc:Bounds x="370" y="132" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="564.0" y="132.0"/>
|
||||
<dc:Bounds x="564" y="79" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_StartEvent_27" targetElement="_BPMNShape_ExclusiveGateway_19">
|
||||
<di:waypoint xsi:type="dc:Point" x="432.0" y="162.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="480.0" y="162.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="480.0" y="198.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="432" y="109" />
|
||||
<di:waypoint xsi:type="dc:Point" x="480" y="109" />
|
||||
<di:waypoint xsi:type="dc:Point" x="480" y="145" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="454.0" y="162.0"/>
|
||||
<dc:Bounds x="412" y="109" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_58" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="732.0" y="144.0"/>
|
||||
<dc:Bounds x="767" y="91" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="750.0" y="185.0"/>
|
||||
<dc:Bounds x="740" y="132" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_Task_3" targetElement="_BPMNShape_EndEvent_58">
|
||||
<di:waypoint xsi:type="dc:Point" x="664.0" y="172.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="704.0" y="172.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="704.0" y="162.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="732.0" y="162.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="664" y="119" />
|
||||
<di:waypoint xsi:type="dc:Point" x="704" y="119" />
|
||||
<di:waypoint xsi:type="dc:Point" x="704" y="109" />
|
||||
<di:waypoint xsi:type="dc:Point" x="767" y="109" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="686.0" y="172.0"/>
|
||||
<dc:Bounds x="674" y="111" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_59" bpmnElement="EndEvent_2">
|
||||
<dc:Bounds height="36.0" width="36.0" x="840.0" y="229.0"/>
|
||||
<dc:Bounds x="875" y="176" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="858.0" y="270.0"/>
|
||||
<dc:Bounds x="848" y="217" width="90" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_4" bpmnElement="SequenceFlow_4" sourceElement="_BPMNShape_SubProcess_8" targetElement="_BPMNShape_EndEvent_59">
|
||||
<di:waypoint xsi:type="dc:Point" x="632.0" y="247.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="813.0" y="246.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="840.0" y="247.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="632" y="194" />
|
||||
<di:waypoint xsi:type="dc:Point" x="813" y="195" />
|
||||
<di:waypoint xsi:type="dc:Point" x="875" y="195" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="634.0" y="247.0"/>
|
||||
<dc:Bounds x="677.5" y="176.5" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_19" bpmnElement="ExclusiveGateway_1" isMarkerVisible="true">
|
||||
<dc:Bounds height="50.0" width="50.0" x="455.0" y="198.0"/>
|
||||
<dc:Bounds x="455" y="145" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="480.0" y="253.0"/>
|
||||
<dc:Bounds x="435" y="200" width="90" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_ExclusiveGateway_19" targetElement="_BPMNShape_Task_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="505.0" y="223.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="541.0" y="223.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="541.0" y="172.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="564.0" y="172.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="505" y="170" />
|
||||
<di:waypoint xsi:type="dc:Point" x="541" y="170" />
|
||||
<di:waypoint xsi:type="dc:Point" x="541" y="119" />
|
||||
<di:waypoint xsi:type="dc:Point" x="564" y="119" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="538.0" y="218.0"/>
|
||||
<dc:Bounds x="496" y="165" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ScriptTask_2" bpmnElement="ScriptTask_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="555.0" y="282.0"/>
|
||||
<dc:Bounds x="555" y="229" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_6" sourceElement="_BPMNShape_ExclusiveGateway_19" targetElement="_BPMNShape_ScriptTask_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="480.0" y="248.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="480.0" y="322.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="555.0" y="322.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="480" y="195" />
|
||||
<di:waypoint xsi:type="dc:Point" x="480" y="269" />
|
||||
<di:waypoint xsi:type="dc:Point" x="555" y="269" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="478.0" y="322.0"/>
|
||||
<dc:Bounds x="391" y="662" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_60" bpmnElement="EndEvent_3">
|
||||
<dc:Bounds height="36.0" width="36.0" x="705.0" y="304.0"/>
|
||||
<dc:Bounds x="740" y="272" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="723.0" y="345.0"/>
|
||||
<dc:Bounds x="668" y="685" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_7" bpmnElement="SequenceFlow_7" sourceElement="_BPMNShape_ScriptTask_2" targetElement="_BPMNShape_EndEvent_60">
|
||||
<di:waypoint xsi:type="dc:Point" x="655.0" y="322.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="705.0" y="322.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="655" y="269" />
|
||||
<di:waypoint xsi:type="dc:Point" x="680" y="269" />
|
||||
<di:waypoint xsi:type="dc:Point" x="680" y="290" />
|
||||
<di:waypoint xsi:type="dc:Point" x="740" y="290" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="677.0" y="322.0"/>
|
||||
<dc:Bounds x="650" y="276.5" width="90" height="6" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="StartEvent_14sl8b4_di" bpmnElement="StartEvent_4">
|
||||
<dc:Bounds x="287" y="417" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="260" y="453" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1t8nq5v_di" bpmnElement="SequenceFlow_9">
|
||||
<di:waypoint xsi:type="dc:Point" x="323" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="376" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="376" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="407" y="435" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="346" y="425" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="EndEvent_1j9tw48_di" bpmnElement="EndEvent_5">
|
||||
<dc:Bounds x="883" y="417" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="856" y="453" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_10jatau_di" bpmnElement="SequenceFlow_8">
|
||||
<di:waypoint xsi:type="dc:Point" x="792" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="834" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="834" y="435" />
|
||||
<di:waypoint xsi:type="dc:Point" x="883" y="435" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="804" y="425" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="StartEvent_19uwuw1_di" bpmnElement="StartEvent_3">
|
||||
<dc:Bounds x="432" y="371" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="405" y="407" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_1y93al0_di" bpmnElement="Task_2">
|
||||
<dc:Bounds x="525" y="397" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_0gkhyqw_di" bpmnElement="SequenceFlow_10">
|
||||
<di:waypoint xsi:type="dc:Point" x="468" y="389" />
|
||||
<di:waypoint xsi:type="dc:Point" x="496" y="389" />
|
||||
<di:waypoint xsi:type="dc:Point" x="496" y="437" />
|
||||
<di:waypoint xsi:type="dc:Point" x="525" y="437" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="466" y="403" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="EndEvent_1bmhzoz_di" bpmnElement="EndEvent_4">
|
||||
<dc:Bounds x="683" y="419" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="656" y="455" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1s8bqj4_di" bpmnElement="SequenceFlow_11">
|
||||
<di:waypoint xsi:type="dc:Point" x="625" y="437" />
|
||||
<di:waypoint xsi:type="dc:Point" x="683" y="437" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="609" y="412" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="SubProcess_081736t_di" bpmnElement="SubProcess_3">
|
||||
<dc:Bounds x="363" y="652" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_17rfv1e_di" bpmnElement="StartEvent_5">
|
||||
<dc:Bounds x="573" y="674" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="546" y="710" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="AdHocSubProcess_0ojckgh_di" bpmnElement="SubProcess_4" isExpanded="false">
|
||||
<dc:Bounds x="541" y="652" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="AdHocSubProcess_128w1vu_di" bpmnElement="SubProcess_2" isExpanded="true">
|
||||
<dc:Bounds x="407" y="335" width="385" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="SubProcess_0qs6p1k_di" bpmnElement="SubProcess_5" isExpanded="false">
|
||||
<dc:Bounds x="716" y="652" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_0076vg5_di" bpmnElement="StartEvent_6">
|
||||
<dc:Bounds x="495" y="537" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="468" y="573" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="SubProcess_15na7ob_di" bpmnElement="SubProcess_6" isExpanded="true">
|
||||
<dc:Bounds x="398" y="796" width="385" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
|
@ -0,0 +1,653 @@
|
|||
'use strict';
|
||||
|
||||
require('../../../../TestHelper');
|
||||
|
||||
/* global bootstrapModeler, inject */
|
||||
|
||||
var modelingModule = require('../../../../../lib/features/modeling'),
|
||||
coreModule = require('../../../../../lib/core');
|
||||
|
||||
var is = require('../../../../../lib/util/ModelUtil').is;
|
||||
|
||||
var testModules = [
|
||||
modelingModule,
|
||||
coreModule
|
||||
];
|
||||
|
||||
describe('features/modeling - collapse and expand elements', function() {
|
||||
|
||||
var diagramXML = require('../../../../fixtures/bpmn/import/collapsed/processWithChildren.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, {
|
||||
modules: testModules
|
||||
}));
|
||||
|
||||
|
||||
describe('expand', function() {
|
||||
|
||||
var defaultSize = {
|
||||
width: 350,
|
||||
height: 200
|
||||
};
|
||||
|
||||
|
||||
it('collapsed-marker is removed',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_3');
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
var businessObject = expandedSubProcess.businessObject;
|
||||
|
||||
// then +-marker is removed
|
||||
expect(businessObject.di.isExpanded).to.eql(true);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('show all children, but hide empty labels',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_1');
|
||||
var originalChildren = collapsedSubProcess.children.slice();
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then keep children
|
||||
originalChildren.forEach(function(c) {
|
||||
expect(expandedSubProcess.children).to.include(c);
|
||||
});
|
||||
|
||||
// and show them
|
||||
expect(expandedSubProcess.children).to.satisfy(allShown());
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('keep ad-hoc and multiInstance-marker',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var collapsedAdHocSubProcess = elementRegistry.get('SubProcess_4');
|
||||
|
||||
// when
|
||||
var expandedAdHocSubProcess = bpmnReplace.replaceElement(collapsedAdHocSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
expect(is(expandedAdHocSubProcess, 'bpmn:AdHocSubProcess')).to.eql(true);
|
||||
var businessObject = expandedAdHocSubProcess.businessObject;
|
||||
expect(businessObject.loopCharacteristics).to.not.be.undefined;
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
describe('resizing', function() {
|
||||
|
||||
|
||||
it('ignors hidden children',
|
||||
inject(function(elementRegistry, bpmnReplace, eventBus) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_5');
|
||||
var hiddenStartEvent = elementRegistry.get('StartEvent_6');
|
||||
eventBus.once('commandStack.shape.toggleCollapse.postExecute', function(e) {
|
||||
hiddenStartEvent.hidden = true;
|
||||
});
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then hidden child should not be covered
|
||||
expect(expandedSubProcess.x).to.be.greaterThan(hiddenStartEvent.x);
|
||||
expect(expandedSubProcess.y).to.be.greaterThan(hiddenStartEvent.y);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('without children is centered and has defaultBounds',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given collapsed SubProcess without children
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_3');
|
||||
|
||||
var oldMid = {
|
||||
x: collapsedSubProcess.x + collapsedSubProcess.width / 2,
|
||||
y: collapsedSubProcess.y + collapsedSubProcess.height / 2
|
||||
};
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
var newMid = {
|
||||
x: expandedSubProcess.x + expandedSubProcess.width / 2,
|
||||
y: expandedSubProcess.y + expandedSubProcess.height / 2
|
||||
};
|
||||
|
||||
expect(newMid).to.eql(oldMid);
|
||||
expect(expandedSubProcess.width).to.be.at.least(defaultSize.width);
|
||||
expect(expandedSubProcess.height).to.be.at.least(defaultSize.height);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('with children is centered to childrenBoundingBox and has at least defaultBounds',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_4');
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
var startEvent = elementRegistry.get('StartEvent_5');
|
||||
var midChildren = {
|
||||
x: startEvent.x + startEvent.width / 2,
|
||||
y: startEvent.y + startEvent.height / 2
|
||||
};
|
||||
|
||||
var expandedMid = {
|
||||
x: expandedSubProcess.x + expandedSubProcess.width / 2,
|
||||
y: expandedSubProcess.y + expandedSubProcess.height / 2
|
||||
};
|
||||
|
||||
expect(expandedMid).to.eql(midChildren),
|
||||
expect(expandedSubProcess.width).to.be.at.least(defaultSize.width);
|
||||
expect(expandedSubProcess.height).to.be.at.least(defaultSize.height);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('to expanding collapsedSubProcess is coverd in childrenBoundingBox',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_5');
|
||||
var collapsedDownRightCorner = {
|
||||
x: collapsedSubProcess.x + collapsedSubProcess.width,
|
||||
y: collapsedSubProcess.y + collapsedSubProcess.height
|
||||
};
|
||||
|
||||
// when
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
var expandedDownRightCorner = {
|
||||
x: expandedSubProcess.x + expandedSubProcess.width,
|
||||
y: expandedSubProcess.y + expandedSubProcess.height
|
||||
};
|
||||
|
||||
expect(expandedDownRightCorner.x).to.be.at.least(collapsedDownRightCorner.x);
|
||||
expect(expandedDownRightCorner.y).to.be.at.least(collapsedDownRightCorner.y);
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('undo', function() {
|
||||
|
||||
|
||||
it('collapsed-marker is placed',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_1');
|
||||
var expandedSubProcess = bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
var businessObject = expandedSubProcess.businessObject;
|
||||
|
||||
// then +-marker is placed
|
||||
expect(businessObject.di.isExpanded).to.eql(false);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('restore previous bounds',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_1');
|
||||
var originalBounds = {
|
||||
x: collapsedSubProcess.x,
|
||||
y: collapsedSubProcess.y,
|
||||
width: collapsedSubProcess.width,
|
||||
height: collapsedSubProcess.height
|
||||
};
|
||||
|
||||
bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(collapsedSubProcess).to.have.bounds(originalBounds);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('hide children',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_1');
|
||||
var originalChildren = collapsedSubProcess.children.slice();
|
||||
|
||||
bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then keep children
|
||||
originalChildren.forEach(function(c) {
|
||||
expect(collapsedSubProcess.children).to.include(c);
|
||||
});
|
||||
// and hide them
|
||||
expect(collapsedSubProcess.children).to.satisfy(allHidden());
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('collapse', function() {
|
||||
|
||||
var defaultSize = {
|
||||
width: 100,
|
||||
height: 80
|
||||
};
|
||||
|
||||
|
||||
it('collapsed-marker is placed',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
|
||||
// when
|
||||
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
var businessObject = collapsedSubProcess.businessObject;
|
||||
|
||||
// then +-marker is set
|
||||
expect(businessObject.di.isExpanded).to.eql(false);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('hide all children',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
var originalChildren = expandedSubProcess.children.slice();
|
||||
|
||||
// when
|
||||
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// then keep children
|
||||
originalChildren.forEach(function(c) {
|
||||
expect(collapsedSubProcess.children).to.include(c);
|
||||
});
|
||||
|
||||
// and hide them
|
||||
expect(collapsedSubProcess.children).to.satisfy(allHidden());
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('keep ad-hoc and multiInstance-marker',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
|
||||
// when
|
||||
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
expect(is(collapsedSubProcess, 'bpmn:AdHocSubProcess')).to.eql(true);
|
||||
var businessObject = collapsedSubProcess.businessObject;
|
||||
expect(businessObject.loopCharacteristics).to.not.be.undefined;
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
describe('resize', function() {
|
||||
|
||||
|
||||
it('is centered and has default bounds',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
var oldMid = {
|
||||
x: expandedSubProcess.x + expandedSubProcess.width / 2,
|
||||
y: expandedSubProcess.y + expandedSubProcess.height / 2
|
||||
};
|
||||
|
||||
// when
|
||||
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
var newMid = {
|
||||
x: collapsedSubProcess.x + collapsedSubProcess.width / 2,
|
||||
y: collapsedSubProcess.y + collapsedSubProcess.height / 2
|
||||
};
|
||||
|
||||
expect(newMid).to.eql(oldMid);
|
||||
expect(collapsedSubProcess.width).to.be.at.least(defaultSize.width);
|
||||
expect(collapsedSubProcess.height).to.be.at.least(defaultSize.height);
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('undo', function() {
|
||||
|
||||
|
||||
it('collapsed marker is removed',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
var collapsedSubProcess = bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
var businessObject = collapsedSubProcess.businessObject;
|
||||
|
||||
// then +-marker is placed
|
||||
expect(businessObject.di.isExpanded).to.eql(true);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('originalBounds are restored',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
var originalBounds = {
|
||||
x: expandedSubProcess.x,
|
||||
y: expandedSubProcess.y,
|
||||
width: expandedSubProcess.width,
|
||||
height: expandedSubProcess.height
|
||||
};
|
||||
|
||||
bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(expandedSubProcess).to.have.bounds(originalBounds);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('show children that were visible',
|
||||
inject(function(elementRegistry, bpmnReplace, commandStack) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
var originalChildren = expandedSubProcess.children.slice();
|
||||
|
||||
bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then keep children
|
||||
originalChildren.forEach(function(c) {
|
||||
expect(expandedSubProcess.children).to.include(c);
|
||||
});
|
||||
|
||||
// and show the previously visible ones
|
||||
expect(expandedSubProcess.children).to.satisfy(allShown());
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('attaching marker', function() {
|
||||
|
||||
|
||||
describe('collapsed', function() {
|
||||
|
||||
|
||||
it('add ad-hoc-marker does not call toggleProvider',
|
||||
inject(function(eventBus, bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_3');
|
||||
|
||||
// should not be called
|
||||
eventBus.once('commandStack.shape.toggleCollapse.execute', function(e) {
|
||||
expect(true).to.eql(false);
|
||||
});
|
||||
|
||||
// when
|
||||
bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:AdHocSubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('remove ad-hoc-marker does not call toggleProvider',
|
||||
inject(function(eventBus, bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('SubProcess_4');
|
||||
|
||||
// should not be called
|
||||
eventBus.once('commandStack.shape.toggleCollapse.execute', function(e) {
|
||||
expect(true).to.eql(false);
|
||||
});
|
||||
|
||||
// when
|
||||
bpmnReplace.replaceElement(collapsedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('expanded', function() {
|
||||
|
||||
|
||||
it('add ad-hoc-marker does not call toggleProvider',
|
||||
inject(function(eventBus, bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_6');
|
||||
|
||||
// should not be called
|
||||
eventBus.once('commandStack.shape.toggleCollapse.execute', function(e) {
|
||||
expect(true).to.eql(false);
|
||||
});
|
||||
|
||||
// when
|
||||
bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:AdHocSubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('remove ad-hoc-marker does not call toggleProvider',
|
||||
inject(function(eventBus, bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var expandedSubProcess = elementRegistry.get('SubProcess_2');
|
||||
|
||||
// should not be called
|
||||
eventBus.once('commandStack.shape.toggleCollapse.execute', function(e) {
|
||||
expect(true).to.eql(false);
|
||||
});
|
||||
|
||||
// when
|
||||
bpmnReplace.replaceElement(expandedSubProcess,
|
||||
{
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
}
|
||||
);
|
||||
|
||||
// then
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////// helpers /////////////////////////////
|
||||
|
||||
|
||||
function allHidden() {
|
||||
return childrenHidden(true);
|
||||
}
|
||||
|
||||
function allShown() {
|
||||
return childrenHidden(false);
|
||||
}
|
||||
|
||||
function childrenHidden(hidden) {
|
||||
return function(children) {
|
||||
return children.every(function(child) {
|
||||
// empty labels are allways hidden
|
||||
if (child.type === 'label' && !child.businessObject.name) {
|
||||
return child.hidden;
|
||||
}
|
||||
else {
|
||||
return child.hidden == hidden;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="0.7.0-dev">
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:subProcess id="Task_1" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="SubProcess_0loe8m1_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="149" y="128" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -1086,6 +1086,30 @@ describe('features/popup-menu - replace menu provider', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('collapsed subprocesses', function() {
|
||||
|
||||
var diagramXML = require('./ReplaceMenuProvider.collapsedSubProcess.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
it('options do not include collapsed subprocesses itself', inject(function(elementRegistry, popupMenu) {
|
||||
|
||||
// given
|
||||
var collapsedSubProcess = elementRegistry.get('Task_1');
|
||||
|
||||
// when
|
||||
openPopup(collapsedSubProcess);
|
||||
|
||||
var collapsedSubProcessEntry = queryEntry(popupMenu, 'replace-with-collapsed-subprocess');
|
||||
|
||||
// then
|
||||
expect(collapsedSubProcessEntry).to.not.exist;
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -781,7 +781,7 @@ describe('features/replace - bpmn replace', function() {
|
|||
});
|
||||
|
||||
|
||||
describe('collapsed to expanded', function() {
|
||||
describe('morph task with boundaryEvent', function() {
|
||||
|
||||
var diagramXML = require('../../../fixtures/bpmn/features/replace/01_replace.bpmn');
|
||||
|
||||
|
@ -790,7 +790,7 @@ describe('features/replace - bpmn replace', function() {
|
|||
}));
|
||||
|
||||
|
||||
it('should morph task -> expanded sub process', inject(function(bpmnReplace, elementRegistry) {
|
||||
it('to expanded sub process', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var element = elementRegistry.get('Task_1');
|
||||
|
@ -805,63 +805,32 @@ describe('features/replace - bpmn replace', function() {
|
|||
// then
|
||||
expect(is(newElement, 'bpmn:SubProcess')).to.be.true;
|
||||
expect(isExpanded(newElement)).to.be.true;
|
||||
}));
|
||||
|
||||
|
||||
it('should expand sub-process', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var element = elementRegistry.get('SubProcessCollapsed');
|
||||
var newElementData = {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
};
|
||||
|
||||
// when
|
||||
var newElement = bpmnReplace.replaceElement(element, newElementData);
|
||||
|
||||
// then
|
||||
expect(is(newElement, 'bpmn:SubProcess')).to.be.true;
|
||||
expect(isExpanded(newElement)).to.be.true;
|
||||
}));
|
||||
|
||||
|
||||
it('should expand ad hoc sub-process', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var element = elementRegistry.get('AdHocSubProcessCollapsed');
|
||||
var newElementData = {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
};
|
||||
|
||||
// when
|
||||
var newElement = bpmnReplace.replaceElement(element, newElementData);
|
||||
|
||||
// then
|
||||
expect(is(newElement, 'bpmn:AdHocSubProcess')).to.be.true;
|
||||
expect(isExpanded(newElement)).to.be.true;
|
||||
}));
|
||||
|
||||
|
||||
it('should keep boundary events', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var element = elementRegistry.get('Task_1');
|
||||
var newElementData = {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
};
|
||||
|
||||
// when
|
||||
var newElement = bpmnReplace.replaceElement(element, newElementData);
|
||||
|
||||
// then
|
||||
expect(is(newElement, 'bpmn:SubProcess')).to.be.true;
|
||||
expect(isExpanded(newElement)).to.be.true;
|
||||
// and keep boundaryEvent
|
||||
expect(newElement.attachers.length).to.be.equal(2);
|
||||
}));
|
||||
|
||||
|
||||
it('to collapsed sub process', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var element = elementRegistry.get('Task_1');
|
||||
var newElementData = {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: false
|
||||
};
|
||||
|
||||
// when
|
||||
var newElement = bpmnReplace.replaceElement(element, newElementData);
|
||||
|
||||
// then
|
||||
expect(is(newElement, 'bpmn:SubProcess')).to.be.true;
|
||||
expect(isExpanded(newElement)).to.be.false;
|
||||
|
||||
// and keep boundaryEvent
|
||||
expect(newElement.attachers.length).to.eql(2);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_QfpVMDO5Eeav0IX5Z32OQQ" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||
<bpmn2:process id="Process_1" isExecutable="false">
|
||||
<bpmn2:subProcess id="SubProcess_1">
|
||||
<bpmn2:task id="Task_1">
|
||||
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="Task_1" targetRef="EndEvent_1"/>
|
||||
<bpmn2:endEvent id="EndEvent_1">
|
||||
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||
</bpmn2:endEvent>
|
||||
</bpmn2:subProcess>
|
||||
</bpmn2:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_2" bpmnElement="SubProcess_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="120.0" y="84.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_1">
|
||||
<dc:Bounds height="80.0" width="100.0" x="55.0" y="84.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="249.0" y="106.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="0.0" width="0.0" x="267.0" y="147.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_Task_2" targetElement="_BPMNShape_EndEvent_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="155.0" y="124.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="249.0" y="124.0"/>
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds height="6.0" width="6.0" x="177.0" y="124.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
Loading…
Reference in New Issue