Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete Vertical Lanes #2082

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions lib/features/modeling/behavior/DeleteLaneBehavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
getChildLanes
} from '../util/LaneUtil';

import {
isHorizontal
} from '../../../util/DiUtil';

import {
eachElement
} from 'diagram-js/lib/util/Elements';
Expand All @@ -32,18 +36,29 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) {


function compensateLaneDelete(shape, oldParent) {
var isHorizontalLane = isHorizontal(shape);

var siblings = getChildLanes(oldParent);

var topAffected = [];
var bottomAffected = [];
var leftAffected = [];
var rightAffected = [];

eachElement(siblings, function(element) {

if (element.y > shape.y) {
bottomAffected.push(element);
if (isHorizontalLane) {
if (element.y > shape.y) {
bottomAffected.push(element);
} else {
topAffected.push(element);
}
} else {
topAffected.push(element);
if (element.x > shape.x) {
rightAffected.push(element);
} else {
leftAffected.push(element);
}
}

return element.children;
Expand All @@ -55,14 +70,24 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) {

var offset;

if (bottomAffected.length && topAffected.length) {
offset = shape.height / 2;
if (isHorizontalLane) {
if (bottomAffected.length && topAffected.length) {
offset = shape.height / 2;
} else {
offset = shape.height;
}
} else {
offset = shape.height;
if (rightAffected.length && leftAffected.length) {
offset = shape.width / 2;
} else {
offset = shape.width;
}
}

var topAdjustments,
bottomAdjustments;
bottomAdjustments,
leftAdjustments,
rightAdjustments;

if (topAffected.length) {
topAdjustments = spaceTool.calculateAdjustments(
Expand All @@ -83,6 +108,26 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) {
bottomAdjustments.resizingShapes,
{ x: 0, y: -offset }, 'n');
}

if (leftAffected.length) {
leftAdjustments = spaceTool.calculateAdjustments(
leftAffected, 'x', offset, shape.x - 10);

spaceTool.makeSpace(
leftAdjustments.movingShapes,
leftAdjustments.resizingShapes,
{ x: offset, y: 0 }, 'e');
}

if (rightAffected.length) {
rightAdjustments = spaceTool.calculateAdjustments(
rightAffected, 'x', -offset, shape.x + shape.width + 10);

spaceTool.makeSpace(
rightAdjustments.movingShapes,
rightAdjustments.resizingShapes,
{ x: -offset, y: 0 }, 'w');
}
}


Expand Down
112 changes: 112 additions & 0 deletions test/spec/features/modeling/lanes/DeleteLaneSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,118 @@ describe('features/modeling - delete lane', function() {
});


describe('features/modeling - delete vertical lane', function() {

var diagramXML = require('./lanes.vertical.bpmn');

var testModules = [ coreModule, modelingModule ];

beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));


it('should remove first Lane', inject(function(elementRegistry, modeling) {

// given
var laneShape = elementRegistry.get('Vertical_Lane_A'),
rightSideLaneShape = elementRegistry.get('Vertical_Lane_B'),
rightSideLaneBounds = getBounds(rightSideLaneShape);

// when
modeling.removeShape(laneShape);

// then
expect(rightSideLaneShape).to.have.bounds({
x: rightSideLaneBounds.x - laneShape.width,
y: rightSideLaneBounds.y,
width: rightSideLaneBounds.width + laneShape.width,
height: rightSideLaneBounds.height
});

}));


it('should remove last Lane', inject(function(elementRegistry, modeling) {

// given
var laneShape = elementRegistry.get('Vertical_Lane_B'),
leftSideLaneShape = elementRegistry.get('Vertical_Lane_A'),
leftSideLaneBounds = getBounds(leftSideLaneShape);

// when
modeling.removeShape(laneShape);

// then
expect(leftSideLaneShape).to.have.bounds({
x: leftSideLaneBounds.x,
y: leftSideLaneBounds.y,
width: leftSideLaneBounds.width + laneShape.width,
height: leftSideLaneBounds.height
});

}));


describe('three lanes', function() {

it('should remove middle Lane', inject(function(elementRegistry, modeling) {

// given
var laneShape = elementRegistry.get('Nested_Vertical_Lane_B'),
leftSideLaneShape = elementRegistry.get('Nested_Vertical_Lane_A'),
leftSideLaneBounds = getBounds(leftSideLaneShape),
rightSideLaneShape = elementRegistry.get('Nested_Vertical_Lane_C'),
rightSideLaneBounds = getBounds(rightSideLaneShape);

// when
modeling.removeShape(laneShape);

// then
expect(leftSideLaneShape).to.have.bounds({
x: leftSideLaneBounds.x,
y: leftSideLaneBounds.y,
width: leftSideLaneBounds.width + laneShape.width / 2,
height: leftSideLaneBounds.height
});

expect(rightSideLaneShape).to.have.bounds({
x: rightSideLaneBounds.x - laneShape.width / 2,
y: rightSideLaneBounds.y,
width: rightSideLaneBounds.width + laneShape.width / 2,
height: rightSideLaneBounds.height
});

}));


it('should remove first Lane', inject(function(elementRegistry, modeling) {

// given
var laneShape = elementRegistry.get('Nested_Vertical_Lane_A'),
rightSideLaneShape = elementRegistry.get('Nested_Vertical_Lane_B'),
rightSideLaneBounds = getBounds(rightSideLaneShape),
lastLaneShape = elementRegistry.get('Nested_Vertical_Lane_C'),
lastLaneBounds = getBounds(lastLaneShape);

// when
modeling.removeShape(laneShape);

// then
expect(rightSideLaneShape).to.have.bounds({
x: rightSideLaneBounds.x - laneShape.width,
y: rightSideLaneBounds.y,
width: rightSideLaneBounds.width + laneShape.width,
height: rightSideLaneBounds.height
});

expect(lastLaneShape).to.have.bounds(lastLaneBounds);

}));

});

});


// helpers ///////////////

function getBounds(element) {
Expand Down
93 changes: 93 additions & 0 deletions test/spec/features/modeling/lanes/lanes.vertical.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?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="_4bAZoD9WEeWLcNBL4nCk1A" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://camunda.org/schema/1.0/bpmn">
<bpmn2:collaboration id="_Collaboration_2">
<bpmn2:participant id="Vertical_Participant_Lane" name="Vertical_Participant_Lane" processRef="Process_Vertical_Lane" />
</bpmn2:collaboration>
<bpmn2:process id="Process_Vertical_Lane" isExecutable="false">
<bpmn2:laneSet id="LaneSet_1o2qvt0" name="Lane Set 1">
<bpmn2:lane id="Vertical_Lane_B" name="Vertical_Lane_B" />
<bpmn2:lane id="Vertical_Lane_A" name="Vertical_Lane_A">
<bpmn2:flowNodeRef>V_Task</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>V_Task_Boundary</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>V_Boundary</bpmn2:flowNodeRef>
<bpmn2:childLaneSet id="LaneSet_1nz9a4u">
<bpmn2:lane id="Nested_Vertical_Lane_C" name="Nested_Vertical_Lane_C" />
<bpmn2:lane id="Nested_Vertical_Lane_B" name="Nested_Vertical_Lane_B" />
<bpmn2:lane id="Nested_Vertical_Lane_A" name="Nested_Vertical_Lane_A">
<bpmn2:flowNodeRef>V_Task</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>V_Task_Boundary</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>V_Boundary</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:childLaneSet>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:task id="V_Task" name="V_Task">
<bpmn2:incoming>Flow_V</bpmn2:incoming>
<bpmn2:incoming>Flow_From_V_Boundary</bpmn2:incoming>
</bpmn2:task>
<bpmn2:task id="V_Task_Boundary" name="V_Task_Boundary">
<bpmn2:outgoing>Flow_V</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:boundaryEvent id="V_Boundary" name="V_Boundary" attachedToRef="V_Task_Boundary">
<bpmn2:outgoing>Flow_From_V_Boundary</bpmn2:outgoing>
</bpmn2:boundaryEvent>
<bpmn2:sequenceFlow id="Flow_V" name="" sourceRef="V_Task_Boundary" targetRef="V_Task" />
<bpmn2:sequenceFlow id="Flow_From_V_Boundary" name="" sourceRef="V_Boundary" targetRef="V_Task" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
<bpmndi:BPMNShape id="BPMNShape_140jwaa" bpmnElement="Vertical_Participant_Lane" isHorizontal="false">
<dc:Bounds x="160" y="50" width="604" height="540" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0n0ckvg" bpmnElement="Vertical_Lane_B" isHorizontal="false">
<dc:Bounds x="656" y="80" width="108" height="510" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_1xhgbhc" bpmnElement="Vertical_Lane_A" isHorizontal="false">
<dc:Bounds x="160" y="80" width="496" height="510" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_1vq767a" bpmnElement="Nested_Vertical_Lane_C" isHorizontal="false">
<dc:Bounds x="503" y="110" width="153" height="480" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0zxz1a9" bpmnElement="Nested_Vertical_Lane_B" isHorizontal="false">
<dc:Bounds x="350" y="110" width="153" height="480" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_1dq00p8" bpmnElement="Nested_Vertical_Lane_A" isHorizontal="false">
<dc:Bounds x="160" y="110" width="190" height="480" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0t1n94f" bpmnElement="V_Task">
<dc:Bounds x="190" y="330" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0d8jcff" bpmnElement="V_Task_Boundary">
<dc:Bounds x="190" y="170" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0ft8wdi" bpmnElement="V_Boundary">
<dc:Bounds x="272" y="212" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="259" y="253" width="62" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_0tb53a9" bpmnElement="Flow_V">
<di:waypoint x="240" y="250" />
<di:waypoint x="240" y="330" />
<bpmndi:BPMNLabel>
<dc:Bounds x="403" y="103" width="6" height="6" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_0yevmra" bpmnElement="Flow_From_V_Boundary">
<di:waypoint x="308" y="230" />
<di:waypoint x="320" y="230" />
<di:waypoint x="320" y="370" />
<di:waypoint x="290" y="370" />
<bpmndi:BPMNLabel>
<dc:Bounds x="377" y="188" width="6" height="6" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>