feat(modeling): create boundary event via moving intermediate event
This commit is contained in:
parent
1da513808c
commit
1e9aceecd7
|
@ -0,0 +1,61 @@
|
||||||
|
import inherits from 'inherits';
|
||||||
|
|
||||||
|
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
||||||
|
|
||||||
|
import { is } from '../../../util/ModelUtil';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN specific attach event behavior
|
||||||
|
*/
|
||||||
|
export default function AttachEventBehavior(eventBus, bpmnFactory, bpmnReplace) {
|
||||||
|
|
||||||
|
CommandInterceptor.call(this, eventBus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace intermediate event with boundary event when
|
||||||
|
* attaching it to a shape
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.preExecute('elements.move', function(context) {
|
||||||
|
var shapes = context.shapes,
|
||||||
|
host = context.newHost,
|
||||||
|
shape,
|
||||||
|
newShape,
|
||||||
|
businessObject,
|
||||||
|
boundaryEvent;
|
||||||
|
|
||||||
|
if (shapes.length !== 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shape = shapes[0];
|
||||||
|
|
||||||
|
var attrs = {
|
||||||
|
cancelActivity: true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (host && is(shape, 'bpmn:IntermediateThrowEvent')) {
|
||||||
|
attrs.attachedToRef = host.businessObject;
|
||||||
|
|
||||||
|
businessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs);
|
||||||
|
|
||||||
|
boundaryEvent = {
|
||||||
|
type: 'bpmn:BoundaryEvent',
|
||||||
|
businessObject: businessObject
|
||||||
|
};
|
||||||
|
|
||||||
|
newShape = bpmnReplace.replaceElement(shape, boundaryEvent);
|
||||||
|
|
||||||
|
context.shapes = [ newShape ];
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachEventBehavior.$inject = [
|
||||||
|
'eventBus',
|
||||||
|
'bpmnFactory',
|
||||||
|
'bpmnReplace'
|
||||||
|
];
|
||||||
|
|
||||||
|
inherits(AttachEventBehavior, CommandInterceptor);
|
|
@ -1,5 +1,6 @@
|
||||||
import AdaptiveLabelPositioningBehavior from './AdaptiveLabelPositioningBehavior';
|
import AdaptiveLabelPositioningBehavior from './AdaptiveLabelPositioningBehavior';
|
||||||
import AppendBehavior from './AppendBehavior';
|
import AppendBehavior from './AppendBehavior';
|
||||||
|
import AttachEventBehavior from './AttachEventBehavior';
|
||||||
import BoundaryEventBehavior from './BoundaryEventBehavior';
|
import BoundaryEventBehavior from './BoundaryEventBehavior';
|
||||||
import CopyPasteBehavior from './CopyPasteBehavior';
|
import CopyPasteBehavior from './CopyPasteBehavior';
|
||||||
import CreateBoundaryEventBehavior from './CreateBoundaryEventBehavior';
|
import CreateBoundaryEventBehavior from './CreateBoundaryEventBehavior';
|
||||||
|
@ -31,6 +32,7 @@ export default {
|
||||||
__init__: [
|
__init__: [
|
||||||
'adaptiveLabelPositioningBehavior',
|
'adaptiveLabelPositioningBehavior',
|
||||||
'appendBehavior',
|
'appendBehavior',
|
||||||
|
'attachEventBehavior',
|
||||||
'boundaryEventBehavior',
|
'boundaryEventBehavior',
|
||||||
'copyPasteBehavior',
|
'copyPasteBehavior',
|
||||||
'createBoundaryEventBehavior',
|
'createBoundaryEventBehavior',
|
||||||
|
@ -60,6 +62,7 @@ export default {
|
||||||
],
|
],
|
||||||
adaptiveLabelPositioningBehavior: [ 'type', AdaptiveLabelPositioningBehavior ],
|
adaptiveLabelPositioningBehavior: [ 'type', AdaptiveLabelPositioningBehavior ],
|
||||||
appendBehavior: [ 'type', AppendBehavior ],
|
appendBehavior: [ 'type', AppendBehavior ],
|
||||||
|
attachEventBehavior: [ 'type', AttachEventBehavior ],
|
||||||
boundaryEventBehavior: [ 'type', BoundaryEventBehavior ],
|
boundaryEventBehavior: [ 'type', BoundaryEventBehavior ],
|
||||||
copyPasteBehavior: [ 'type', CopyPasteBehavior ],
|
copyPasteBehavior: [ 'type', CopyPasteBehavior ],
|
||||||
createBoundaryEventBehavior: [ 'type', CreateBoundaryEventBehavior ],
|
createBoundaryEventBehavior: [ 'type', CreateBoundaryEventBehavior ],
|
||||||
|
|
|
@ -564,8 +564,7 @@ function isLane(element) {
|
||||||
* this must be reflected in the rules.
|
* this must be reflected in the rules.
|
||||||
*/
|
*/
|
||||||
function isBoundaryCandidate(element) {
|
function isBoundaryCandidate(element) {
|
||||||
return isBoundaryEvent(element) ||
|
return isBoundaryEvent(element) || is(element, 'bpmn:IntermediateThrowEvent');
|
||||||
(is(element, 'bpmn:IntermediateThrowEvent') && !element.parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasNoEventDefinition(element) {
|
function hasNoEventDefinition(element) {
|
||||||
|
@ -605,11 +604,6 @@ function canAttach(elements, target, source, position) {
|
||||||
elements = [ elements ];
|
elements = [ elements ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// disallow appending as boundary event
|
|
||||||
if (source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only (re-)attach one element at a time
|
// only (re-)attach one element at a time
|
||||||
if (elements.length !== 1) {
|
if (elements.length !== 1) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<bpmn2:task id="Task_2" />
|
<bpmn2:task id="Task_2" />
|
||||||
<bpmn2:boundaryEvent id="BoundaryEvent_2" name="superman" attachedToRef="Task_2" />
|
<bpmn2:boundaryEvent id="BoundaryEvent_2" name="superman" attachedToRef="Task_2" />
|
||||||
<bpmn2:task id="CompensationTask" isForCompensation="true" />
|
<bpmn2:task id="CompensationTask" isForCompensation="true" />
|
||||||
|
<bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_1" name="joker" />
|
||||||
</bpmn2:process>
|
</bpmn2:process>
|
||||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||||
|
@ -54,6 +55,12 @@
|
||||||
<bpmndi:BPMNShape id="CompensationTask_di" bpmnElement="CompensationTask">
|
<bpmndi:BPMNShape id="CompensationTask_di" bpmnElement="CompensationTask">
|
||||||
<dc:Bounds x="795" y="249" width="100" height="80" />
|
<dc:Bounds x="795" y="249" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="IntermediateThrowEvent_1_di" bpmnElement="IntermediateThrowEvent_1">
|
||||||
|
<dc:Bounds x="185" y="480" width="36" height="36" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="191" y="525" width="24" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
</bpmndi:BPMNPlane>
|
</bpmndi:BPMNPlane>
|
||||||
</bpmndi:BPMNDiagram>
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn2:definitions>
|
</bpmn2:definitions>
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import {
|
||||||
|
bootstrapModeler,
|
||||||
|
inject
|
||||||
|
} from 'test/TestHelper';
|
||||||
|
|
||||||
|
import modelingModule from 'lib/features/modeling';
|
||||||
|
import coreModule from 'lib/core';
|
||||||
|
|
||||||
|
|
||||||
|
describe('features/modeling/behavior - attach events', function() {
|
||||||
|
|
||||||
|
var testModules = [ coreModule, modelingModule ];
|
||||||
|
|
||||||
|
var processDiagramXML = require('../../../../fixtures/bpmn/boundary-events.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('should execute on attach', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var eventId = 'IntermediateThrowEvent_1',
|
||||||
|
intermediateThrowEvent = elementRegistry.get(eventId),
|
||||||
|
subProcess = elementRegistry.get('SubProcess_1'),
|
||||||
|
boundaryEvent;
|
||||||
|
|
||||||
|
var elements = [ intermediateThrowEvent ];
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.moveElements(elements, { x: 60, y: -131 }, subProcess, { attach: true });
|
||||||
|
|
||||||
|
// then
|
||||||
|
boundaryEvent = elementRegistry.get(eventId);
|
||||||
|
|
||||||
|
expect(intermediateThrowEvent.parent).to.not.exist;
|
||||||
|
expect(boundaryEvent).to.exist;
|
||||||
|
expect(boundaryEvent.type).to.equal('bpmn:BoundaryEvent');
|
||||||
|
expect(boundaryEvent.businessObject.attachedToRef).to.equal(subProcess.businessObject);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should NOT execute on drop', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var eventId = 'IntermediateThrowEvent_1',
|
||||||
|
intermediateThrowEvent = elementRegistry.get(eventId),
|
||||||
|
subProcess = elementRegistry.get('SubProcess_1');
|
||||||
|
|
||||||
|
var elements = [ intermediateThrowEvent ];
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.moveElements(elements, { x: 60, y: -191 }, subProcess);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(intermediateThrowEvent.parent).to.eql(subProcess);
|
||||||
|
expect(intermediateThrowEvent.type).to.equal('bpmn:IntermediateThrowEvent');
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
|
@ -1260,6 +1260,23 @@ describe('features/modeling/rules - BpmnRules', function() {
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
it('attach/move IntermediateThrowEvent -> SubProcess', inject(
|
||||||
|
function(elementRegistry) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var intermediateThrowEvent = elementRegistry.get('IntermediateThrowEvent_1');
|
||||||
|
|
||||||
|
var elements = [ intermediateThrowEvent ];
|
||||||
|
|
||||||
|
// then
|
||||||
|
expectCanMove(elements, 'SubProcess_1', {
|
||||||
|
attach: 'attach',
|
||||||
|
move: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1539,7 +1556,7 @@ describe('features/modeling/rules - BpmnRules', function() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(canAttach).to.be.false;
|
expect(canAttach).to.eql('attach');
|
||||||
expect(canCreate).to.be.false;
|
expect(canCreate).to.be.false;
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in New Issue