feat(replace): add default flows

Closes #272
This commit is contained in:
Ricardo Matias 2015-09-29 07:58:26 +02:00 committed by pedesen
parent 421912ddbf
commit 5a60c370a7
5 changed files with 199 additions and 10 deletions

View File

@ -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': {

View File

@ -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;

View File

@ -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'
}
}
];

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_1" isExecutable="false">
<bpmn:exclusiveGateway id="ExclusiveGateway_1" name="desired dish? " default="SequenceFlow_3">
<bpmn:outgoing>SequenceFlow_1</bpmn:outgoing>
<bpmn:outgoing>SequenceFlow_2</bpmn:outgoing>
<bpmn:outgoing>SequenceFlow_3</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:task id="Task_1" name="Make a pizza">
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow_1" sourceRef="ExclusiveGateway_1" targetRef="Task_1" />
<bpmn:task id="Task_2" name="cook salmon">
<bpmn:incoming>SequenceFlow_2</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow_2" sourceRef="ExclusiveGateway_1" targetRef="Task_2" />
<bpmn:task id="Task_3" name="starve..">
<bpmn:incoming>SequenceFlow_3</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow_3" sourceRef="ExclusiveGateway_1" targetRef="Task_3" />
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_4</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:task id="Task_4">
<bpmn:incoming>SequenceFlow_4</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="SequenceFlow_4" sourceRef="StartEvent_1" targetRef="Task_4" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="ExclusiveGateway_1_di" bpmnElement="ExclusiveGateway_1" isMarkerVisible="true">
<dc:Bounds x="452" y="282" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="332" y="337" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
<dc:Bounds x="636" y="127" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_1_di" bpmnElement="SequenceFlow_1">
<di:waypoint xsi:type="dc:Point" x="477" y="282" />
<di:waypoint xsi:type="dc:Point" x="477" y="167" />
<di:waypoint xsi:type="dc:Point" x="636" y="167" />
<bpmndi:BPMNLabel>
<dc:Bounds x="432" y="214.5" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Task_2_di" bpmnElement="Task_2">
<dc:Bounds x="636" y="267" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_2_di" bpmnElement="SequenceFlow_2">
<di:waypoint xsi:type="dc:Point" x="502" y="307" />
<di:waypoint xsi:type="dc:Point" x="569" y="307" />
<di:waypoint xsi:type="dc:Point" x="569" y="307" />
<di:waypoint xsi:type="dc:Point" x="636" y="307" />
<bpmndi:BPMNLabel>
<dc:Bounds x="524" y="304.5" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Task_3_di" bpmnElement="Task_3">
<dc:Bounds x="636" y="420" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_3_di" bpmnElement="SequenceFlow_3">
<di:waypoint xsi:type="dc:Point" x="477" y="332" />
<di:waypoint xsi:type="dc:Point" x="477" y="460" />
<di:waypoint xsi:type="dc:Point" x="636" y="460" />
<bpmndi:BPMNLabel>
<dc:Bounds x="432" y="386" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
<dc:Bounds x="864" y="289" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="837" y="325" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Task_4_di" bpmnElement="Task_4">
<dc:Bounds x="1045" y="267" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_4_di" bpmnElement="SequenceFlow_4">
<di:waypoint xsi:type="dc:Point" x="900" y="307" />
<di:waypoint xsi:type="dc:Point" x="1045" y="307" />
<bpmndi:BPMNLabel>
<dc:Bounds x="927.5" y="297" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -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);
}));
});
});