From 5a60c370a77d758b21ef0eae451455c6a3298b97 Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Tue, 29 Sep 2015 07:58:26 +0200 Subject: [PATCH] feat(replace): add default flows Closes #272 --- .../context-pad/ContextPadProvider.js | 3 +- lib/features/replace/BpmnReplace.js | 38 ++++++-- lib/features/replace/ReplaceOptions.js | 11 +++ .../replace/BpmnReplace.defaultFlows.bpmn | 89 +++++++++++++++++++ test/spec/features/replace/BpmnReplaceSpec.js | 68 ++++++++++++++ 5 files changed, 199 insertions(+), 10 deletions(-) create mode 100644 test/spec/features/replace/BpmnReplace.defaultFlows.bpmn diff --git a/lib/features/context-pad/ContextPadProvider.js b/lib/features/context-pad/ContextPadProvider.js index a90e6142..637ea8a1 100644 --- a/lib/features/context-pad/ContextPadProvider.js +++ b/lib/features/context-pad/ContextPadProvider.js @@ -145,8 +145,9 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) { { _eventDefinitionType: 'bpmn:SignalEventDefinition'}) }); } + } - + if (is(bpmnElement, 'bpmn:FlowNode') || is(bpmnElement, 'bpmn:SequenceFlow')) { // Replace menu entry assign(actions, { 'replace': { diff --git a/lib/features/replace/BpmnReplace.js b/lib/features/replace/BpmnReplace.js index 071fc03d..33f7a4f9 100644 --- a/lib/features/replace/BpmnReplace.js +++ b/lib/features/replace/BpmnReplace.js @@ -16,7 +16,8 @@ var startEventReplace = REPLACE_OPTIONS.START_EVENT, transactionReplace = REPLACE_OPTIONS.TRANSACTION, eventSubProcessReplace = REPLACE_OPTIONS.EVENT_SUB_PROCESS, boundaryEventReplace = REPLACE_OPTIONS.BOUNDARY_EVENT, - eventSubProcessStartEventReplace = REPLACE_OPTIONS.EVENT_SUB_PROCESS_START_EVENT; + eventSubProcessStartEventReplace = REPLACE_OPTIONS.EVENT_SUB_PROCESS_START_EVENT, + sequenceFlowReplace = REPLACE_OPTIONS.SEQUENCE_FLOW; var is = require('../../util/ModelUtil').is, getBusinessObject = require('../../util/ModelUtil').getBusinessObject, @@ -71,7 +72,6 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin }; // initialize custom BPMN extensions - if (target.eventDefinition) { var eventDefinitions = businessObject.get('eventDefinitions'), eventDefinition = moddle.create(target.eventDefinition); @@ -80,10 +80,8 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin } // initialize special properties defined in target definition - assign(businessObject, pick(target, CUSTOM_PROPERTIES)); - // copy size (for activities only) if (is(oldBusinessObject, 'bpmn:Activity')) { @@ -271,12 +269,28 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin addEntries(boundaryEventReplace, filterEvents); } else + if (is(businessObject, 'bpmn:SequenceFlow')) { + addSequenceFlowEntries(sequenceFlowReplace); + } else + if (is(businessObject, 'bpmn:FlowNode')) { addEntries(taskReplace, function(entry) { return entry.target.type !== businessObject.$type; }); } + function addSequenceFlowEntries(entries) { + forEach(entries, function(entry) { + if (entry.actionName === 'replace-with-default-flow' && + is(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || + is(businessObject.sourceRef, 'bpmn:InclusiveGateway')) { + + menuEntries.push(addMenuEntry(entry, function() { + modeling.updateProperties(element.source, { default: businessObject }); + })); + } + }); + } function filterEvents(entry) { @@ -332,16 +346,22 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin } - function addMenuEntry(definition) { + function addMenuEntry(definition, action) { - return { + var menuEntry = { label: definition.label, className: definition.className, id: definition.actionName, - action: function() { - return replaceElement(element, definition.target); - } + action: action }; + + if (!menuEntry.action) { + menuEntry.action = function() { + return replaceElement(element, definition.target); + }; + } + + return menuEntry; } return menuEntries; diff --git a/lib/features/replace/ReplaceOptions.js b/lib/features/replace/ReplaceOptions.js index 7613d4ea..e799588f 100644 --- a/lib/features/replace/ReplaceOptions.js +++ b/lib/features/replace/ReplaceOptions.js @@ -718,3 +718,14 @@ module.exports.EVENT_SUB_PROCESS_START_EVENT = [ } }, ]; + +module.exports.SEQUENCE_FLOW = [ + { + label: 'Default Flow', + actionName: 'replace-with-default-flow', + className: 'icon-connection', + target: { + type: 'bpmn:SequenceFlow' + } + } +]; diff --git a/test/spec/features/replace/BpmnReplace.defaultFlows.bpmn b/test/spec/features/replace/BpmnReplace.defaultFlows.bpmn new file mode 100644 index 00000000..e82a8552 --- /dev/null +++ b/test/spec/features/replace/BpmnReplace.defaultFlows.bpmn @@ -0,0 +1,89 @@ + + + + + SequenceFlow_1 + SequenceFlow_2 + SequenceFlow_3 + + + SequenceFlow_1 + + + + SequenceFlow_2 + + + + SequenceFlow_3 + + + + SequenceFlow_4 + + + SequenceFlow_4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/features/replace/BpmnReplaceSpec.js b/test/spec/features/replace/BpmnReplaceSpec.js index 82dd7de4..f1e30cc8 100644 --- a/test/spec/features/replace/BpmnReplaceSpec.js +++ b/test/spec/features/replace/BpmnReplaceSpec.js @@ -926,4 +926,72 @@ describe('features/replace', function() { }); + describe('default flows', function() { + + var diagramXML = require('./BpmnReplace.defaultFlows.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: testModules })); + + it('should show Default replace option', inject(function(elementRegistry, bpmnReplace) { + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_3'); + + // when + var opts = bpmnReplace.getReplaceOptions(sequenceFlow); + + // then + expect(opts).to.have.length(1); + })); + + + it('should NOT show Default replace option', inject(function(elementRegistry, bpmnReplace) { + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_4'); + + // when + var opts = bpmnReplace.getReplaceOptions(sequenceFlow); + + // then + expect(opts).to.have.length(0); + })); + + + it('should replace SequenceFlow with DefaultFlow', inject(function(elementRegistry, bpmnReplace) { + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_3'); + + // when + var opts = bpmnReplace.getReplaceOptions(sequenceFlow); + + // trigger DefaultFlow replacement + opts[0].action(); + + var gateway = elementRegistry.get('ExclusiveGateway_1'); + + // then + expect(gateway.businessObject.default).to.equal(sequenceFlow.businessObject); + })); + + + it('should only have one DefaultFlow', inject(function(elementRegistry, bpmnReplace) { + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_1'), + sequenceFlow2 = elementRegistry.get('SequenceFlow_3'); + + // when + var sequenceFlowOpts = bpmnReplace.getReplaceOptions(sequenceFlow), + sequenceFlowOpts2 = bpmnReplace.getReplaceOptions(sequenceFlow2); + + // trigger DefaultFlow replacement + sequenceFlowOpts2[0].action(); + sequenceFlowOpts[0].action(); + + var gateway = elementRegistry.get('ExclusiveGateway_1'); + + // then + expect(gateway.businessObject.default).to.equal(sequenceFlow.businessObject); + })); + + }); + });