feat(bpmn-rules): replace start events only allowed in event sub process
this includes the following event definitions: * error * escalation * compensate Closes #583
This commit is contained in:
parent
42a40494a7
commit
d5fa27ead2
|
@ -13,7 +13,10 @@ var getParents = require('../modeling/util/ModelingUtil').getParents,
|
|||
getBusinessObject = require('../../util/ModelUtil').getBusinessObject,
|
||||
isExpanded = require('../../util/DiUtil').isExpanded,
|
||||
isEventSubProcess = require('../../util/DiUtil').isEventSubProcess,
|
||||
isInterrupting = require('../../util/DiUtil').isInterrupting;
|
||||
isInterrupting = require('../../util/DiUtil').isInterrupting,
|
||||
hasErrorEventDefinition = require('../../util/DiUtil').hasErrorEventDefinition,
|
||||
hasEscalationEventDefinition = require('../../util/DiUtil').hasEscalationEventDefinition,
|
||||
hasCompensateEventDefinition = require('../../util/DiUtil').hasCompensateEventDefinition;
|
||||
|
||||
|
||||
var RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
|
||||
|
@ -564,19 +567,31 @@ function canReplace(elements, target, position) {
|
|||
|
||||
forEach(elements, function(element) {
|
||||
|
||||
// replace a non-interrupting start event by a blank interrupting start event
|
||||
// when the target is not an event sub process
|
||||
if (!isEventSubProcess(target)) {
|
||||
|
||||
if (is(element, 'bpmn:StartEvent') &&
|
||||
!isInterrupting(element) &&
|
||||
element.type !== 'label' &&
|
||||
canDrop(element, target)) {
|
||||
|
||||
canExecute.replacements.push({
|
||||
oldElementId: element.id,
|
||||
newElementType: 'bpmn:StartEvent'
|
||||
});
|
||||
// replace a non-interrupting start event by a blank interrupting start event
|
||||
// when the target is not an event sub process
|
||||
if (!isInterrupting(element)) {
|
||||
canExecute.replacements.push({
|
||||
oldElementId: element.id,
|
||||
newElementType: 'bpmn:StartEvent'
|
||||
});
|
||||
}
|
||||
|
||||
// replace an error/escalation/compansate start event by a blank interrupting start event
|
||||
// when the target is not an event sub process
|
||||
if (hasErrorEventDefinition(element) ||
|
||||
hasEscalationEventDefinition(element) ||
|
||||
hasCompensateEventDefinition(element)) {
|
||||
canExecute.replacements.push({
|
||||
oldElementId: element.id,
|
||||
newElementType: 'bpmn:StartEvent'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
var is = require('./ModelUtil').is,
|
||||
getBusinessObject = require('./ModelUtil').getBusinessObject;
|
||||
|
||||
var forEach = require('lodash/collection/forEach');
|
||||
|
||||
module.exports.isExpanded = function(element) {
|
||||
|
||||
if (is(element, 'bpmn:CallActivity')) {
|
||||
|
@ -27,3 +29,32 @@ module.exports.isInterrupting = function(element) {
|
|||
module.exports.isEventSubProcess = function(element) {
|
||||
return element && !!getBusinessObject(element).triggeredByEvent;
|
||||
};
|
||||
|
||||
function hasEventDefinition(element, eventType) {
|
||||
var bo = getBusinessObject(element),
|
||||
hasEventDefinition = false;
|
||||
|
||||
if (bo.eventDefinitions) {
|
||||
forEach(bo.eventDefinitions, function(event) {
|
||||
if (is(event, eventType)) {
|
||||
hasEventDefinition = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return hasEventDefinition;
|
||||
}
|
||||
|
||||
module.exports.hasEventDefinition = hasEventDefinition;
|
||||
|
||||
module.exports.hasErrorEventDefinition = function(element) {
|
||||
return hasEventDefinition(element, 'bpmn:ErrorEventDefinition');
|
||||
};
|
||||
|
||||
module.exports.hasEscalationEventDefinition = function(element) {
|
||||
return hasEventDefinition(element, 'bpmn:EscalationEventDefinition');
|
||||
};
|
||||
|
||||
module.exports.hasCompensateEventDefinition = function(element) {
|
||||
return hasEventDefinition(element, 'bpmn:CompensateEventDefinition');
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?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: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" exporter="Camunda Modeler" exporterVersion="1.2.2">
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:subProcess id="SubProcess_1" name="SubProcess_1">
|
||||
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
|
||||
|
@ -31,6 +31,16 @@
|
|||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1" sourceRef="Task_3" targetRef="SubProcess_1" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_2" sourceRef="SubProcess_1" targetRef="Task_4" />
|
||||
<bpmn:subProcess id="SubProcess_3" name="SubProcess_3" triggeredByEvent="true">
|
||||
<bpmn:startEvent id="StartEvent_3" name="StartEvent_3">
|
||||
<bpmn:outgoing>SequenceFlow_094t9fa</bpmn:outgoing>
|
||||
<bpmn:errorEventDefinition />
|
||||
</bpmn:startEvent>
|
||||
<bpmn:task id="Task_5">
|
||||
<bpmn:incoming>SequenceFlow_094t9fa</bpmn:incoming>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_094t9fa" sourceRef="StartEvent_3" targetRef="Task_5" />
|
||||
</bpmn:subProcess>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
|
@ -92,6 +102,25 @@
|
|||
<dc:Bounds x="400" y="142" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="SubProcess_09cm4qb_di" bpmnElement="SubProcess_3" isExpanded="true">
|
||||
<dc:Bounds x="816" y="59" width="350" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="StartEvent_1v1eve6_di" bpmnElement="StartEvent_3">
|
||||
<dc:Bounds x="858" y="134" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="831" y="170" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_1j96pnq_di" bpmnElement="Task_5">
|
||||
<dc:Bounds x="972" y="112" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_094t9fa_di" bpmnElement="SequenceFlow_094t9fa">
|
||||
<di:waypoint xsi:type="dc:Point" x="894" y="152" />
|
||||
<di:waypoint xsi:type="dc:Point" x="972" y="152" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="888" y="127" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
|
|
|
@ -12,7 +12,8 @@ var modelingModule = require('../../../../lib/features/modeling'),
|
|||
var is = require('../../../../lib/util/ModelUtil').is,
|
||||
isExpanded = require('../../../../lib/util/DiUtil').isExpanded,
|
||||
isInterrupting = require('../../../../lib/util/DiUtil').isInterrupting,
|
||||
isEventSubProcess = require('../../../../lib/util/DiUtil').isEventSubProcess;
|
||||
isEventSubProcess = require('../../../../lib/util/DiUtil').isEventSubProcess,
|
||||
hasErrorEventDefinition = require('../../../../lib/util/DiUtil').hasErrorEventDefinition;
|
||||
|
||||
|
||||
describe('features/replace - bpmn replace', function() {
|
||||
|
@ -1030,6 +1031,115 @@ describe('features/replace - bpmn replace', function() {
|
|||
})
|
||||
);
|
||||
|
||||
it('should replace error start event after moving it outside event sub process',
|
||||
inject(function(elementRegistry, bpmnReplace, modeling) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_3'),
|
||||
root = elementRegistry.get('Process_1');
|
||||
|
||||
// when
|
||||
modeling.moveElements([startEvent], { x: 0, y: 200 }, root);
|
||||
|
||||
var startEventAfter = elementRegistry.filter(function(element) {
|
||||
return is(element, 'bpmn:StartEvent') && element.parent === root;
|
||||
})[0];
|
||||
|
||||
// then
|
||||
expect(hasErrorEventDefinition(startEventAfter)).to.be.false;
|
||||
expect(startEventAfter.parent).to.equal(root);
|
||||
})
|
||||
);
|
||||
|
||||
it('should replace error start event after moving it to a regular sub process',
|
||||
inject(function(bpmnReplace, elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_3'),
|
||||
subProcess = elementRegistry.get('SubProcess_1');
|
||||
|
||||
// when
|
||||
modeling.moveElements([startEvent], { x: 260, y: 60 }, subProcess);
|
||||
|
||||
var startEventAfter = elementRegistry.filter(function(element) {
|
||||
return is(element, 'bpmn:StartEvent') && element.parent === subProcess;
|
||||
})[0];
|
||||
|
||||
// then
|
||||
expect(hasErrorEventDefinition(startEventAfter)).to.be.false;
|
||||
expect(startEventAfter.parent).to.equal(subProcess);
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
it('should not replace error start event after moving it to another event sub process',
|
||||
inject(function(bpmnReplace, elementRegistry, modeling) {
|
||||
|
||||
// given
|
||||
var startEvent = elementRegistry.get('StartEvent_3'),
|
||||
subProcess = elementRegistry.get('SubProcess_1');
|
||||
|
||||
var eventSubProcess = bpmnReplace.replaceElement(subProcess, {
|
||||
type: 'bpmn:SubProcess',
|
||||
triggeredByEvent: true,
|
||||
isExpanded: true
|
||||
});
|
||||
|
||||
// when
|
||||
modeling.moveElements([startEvent], { x: 260, y: 60 }, eventSubProcess);
|
||||
|
||||
var startEventAfter = elementRegistry.filter(function(element) {
|
||||
return is(element, 'bpmn:StartEvent') && element.parent === eventSubProcess && element.type !== 'label';
|
||||
})[1];
|
||||
|
||||
// then
|
||||
expect(hasErrorEventDefinition(startEventAfter)).to.be.true;
|
||||
expect(startEventAfter.parent).to.equal(eventSubProcess);
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
it('should replace error start event when replacing parent event sub process',
|
||||
inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var eventSubProcess = elementRegistry.get('SubProcess_3');
|
||||
|
||||
// when
|
||||
var subProcess = bpmnReplace.replaceElement(eventSubProcess, { type: 'bpmn:SubProcess' });
|
||||
|
||||
// then
|
||||
var replacedStartEvent = elementRegistry.filter(function(element) {
|
||||
return (element.parent === subProcess && element.type !== 'label');
|
||||
})[0];
|
||||
|
||||
expect(hasErrorEventDefinition(replacedStartEvent)).to.be.false;
|
||||
expect(replacedStartEvent.parent).to.equal(subProcess);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
it('should not replace error start event when moving parent event sub process',
|
||||
inject(function(elementRegistry, bpmnReplace, modeling) {
|
||||
|
||||
// given
|
||||
var eventSubProcess = elementRegistry.get('SubProcess_3'),
|
||||
startEvent = elementRegistry.get('StartEvent_3');
|
||||
|
||||
// when
|
||||
modeling.moveElements([eventSubProcess], { x: 20, y: 30 });
|
||||
|
||||
// start event after moving parent
|
||||
var startEventAfter = elementRegistry.filter(function(element) {
|
||||
return (element.parent === eventSubProcess && element.type !== 'label');
|
||||
})[0];
|
||||
|
||||
// then
|
||||
expect(startEventAfter).to.equal(startEvent);
|
||||
expect(startEventAfter.parent).to.eql(eventSubProcess);
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue