From d640a3ce54fc30bdff70ccf5ee59ea6a54c1b890 Mon Sep 17 00:00:00 2001 From: Martin Stamm Date: Tue, 28 May 2024 13:41:50 +0200 Subject: [PATCH] feat(modeling): keep global elements when deleting last participant closes #1676 --- lib/features/modeling/Modeling.js | 2 + .../behavior/RemoveParticipantBehavior.js | 7 +- .../collaboration-data-store.bpmn | 23 +++++ .../behavior/RemoveParticipantBehaviorSpec.js | 98 ++++++++++++++++++- 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/bpmn/collaboration/collaboration-data-store.bpmn diff --git a/lib/features/modeling/Modeling.js b/lib/features/modeling/Modeling.js index b3dfd5e348..0bddbde438 100644 --- a/lib/features/modeling/Modeling.js +++ b/lib/features/modeling/Modeling.js @@ -246,6 +246,8 @@ Modeling.prototype.makeProcess = function() { }; this._commandStack.execute('canvas.updateRoot', context); + + return processElement; }; /** diff --git a/lib/features/modeling/behavior/RemoveParticipantBehavior.js b/lib/features/modeling/behavior/RemoveParticipantBehavior.js index ad23cf959c..605681bb90 100644 --- a/lib/features/modeling/behavior/RemoveParticipantBehavior.js +++ b/lib/features/modeling/behavior/RemoveParticipantBehavior.js @@ -44,7 +44,12 @@ export default function RemoveParticipantBehavior(eventBus, modeling) { if (collaborationRoot && !collaborationRoot.businessObject.participants.length) { // replace empty collaboration with process diagram - modeling.makeProcess(); + var process = modeling.makeProcess(); + + // move all root elements from collaboration to process + var children = collaborationRoot.children.slice(); + + modeling.moveElements(children, { x: 0, y: 0 }, process); } }, true); diff --git a/test/fixtures/bpmn/collaboration/collaboration-data-store.bpmn b/test/fixtures/bpmn/collaboration/collaboration-data-store.bpmn new file mode 100644 index 0000000000..9ac6e77f45 --- /dev/null +++ b/test/fixtures/bpmn/collaboration/collaboration-data-store.bpmn @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/features/modeling/behavior/RemoveParticipantBehaviorSpec.js b/test/spec/features/modeling/behavior/RemoveParticipantBehaviorSpec.js index 0d8cd5c4a0..bf9179fe88 100644 --- a/test/spec/features/modeling/behavior/RemoveParticipantBehaviorSpec.js +++ b/test/spec/features/modeling/behavior/RemoveParticipantBehaviorSpec.js @@ -47,7 +47,7 @@ describe('features/modeling - remove participant behavior', function() { describe('when removing last remaining participant', function() { - var processDiagramXML = require('../../../../fixtures/bpmn/collaboration/collaboration-empty-participant.bpmn'); + var processDiagramXML = require('../../../../fixtures/bpmn/collaboration/collaboration-data-store.bpmn'); beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules })); @@ -89,6 +89,9 @@ describe('features/modeling - remove participant behavior', function() { expect(getDi(newRootShape)).to.eql(diPlane); expect(bpmnDefinitions.rootElements).to.include(newRootBusinessObject); + + // data store is preserved + expect(newRootShape.children).to.have.length(1); })); @@ -126,4 +129,97 @@ describe('features/modeling - remove participant behavior', function() { }); + + describe('when removing all diagram content', function() { + + var processDiagramXML = require('../../../../fixtures/bpmn/collaboration/collaboration-data-store.bpmn'); + + beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules })); + + describe('should transform diagram into process diagram', function() { + + it('execute', inject(function(modeling, elementRegistry, canvas) { + + // given + var participantShape = elementRegistry.get('_Participant_2'), + participant = participantShape.businessObject, + participantDi = getDi(participantShape), + process = participant.processRef, + collaborationElement = participantShape.parent, + collaboration = collaborationElement.businessObject, + diPlane = getDi(collaborationElement), + bpmnDefinitions = collaboration.$parent; + + // when + var rootElement = canvas.getRootElement(); + + var elements = elementRegistry.filter(function(element) { + return element !== rootElement; + }); + + modeling.removeElements(elements); + + // then + expect(participant.$parent).not.to.be.ok; + + var newRootShape = canvas.getRootElement(), + newRootBusinessObject = newRootShape.businessObject; + + expect(newRootBusinessObject.$instanceOf('bpmn:Process')).to.be.true; + + // collaboration DI is unwired + expect(participantDi.$parent).not.to.be.ok; + expect(getDi(collaborationElement)).not.to.be.ok; + + expect(bpmnDefinitions.rootElements).not.to.include(process); + expect(bpmnDefinitions.rootElements).not.to.include(collaboration); + + // process DI is wired + expect(diPlane.bpmnElement).to.eql(newRootBusinessObject); + expect(getDi(newRootShape)).to.eql(diPlane); + + expect(bpmnDefinitions.rootElements).to.include(newRootBusinessObject); + })); + + + it('undo', inject(function(modeling, elementRegistry, canvas, commandStack) { + + // given + var participantShape = elementRegistry.get('_Participant_2'), + participant = participantShape.businessObject, + originalRootElement = participantShape.parent, + originalRootElementBo = originalRootElement.businessObject, + originalRootElementDi = getDi(originalRootElement), + bpmnDefinitions = originalRootElementBo.$parent, + participantDi = getDi(participantShape), + diPlane = participantDi.$parent; + + var rootElement = canvas.getRootElement(); + + var elements = elementRegistry.filter(function(element) { + return element !== rootElement; + }); + + modeling.removeElements(elements); + + // when + commandStack.undo(); + + // then + expect(participant.$parent).to.eql(originalRootElementBo); + expect(originalRootElementBo.$parent).to.eql(bpmnDefinitions); + + expect(canvas.getRootElement()).to.eql(originalRootElement); + + // di is unwired + expect(participantDi.$parent).to.eql(originalRootElementDi); + + // new di is wired + expect(diPlane.bpmnElement).to.eql(originalRootElementBo); + })); + + }); + + }); + }); \ No newline at end of file