feat(modeling): prevent expanded subprocess overlap of previous content
This covers two scenarios: 1. When a shape is replaced with an expanded subprocess 2. When a subprocess is toggled from collapsed to expanded Only when: 1. There are incoming sequence flows (previous content) 2. There are no outgoing sequence flows (following content)
This commit is contained in:
parent
62d7746e81
commit
05fea05834
|
@ -4,8 +4,8 @@ import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
|||
|
||||
import { is } from '../../../util/ModelUtil';
|
||||
|
||||
export default function EventBasedGatewayBehavior(eventBus, modeling) {
|
||||
|
||||
export default function EventBasedGatewayBehavior(eventBus, modeling) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,6 @@ export default function EventBasedGatewayBehavior(eventBus, modeling) {
|
|||
* from event-based gateway.
|
||||
*/
|
||||
this.preExecuted('connection.create', function(event) {
|
||||
|
||||
var source = event.context.source,
|
||||
target = event.context.target,
|
||||
existingIncomingConnections = target.incoming.slice();
|
||||
|
@ -36,7 +35,6 @@ export default function EventBasedGatewayBehavior(eventBus, modeling) {
|
|||
* source.
|
||||
*/
|
||||
this.preExecuted('shape.replace', function(event) {
|
||||
|
||||
var newShape = event.context.newShape,
|
||||
newShapeTargets,
|
||||
newShapeTargetsIncomingSequenceFlows;
|
||||
|
@ -72,8 +70,7 @@ EventBasedGatewayBehavior.$inject = [
|
|||
inherits(EventBasedGatewayBehavior, CommandInterceptor);
|
||||
|
||||
|
||||
|
||||
// helpers //////////////////////
|
||||
// helpers //////////
|
||||
|
||||
function isSequenceFlow(connection) {
|
||||
return is(connection, 'bpmn:SequenceFlow');
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
import inherits from 'inherits';
|
||||
|
||||
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
||||
|
||||
import { is } from '../../../util/ModelUtil';
|
||||
|
||||
import { expandedBounds } from './ToggleElementCollapseBehaviour';
|
||||
|
||||
|
||||
export default function SubProcessBehavior(elementFactory, eventBus, modeling) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
/**
|
||||
* Adjust position of sub process after it replaces a shape with incoming
|
||||
* sequence flows and no outgoing sequence flows to prevent overlap.
|
||||
*/
|
||||
this.postExecuted('shape.replace', function(event) {
|
||||
var oldShape = event.context.oldShape,
|
||||
newShape = event.context.newShape;
|
||||
|
||||
if (!is(newShape, 'bpmn:SubProcess') ||
|
||||
!hasIncomingSequenceFlows(newShape) ||
|
||||
hasOutgoingSequenceFlows(newShape)) {
|
||||
return;
|
||||
}
|
||||
|
||||
modeling.moveShape(newShape, {
|
||||
x: oldShape.x - newShape.x,
|
||||
y: 0
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Adjust position of sub process with incoming sequence flows and no outgoing
|
||||
* sequence flows after toggling to prevent overlap.
|
||||
*/
|
||||
this.postExecuted('shape.toggleCollapse', function(event) {
|
||||
var context = event.context,
|
||||
shape = context.shape,
|
||||
defaultSize = elementFactory._getDefaultSize(shape),
|
||||
newBounds;
|
||||
|
||||
if (!is(shape, 'bpmn:SubProcess') ||
|
||||
shape.collapsed ||
|
||||
!hasIncomingSequenceFlows(shape) ||
|
||||
hasOutgoingSequenceFlows(shape)) {
|
||||
return;
|
||||
}
|
||||
|
||||
newBounds = expandedBounds(shape, defaultSize);
|
||||
|
||||
modeling.moveShape(shape, {
|
||||
x: shape.x - newBounds.x,
|
||||
y: 0
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
SubProcessBehavior.$inject = [
|
||||
'elementFactory',
|
||||
'eventBus',
|
||||
'modeling'
|
||||
];
|
||||
|
||||
inherits(SubProcessBehavior, CommandInterceptor);
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function hasIncomingSequenceFlows(shape) {
|
||||
shape = shape || {};
|
||||
|
||||
if (shape.incoming && shape.incoming.length) {
|
||||
return shape.incoming.some(isSequenceFlow);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasOutgoingSequenceFlows(shape) {
|
||||
shape = shape || {};
|
||||
|
||||
if (shape.outgoing && shape.outgoing.length) {
|
||||
return shape.outgoing.some(isSequenceFlow);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isSequenceFlow(connection) {
|
||||
return is(connection, 'bpmn:SequenceFlow');
|
||||
}
|
|
@ -15,13 +15,9 @@ import {
|
|||
var LOW_PRIORITY = 500;
|
||||
|
||||
|
||||
export default function ToggleElementCollapseBehaviour(
|
||||
eventBus, elementFactory, modeling,
|
||||
resize) {
|
||||
|
||||
export default function ToggleElementCollapseBehaviour(elementFactory, eventBus, modeling) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
|
||||
function hideEmptyLables(children) {
|
||||
if (children.length) {
|
||||
children.forEach(function(child) {
|
||||
|
@ -32,42 +28,6 @@ export default function ToggleElementCollapseBehaviour(
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -130,13 +90,49 @@ export default function ToggleElementCollapseBehaviour(
|
|||
inherits(ToggleElementCollapseBehaviour, CommandInterceptor);
|
||||
|
||||
ToggleElementCollapseBehaviour.$inject = [
|
||||
'eventBus',
|
||||
'elementFactory',
|
||||
'eventBus',
|
||||
'modeling'
|
||||
];
|
||||
|
||||
// helpers //////////
|
||||
|
||||
// helpers //////////////////////
|
||||
export 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;
|
||||
}
|
||||
|
||||
export 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
|
||||
};
|
||||
}
|
||||
|
||||
function filterVisible(elements) {
|
||||
return elements.filter(function(e) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import RemoveParticipantBehavior from './RemoveParticipantBehavior';
|
|||
import ReplaceElementBehaviour from './ReplaceElementBehaviour';
|
||||
import ResizeLaneBehavior from './ResizeLaneBehavior';
|
||||
import RemoveElementBehavior from './RemoveElementBehavior';
|
||||
import SubProcessBehavior from './SubProcessBehavior';
|
||||
import ToggleElementCollapseBehaviour from './ToggleElementCollapseBehaviour';
|
||||
import UnclaimIdBehavior from './UnclaimIdBehavior';
|
||||
import UpdateFlowNodeRefsBehavior from './UpdateFlowNodeRefsBehavior';
|
||||
|
@ -48,6 +49,7 @@ export default {
|
|||
'replaceElementBehaviour',
|
||||
'resizeLaneBehavior',
|
||||
'toggleElementCollapseBehaviour',
|
||||
'subProcessBehavior',
|
||||
'unclaimIdBehavior',
|
||||
'unsetDefaultFlowBehavior',
|
||||
'updateFlowNodeRefsBehavior'
|
||||
|
@ -74,6 +76,7 @@ export default {
|
|||
resizeLaneBehavior: [ 'type', ResizeLaneBehavior ],
|
||||
removeElementBehavior: [ 'type', RemoveElementBehavior ],
|
||||
toggleElementCollapseBehaviour : [ 'type', ToggleElementCollapseBehaviour ],
|
||||
subProcessBehavior: [ 'type', SubProcessBehavior ],
|
||||
unclaimIdBehavior: [ 'type', UnclaimIdBehavior ],
|
||||
updateFlowNodeRefsBehavior: [ 'type', UpdateFlowNodeRefsBehavior ],
|
||||
unsetDefaultFlowBehavior: [ 'type', UnsetDefaultFlowBehavior ]
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
<?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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.1.0">
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>SequenceFlow_1</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1" sourceRef="StartEvent_1" targetRef="Task_1" />
|
||||
<bpmn:startEvent id="StartEvent_2">
|
||||
<bpmn:outgoing>SequenceFlow_2</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_2" sourceRef="StartEvent_2" targetRef="SubProcess_1" />
|
||||
<bpmn:subProcess id="SubProcess_1">
|
||||
<bpmn:incoming>SequenceFlow_2</bpmn:incoming>
|
||||
</bpmn:subProcess>
|
||||
<bpmn:startEvent id="StartEvent_3">
|
||||
<bpmn:outgoing>SequenceFlow_3</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:task id="Task_3">
|
||||
<bpmn:incoming>SequenceFlow_3</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_4</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_3" sourceRef="StartEvent_3" targetRef="Task_3" />
|
||||
<bpmn:endEvent id="EndEvent_1">
|
||||
<bpmn:incoming>SequenceFlow_4</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_4" sourceRef="Task_3" targetRef="EndEvent_1" />
|
||||
<bpmn:startEvent id="StartEvent_4">
|
||||
<bpmn:outgoing>SequenceFlow_5</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_5" sourceRef="StartEvent_4" targetRef="SubProcess_3" />
|
||||
<bpmn:subProcess id="SubProcess_3">
|
||||
<bpmn:incoming>SequenceFlow_5</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_6</bpmn:outgoing>
|
||||
</bpmn:subProcess>
|
||||
<bpmn:endEvent id="EndEvent_2">
|
||||
<bpmn:incoming>SequenceFlow_6</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_6" sourceRef="SubProcess_3" targetRef="EndEvent_2" />
|
||||
<bpmn:task id="Task_1">
|
||||
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
|
||||
</bpmn:task>
|
||||
<bpmn:task id="Task_2" />
|
||||
<bpmn:subProcess id="SubProcess_2" />
|
||||
<bpmn:startEvent id="StartEvent_5">
|
||||
<bpmn:outgoing>SequenceFlow_7</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:subProcess id="SubProcess_4">
|
||||
<bpmn:incoming>SequenceFlow_7</bpmn:incoming>
|
||||
</bpmn:subProcess>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_7" sourceRef="StartEvent_5" targetRef="SubProcess_4" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="StartEvent_0clu1xt_di" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="-18" y="-18" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1sitg9h_di" bpmnElement="SequenceFlow_1">
|
||||
<di:waypoint x="18" y="0" />
|
||||
<di:waypoint x="50" y="0" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="StartEvent_1jvrle8_di" bpmnElement="StartEvent_2">
|
||||
<dc:Bounds x="-18" y="182" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_059hdit_di" bpmnElement="SequenceFlow_2">
|
||||
<di:waypoint x="18" y="200" />
|
||||
<di:waypoint x="50" y="200" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="SubProcess_07paci4_di" bpmnElement="SubProcess_1" isExpanded="false">
|
||||
<dc:Bounds x="50" y="160" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_1tbkscg_di" bpmnElement="StartEvent_3">
|
||||
<dc:Bounds x="-18" y="382" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_0y95x1n_di" bpmnElement="Task_3">
|
||||
<dc:Bounds x="50" y="360" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_073fv22_di" bpmnElement="SequenceFlow_3">
|
||||
<di:waypoint x="18" y="400" />
|
||||
<di:waypoint x="50" y="400" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="EndEvent_1meaw0v_di" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds x="182" y="382" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_16gom91_di" bpmnElement="SequenceFlow_4">
|
||||
<di:waypoint x="150" y="400" />
|
||||
<di:waypoint x="182" y="400" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="StartEvent_1pdfdjj_di" bpmnElement="StartEvent_4">
|
||||
<dc:Bounds x="-18" y="582" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_0d47csb_di" bpmnElement="SequenceFlow_5">
|
||||
<di:waypoint x="18" y="600" />
|
||||
<di:waypoint x="50" y="600" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="SubProcess_0457ogb_di" bpmnElement="SubProcess_3">
|
||||
<dc:Bounds x="50" y="560" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="EndEvent_1mik03m_di" bpmnElement="EndEvent_2">
|
||||
<dc:Bounds x="182" y="582" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1mdz5dl_di" bpmnElement="SequenceFlow_6">
|
||||
<di:waypoint x="150" y="600" />
|
||||
<di:waypoint x="182" y="600" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="50" y="-40" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_2_di" bpmnElement="Task_2">
|
||||
<dc:Bounds x="350" y="-40" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="SubProcess_2_di" bpmnElement="SubProcess_2" isExpanded="false">
|
||||
<dc:Bounds x="350" y="160" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_4_di" bpmnElement="StartEvent_5">
|
||||
<dc:Bounds x="382" y="382" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="SubProcess_3_di" bpmnElement="SubProcess_4" isExpanded="true">
|
||||
<dc:Bounds x="525" y="300" width="350" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_5_di" bpmnElement="SequenceFlow_7">
|
||||
<di:waypoint x="418" y="400" />
|
||||
<di:waypoint x="525" y="400" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -0,0 +1,212 @@
|
|||
/* global sinon */
|
||||
|
||||
import {
|
||||
bootstrapModeler,
|
||||
inject
|
||||
} from 'test/TestHelper';
|
||||
|
||||
import coreModule from 'lib/core';
|
||||
import modelingModule from 'lib/features/modeling';
|
||||
import replaceModule from 'lib/features/replace';
|
||||
import { getMid } from 'diagram-js/lib/layout/LayoutUtil';
|
||||
|
||||
|
||||
describe('features/modeling/behavior - sub process', function() {
|
||||
|
||||
var diagramXML = require('./SubProcessBehavior.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, {
|
||||
modules: [
|
||||
coreModule,
|
||||
modelingModule,
|
||||
replaceModule
|
||||
]
|
||||
}));
|
||||
|
||||
afterEach(sinon.restore);
|
||||
|
||||
|
||||
describe('replace', function() {
|
||||
|
||||
describe('task -> expanded subprocess', function() {
|
||||
|
||||
describe('incoming sequence flows', function() {
|
||||
|
||||
it('should move', inject(function(bpmnReplace, elementRegistry) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('Task_1');
|
||||
|
||||
// when
|
||||
var subProcess = bpmnReplace.replaceElement(shape, {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
});
|
||||
|
||||
// then
|
||||
var expectedBounds = {
|
||||
x: 50,
|
||||
y: -100,
|
||||
width: 350,
|
||||
height: 200
|
||||
};
|
||||
|
||||
expect(subProcess).to.have.bounds(expectedBounds);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('no incoming sequence flows', function() {
|
||||
|
||||
it('should NOT move', inject(function(bpmnReplace, elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_2'),
|
||||
taskMid = getMid(task);
|
||||
|
||||
// when
|
||||
var subProcess = bpmnReplace.replaceElement(task, {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
});
|
||||
|
||||
// then
|
||||
expect(getMid(subProcess)).to.eql(taskMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('outgoing sequence flows', function() {
|
||||
|
||||
it('should NOT move', inject(function(bpmnReplace, elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_3'),
|
||||
taskMid = getMid(task);
|
||||
|
||||
// when
|
||||
var subProcess = bpmnReplace.replaceElement(task, {
|
||||
type: 'bpmn:SubProcess',
|
||||
isExpanded: true
|
||||
});
|
||||
|
||||
// then
|
||||
expect(getMid(subProcess)).to.eql(taskMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('task -> non-subprocess', function() {
|
||||
|
||||
it('should NOT move', inject(function(bpmnReplace, elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_1'),
|
||||
taskMid = getMid(task);
|
||||
|
||||
|
||||
// when
|
||||
var callActivity = bpmnReplace.replaceElement(task, {
|
||||
type: 'bpmn:CallActivity'
|
||||
});
|
||||
|
||||
// then
|
||||
expect(getMid(callActivity)).to.eql(taskMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('toggle', function() {
|
||||
|
||||
describe('collapsed subprocess -> expanded subprocess', function() {
|
||||
|
||||
describe('incoming sequence flows', function() {
|
||||
|
||||
it('should move', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_1');
|
||||
|
||||
// when
|
||||
modeling.toggleCollapse(subProcess);
|
||||
|
||||
// then
|
||||
var expectedBounds = {
|
||||
x: 50,
|
||||
y: 100,
|
||||
width: 350,
|
||||
height: 200
|
||||
};
|
||||
|
||||
expect(subProcess).to.have.bounds(expectedBounds);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('no incoming sequence flows', function() {
|
||||
|
||||
it('should NOT move', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_2'),
|
||||
subProcessMid = getMid(subProcess);
|
||||
|
||||
// when
|
||||
modeling.toggleCollapse(subProcess);
|
||||
|
||||
// then
|
||||
expect(getMid(subProcess)).to.eql(subProcessMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('outgoing sequence flows', function() {
|
||||
|
||||
it('should NOT move', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_3'),
|
||||
subProcessMid = getMid(subProcess);
|
||||
|
||||
// when
|
||||
modeling.toggleCollapse(subProcess);
|
||||
|
||||
// then
|
||||
expect(getMid(subProcess)).to.eql(subProcessMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('expanded sub process -> collapsed sub process', function() {
|
||||
|
||||
it('should NOT move', inject(function(elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var subProcess = elementRegistry.get('SubProcess_4'),
|
||||
subProcessMid = getMid(subProcess);
|
||||
|
||||
// when
|
||||
modeling.toggleCollapse(subProcess);
|
||||
|
||||
// then
|
||||
expect(getMid(subProcess)).to.eql(subProcessMid);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue