From 5eff166135efb543b25e138d2d40c8df6e0783ac Mon Sep 17 00:00:00 2001 From: Alexis Zeghers <42282939+AZeghers@users.noreply.github.com> Date: Wed, 9 Dec 2020 14:56:12 +0100 Subject: [PATCH] feat(replace): add multiplicity marker to replace menu for participants Closes #533 --- lib/draw/BpmnRenderer.js | 2 +- .../popup-menu/ReplaceMenuProvider.js | 50 +++++++- .../bpmn/features/replace/participants.bpmn | 14 +++ .../popup-menu/ReplaceMenuProviderSpec.js | 107 +++++++++++++++++- 4 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/bpmn/features/replace/participants.bpmn diff --git a/lib/draw/BpmnRenderer.js b/lib/draw/BpmnRenderer.js index 6bb7a383..e97bfc39 100644 --- a/lib/draw/BpmnRenderer.js +++ b/lib/draw/BpmnRenderer.js @@ -1648,7 +1648,7 @@ export default function BpmnRenderer( }); drawMarker('participant-multiplicity', parentGfx, markerPath, { - strokeWidth: 1, + strokeWidth: 2, fill: getFillColor(element, defaultFillColor), stroke: getStrokeColor(element, defaultStrokeColor) }); diff --git a/lib/features/popup-menu/ReplaceMenuProvider.js b/lib/features/popup-menu/ReplaceMenuProvider.js index caa9e7c2..d2b1887b 100644 --- a/lib/features/popup-menu/ReplaceMenuProvider.js +++ b/lib/features/popup-menu/ReplaceMenuProvider.js @@ -24,9 +24,10 @@ import * as replaceOptions from '../replace/ReplaceOptions'; * This module is an element agnostic replace menu provider for the popup menu. */ export default function ReplaceMenuProvider( - popupMenu, modeling, moddle, + bpmnFactory, popupMenu, modeling, moddle, bpmnReplace, rules, translate) { + this._bpmnFactory = bpmnFactory; this._popupMenu = popupMenu; this._modeling = modeling; this._moddle = moddle; @@ -38,6 +39,7 @@ export default function ReplaceMenuProvider( } ReplaceMenuProvider.$inject = [ + 'bpmnFactory', 'popupMenu', 'modeling', 'moddle', @@ -268,6 +270,10 @@ ReplaceMenuProvider.prototype.getHeaderEntries = function(element) { headerEntries = headerEntries.concat(this._getDataObjectIsCollection(element)); } + if (is(element, 'bpmn:Participant')) { + headerEntries = headerEntries.concat(this._getParticipantMultiplicity(element)); + } + if (is(element, 'bpmn:SubProcess') && !is(element, 'bpmn:Transaction') && !isEventSubProcess(element)) { @@ -486,7 +492,7 @@ ReplaceMenuProvider.prototype._getLoopEntries = function(element) { }; /** - * Get a list of menu items containing buttons for multi instance markers + * Get a list of menu items containing a button for the collection marker * * @param {djs.model.Base} element * @@ -519,6 +525,46 @@ ReplaceMenuProvider.prototype._getDataObjectIsCollection = function(element) { return dataObjectEntries; }; +/** + * Get a list of menu items containing a button for the participant multiplicity marker + * + * @param {djs.model.Base} element + * + * @return {Array} a list of menu items + */ +ReplaceMenuProvider.prototype._getParticipantMultiplicity = function(element) { + + var self = this; + var bpmnFactory = this._bpmnFactory; + var translate = this._translate; + + function toggleParticipantMultiplicity(event, entry) { + var isActive = entry.active; + var participantMultiplicity; + + if (!isActive) { + participantMultiplicity = bpmnFactory.create('bpmn:ParticipantMultiplicity'); + } + + self._modeling.updateProperties( + element, + { participantMultiplicity: participantMultiplicity }); + } + + var participantMultiplicity = element.businessObject.participantMultiplicity; + + var participantEntries = [ + { + id: 'toggle-participant-multiplicity', + className: 'bpmn-icon-parallel-mi-marker', + title: translate('Participant Multiplicity'), + active: !!participantMultiplicity, + action: toggleParticipantMultiplicity, + } + ]; + return participantEntries; +}; + /** * Get the menu items containing a button for the ad hoc marker diff --git a/test/fixtures/bpmn/features/replace/participants.bpmn b/test/fixtures/bpmn/features/replace/participants.bpmn new file mode 100644 index 00000000..8a1c6b85 --- /dev/null +++ b/test/fixtures/bpmn/features/replace/participants.bpmn @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js index d3b864dc..ea92655e 100644 --- a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js +++ b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js @@ -29,7 +29,8 @@ describe('features/popup-menu - replace menu provider', function() { var diagramXMLMarkers = require('../../../fixtures/bpmn/draw/activity-markers-simple.bpmn'), diagramXMLReplace = require('../../../fixtures/bpmn/features/replace/01_replace.bpmn'), - diagramXMLDataElements = require('../../../fixtures/bpmn/features/replace/data-elements.bpmn'); + diagramXMLDataElements = require('../../../fixtures/bpmn/features/replace/data-elements.bpmn'), + diagramXMLParticipants = require('../../../fixtures/bpmn/features/replace/participants.bpmn'); var testModules = [ coreModule, @@ -76,7 +77,7 @@ describe('features/popup-menu - replace menu provider', function() { })); - it('should undo toggle on', inject(function(commandStack, elementRegistry) { + it('should undo', inject(function(commandStack, elementRegistry) { // given var dataObjectReference = elementRegistry.get('DataObjectReference_1'); @@ -93,12 +94,12 @@ describe('features/popup-menu - replace menu provider', function() { var isCollectionMarker = queryEntry('toggle-is-collection'); // then - expect(domClasses(isCollectionMarker).has('active')).not.to.be.true; + expect(domClasses(isCollectionMarker).has('active')).to.be.false; expect(dataObjectReference.businessObject.dataObjectRef.isCollection).not.to.be.true; })); - it('should redo toggle on', inject(function(commandStack, elementRegistry) { + it('should redo', inject(function(commandStack, elementRegistry) { // given var dataObjectReference = elementRegistry.get('DataObjectReference_1'); @@ -188,6 +189,104 @@ describe('features/popup-menu - replace menu provider', function() { // then expect(domClasses(isCollectionMarker).has('active')).to.be.false; })); + + }); + + + describe('participants - multiplicity marker', function() { + + beforeEach(bootstrapModeler(diagramXMLParticipants, { modules: testModules })); + + + it('should toggle on', inject(function(elementRegistry) { + + // given + var participant = elementRegistry.get('Participant_1'); + + openPopup(participant); + + // when + triggerAction('toggle-participant-multiplicity'); + + openPopup(participant); + + var multiplicityMarker = queryEntry('toggle-participant-multiplicity'); + + // then + expect(domClasses(multiplicityMarker).has('active')).to.be.true; + expect(participant.businessObject.participantMultiplicity).to.exist; + })); + + + it('should undo', inject(function(commandStack, elementRegistry) { + + // given + var participant = elementRegistry.get('Participant_1'); + + openPopup(participant); + + triggerAction('toggle-participant-multiplicity'); + + // when + commandStack.undo(); + + openPopup(participant); + + var multiplicityMarker = queryEntry('toggle-participant-multiplicity'); + + // then + expect(domClasses(multiplicityMarker).has('active')).to.be.false; + expect(participant.businessObject.participantMultiplicity).not.to.exist; + })); + + + it('should redo', inject(function(commandStack, elementRegistry) { + + // given + var participant = elementRegistry.get('Participant_1'); + + openPopup(participant); + + triggerAction('toggle-participant-multiplicity'); + + commandStack.undo(); + + // when + commandStack.redo(); + + openPopup(participant); + + var multiplicityMarker = queryEntry('toggle-participant-multiplicity'); + + // then + expect(domClasses(multiplicityMarker).has('active')).to.be.true; + expect(participant.businessObject.participantMultiplicity).to.exist; + })); + + + it('should toggle off', inject(function(elementRegistry) { + + // given + var participant = elementRegistry.get('Participant_1'); + + openPopup(participant); + + triggerAction('toggle-participant-multiplicity'); + + openPopup(participant); + + // when + triggerAction('toggle-participant-multiplicity'); + + openPopup(participant); + + var multiplicityMarker = queryEntry('toggle-participant-multiplicity'); + + // then + expect(domClasses(multiplicityMarker).has('active')).to.be.false; + expect(participant.businessObject.participantMultiplicity).not.to.exist; + })); + });