From cf6ea589eb7eb0ff9c8f7d6fd3a62418153c1d53 Mon Sep 17 00:00:00 2001 From: Daniel <150448993+sombrek@users.noreply.github.com> Date: Sun, 21 Jan 2024 10:47:57 +0100 Subject: [PATCH 1/3] feat: delete vertical lanes --- .../modeling/behavior/DeleteLaneBehavior.js | 64 ++++++++-- .../features/modeling/lanes/DeleteLaneSpec.js | 112 ++++++++++++++++++ .../modeling/lanes/lanes.vertical.bpmn | 93 +++++++++++++++ 3 files changed, 260 insertions(+), 9 deletions(-) create mode 100644 test/spec/features/modeling/lanes/lanes.vertical.bpmn diff --git a/lib/features/modeling/behavior/DeleteLaneBehavior.js b/lib/features/modeling/behavior/DeleteLaneBehavior.js index f70c6d2f96..c79a6b1a24 100644 --- a/lib/features/modeling/behavior/DeleteLaneBehavior.js +++ b/lib/features/modeling/behavior/DeleteLaneBehavior.js @@ -8,6 +8,10 @@ import { getChildLanes } from '../util/LaneUtil'; +import { + isHorizontal +} from '../../../util/DiUtil'; + import { eachElement } from 'diagram-js/lib/util/Elements'; @@ -31,19 +35,29 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) { CommandInterceptor.call(this, eventBus); - function compensateLaneDelete(shape, oldParent) { + function compensateLaneDelete(shape, oldParent, isHorizontalLane) { 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; @@ -55,14 +69,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( @@ -83,6 +107,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'); + } } @@ -106,7 +150,9 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) { return; } - compensateLaneDelete(shape, oldParent); + var isHorizontalLane = isHorizontal(shape); + + compensateLaneDelete(shape, oldParent, isHorizontalLane); }); } diff --git a/test/spec/features/modeling/lanes/DeleteLaneSpec.js b/test/spec/features/modeling/lanes/DeleteLaneSpec.js index 43a5863c58..c6c14a4aaa 100644 --- a/test/spec/features/modeling/lanes/DeleteLaneSpec.js +++ b/test/spec/features/modeling/lanes/DeleteLaneSpec.js @@ -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) { diff --git a/test/spec/features/modeling/lanes/lanes.vertical.bpmn b/test/spec/features/modeling/lanes/lanes.vertical.bpmn new file mode 100644 index 0000000000..4a7d2b87f7 --- /dev/null +++ b/test/spec/features/modeling/lanes/lanes.vertical.bpmn @@ -0,0 +1,93 @@ + + + + + + + + + + V_Task + V_Task_Boundary + V_Boundary + + + + + V_Task + V_Task_Boundary + V_Boundary + + + + + + Flow_V + Flow_From_V_Boundary + + + Flow_V + + + Flow_From_V_Boundary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ee20c484ac0b495372df32ed9d36ff272c70a494 Mon Sep 17 00:00:00 2001 From: Maciej Barelkowski Date: Mon, 22 Jan 2024 13:01:50 +0100 Subject: [PATCH 2/3] test: fix bounds values --- test/spec/features/modeling/lanes/lanes.vertical.bpmn | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/spec/features/modeling/lanes/lanes.vertical.bpmn b/test/spec/features/modeling/lanes/lanes.vertical.bpmn index 4a7d2b87f7..81295c8262 100644 --- a/test/spec/features/modeling/lanes/lanes.vertical.bpmn +++ b/test/spec/features/modeling/lanes/lanes.vertical.bpmn @@ -37,11 +37,11 @@ - + - + @@ -49,7 +49,7 @@ - + @@ -57,7 +57,7 @@ - + From d306dcde8b9b125880438ade214bc8594a12b97e Mon Sep 17 00:00:00 2001 From: Maciej Barelkowski Date: Mon, 22 Jan 2024 13:02:13 +0100 Subject: [PATCH 3/3] chore: improve code style --- lib/features/modeling/behavior/DeleteLaneBehavior.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/features/modeling/behavior/DeleteLaneBehavior.js b/lib/features/modeling/behavior/DeleteLaneBehavior.js index c79a6b1a24..96b6cc01c2 100644 --- a/lib/features/modeling/behavior/DeleteLaneBehavior.js +++ b/lib/features/modeling/behavior/DeleteLaneBehavior.js @@ -35,7 +35,8 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) { CommandInterceptor.call(this, eventBus); - function compensateLaneDelete(shape, oldParent, isHorizontalLane) { + function compensateLaneDelete(shape, oldParent) { + var isHorizontalLane = isHorizontal(shape); var siblings = getChildLanes(oldParent); @@ -150,9 +151,7 @@ export default function DeleteLaneBehavior(eventBus, spaceTool) { return; } - var isHorizontalLane = isHorizontal(shape); - - compensateLaneDelete(shape, oldParent, isHorizontalLane); + compensateLaneDelete(shape, oldParent); }); }