feat(modeling): create collapsed pools via morph menu
You are now able to morph between collapsed and expanded pools * Not possible to drop elements in a collapsed pool * if a expanded pool collapses, the children are deleted Closes #365
This commit is contained in:
parent
49173abdad
commit
4732dcfc74
|
@ -5,6 +5,7 @@ var assign = require('lodash/object/assign'),
|
|||
forEach = require('lodash/collection/forEach'),
|
||||
isArray = require('lodash/lang/isArray'),
|
||||
is = require('../../util/ModelUtil').is,
|
||||
isExpanded = require('../../util/DiUtil').isExpanded,
|
||||
isAny = require('../modeling/util/ModelingUtil').isAny,
|
||||
getChildLanes = require('../modeling/util/LaneUtil').getChildLanes,
|
||||
isEventSubProcess = require('../../util/DiUtil').isEventSubProcess;
|
||||
|
@ -145,7 +146,8 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
|||
};
|
||||
}
|
||||
|
||||
if (isAny(businessObject, [ 'bpmn:Lane', 'bpmn:Participant' ])) {
|
||||
|
||||
if (isAny(businessObject, [ 'bpmn:Lane', 'bpmn:Participant' ]) && isExpanded(businessObject)) {
|
||||
|
||||
var childLanes = getChildLanes(element);
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ var assign = require('lodash/object/assign'),
|
|||
|
||||
var is = require('../../util/ModelUtil').is;
|
||||
|
||||
var isExpanded = require('../../util/DiUtil').isExpanded;
|
||||
|
||||
var BaseElementFactory = require('diagram-js/lib/core/ElementFactory'),
|
||||
LabelUtil = require('../../util/LabelUtil');
|
||||
|
||||
|
||||
/**
|
||||
* A bpmn-aware factory for diagram-js shapes
|
||||
*/
|
||||
|
@ -73,6 +74,10 @@ ElementFactory.prototype.createBpmnElement = function(elementType, attrs) {
|
|||
}
|
||||
}
|
||||
|
||||
if (attrs.processRef) {
|
||||
businessObject.processRef = attrs.processRef;
|
||||
}
|
||||
|
||||
if (attrs.isExpanded) {
|
||||
businessObject.di.isExpanded = attrs.isExpanded;
|
||||
}
|
||||
|
@ -120,9 +125,8 @@ ElementFactory.prototype.createBpmnElement = function(elementType, attrs) {
|
|||
ElementFactory.prototype._getDefaultSize = function(semantic) {
|
||||
|
||||
if (is(semantic, 'bpmn:SubProcess')) {
|
||||
var isExpanded = semantic.di.isExpanded === true;
|
||||
|
||||
if (isExpanded) {
|
||||
if (isExpanded(semantic)) {
|
||||
return { width: 350, height: 200 };
|
||||
} else {
|
||||
return { width: 100, height: 80 };
|
||||
|
@ -142,7 +146,11 @@ ElementFactory.prototype._getDefaultSize = function(semantic) {
|
|||
}
|
||||
|
||||
if (is(semantic, 'bpmn:Participant')) {
|
||||
return { width: 600, height: 250 };
|
||||
if (!isExpanded(semantic)) {
|
||||
return { width: 400, height: 100 };
|
||||
} else {
|
||||
return { width: 600, height: 250 };
|
||||
}
|
||||
}
|
||||
|
||||
if (is(semantic, 'bpmn:Lane')) {
|
||||
|
@ -167,11 +175,11 @@ ElementFactory.prototype._getDefaultSize = function(semantic) {
|
|||
|
||||
ElementFactory.prototype.createParticipantShape = function(collapsed) {
|
||||
|
||||
var participantShape = this.createShape({ type: 'bpmn:Participant' });
|
||||
var attrs = { type: 'bpmn:Participant' };
|
||||
|
||||
if (!collapsed) {
|
||||
participantShape.businessObject.processRef = this._bpmnFactory.create('bpmn:Process');
|
||||
attrs.processRef = this._bpmnFactory.create('bpmn:Process');
|
||||
}
|
||||
|
||||
return participantShape;
|
||||
return this.createShape(attrs);
|
||||
};
|
||||
|
|
|
@ -68,6 +68,16 @@ ReplaceMenuProvider.prototype.getEntries = function(element) {
|
|||
return this._createEntries(element, entries);
|
||||
}
|
||||
|
||||
// expanded/collapsed pools
|
||||
if (is(businessObject, 'bpmn:Participant')) {
|
||||
|
||||
entries = filter(replaceOptions.PARTICIPANT, function(entry) {
|
||||
return isExpanded(businessObject) !== entry.target.isExpanded;
|
||||
});
|
||||
|
||||
return this._createEntries(element, entries);
|
||||
}
|
||||
|
||||
// start events inside event sub processes
|
||||
if (is(businessObject, 'bpmn:StartEvent') && isEventSubProcess(businessObject.$parent)) {
|
||||
|
||||
|
@ -253,7 +263,6 @@ ReplaceMenuProvider.prototype._createEntries = function(element, replaceOptions)
|
|||
return menuEntries;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates an array of menu entry objects for a given sequence flow.
|
||||
*
|
||||
|
@ -462,4 +471,4 @@ ReplaceMenuProvider.prototype._getAdHocEntry = function(element) {
|
|||
return adHocEntry;
|
||||
};
|
||||
|
||||
module.exports = ReplaceMenuProvider;
|
||||
module.exports = ReplaceMenuProvider;
|
||||
|
|
|
@ -65,6 +65,22 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
newElement.isExpanded = isExpanded(oldBusinessObject);
|
||||
}
|
||||
|
||||
// transform collapsed/expanded pools
|
||||
if (is(oldBusinessObject, 'bpmn:Participant')) {
|
||||
|
||||
// create expanded pool
|
||||
if (target.isExpanded === true) {
|
||||
newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
|
||||
} else {
|
||||
// remove children when transforming to collapsed pool
|
||||
hints.moveChildren = false;
|
||||
}
|
||||
|
||||
// apply same size
|
||||
newElement.width = element.width;
|
||||
newElement.height = element.height;
|
||||
}
|
||||
|
||||
newBusinessObject.name = oldBusinessObject.name;
|
||||
|
||||
// retain loop characteristics if the target element is not an event sub process
|
||||
|
@ -85,7 +101,7 @@ function BpmnReplace(bpmnFactory, replace, selection, modeling) {
|
|||
newBusinessObject.isForCompensation = true;
|
||||
}
|
||||
|
||||
newElement = replace.replaceElement(element, newElement);
|
||||
newElement = replace.replaceElement(element, newElement, hints);
|
||||
|
||||
if (hints.select !== false) {
|
||||
selection.select(newElement);
|
||||
|
|
|
@ -745,3 +745,25 @@ module.exports.SEQUENCE_FLOW = [
|
|||
className: 'bpmn-icon-conditional-flow'
|
||||
}
|
||||
];
|
||||
|
||||
module.exports.PARTICIPANT = [
|
||||
{
|
||||
label: 'Expanded Pool',
|
||||
actionName: 'replace-with-expanded-pool',
|
||||
className: 'bpmn-icon-participant',
|
||||
target: {
|
||||
type: 'bpmn:Participant',
|
||||
isExpanded: true
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Collapsed Pool',
|
||||
actionName: 'replace-with-collapsed-pool',
|
||||
// TODO(@janstuemmel): maybe design new icon
|
||||
className: 'bpmn-icon-lane',
|
||||
target: {
|
||||
type: 'bpmn:Participant',
|
||||
isExpanded: false
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -341,6 +341,11 @@ function canDrop(element, target, position) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// disallow to create elements on collapsed pools
|
||||
if (is(target, 'bpmn:Participant') && !isExpanded(target)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// allow to create new participants on
|
||||
// on existing collaboration and process diagrams
|
||||
if (is(element, 'bpmn:Participant')) {
|
||||
|
@ -401,6 +406,7 @@ function isBoundaryCandidate(element) {
|
|||
|
||||
|
||||
function canAttach(elements, target, source, position) {
|
||||
|
||||
if (!Array.isArray(elements)) {
|
||||
elements = [ elements ];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
|
||||
<bpmn:collaboration id="Collaboration_1wsnry3">
|
||||
<bpmn:participant id="Participant_1" name="Pool" processRef="Process_1" />
|
||||
<bpmn:participant id="Participant_2" name="Pool" />
|
||||
<bpmn:messageFlow id="MessageFlow_2" sourceRef="Participant_2" targetRef="Participant_1" />
|
||||
<bpmn:messageFlow id="MessageFlow_1" sourceRef="Task_1" targetRef="Participant_2" />
|
||||
<bpmn:messageFlow id="MessageFlow_3" sourceRef="EndEvent_1" targetRef="Participant_2" />
|
||||
</bpmn:collaboration>
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:laneSet>
|
||||
<bpmn:lane id="Lane_1">
|
||||
<bpmn:flowNodeRef>Task_1</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>EndEvent_1</bpmn:flowNodeRef>
|
||||
</bpmn:lane>
|
||||
<bpmn:lane id="Lane_2" />
|
||||
</bpmn:laneSet>
|
||||
<bpmn:task id="Task_1" />
|
||||
<bpmn:endEvent id="EndEvent_1">
|
||||
<bpmn:messageEventDefinition />
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
<bpmn:process id="Process_18059hr" isExecutable="false" />
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1wsnry3">
|
||||
<bpmndi:BPMNShape id="Participant_0dhyklk_di" bpmnElement="Participant_1">
|
||||
<dc:Bounds x="181" y="82" width="458" height="271" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Lane_1lr6kkb_di" bpmnElement="Lane_1">
|
||||
<dc:Bounds x="211" y="82" width="428" height="138" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Lane_0c9o07a_di" bpmnElement="Lane_2">
|
||||
<dc:Bounds x="211" y="220" width="428" height="133" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Participant_06fwm9a_di" bpmnElement="Participant_2">
|
||||
<dc:Bounds x="237" y="436" width="378" height="115" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="MessageFlow_1xdh89f_di" bpmnElement="MessageFlow_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="368" y="436" />
|
||||
<di:waypoint xsi:type="dc:Point" x="368" y="353" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="381" y="384.5" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Task_0atv48s_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="276" y="112" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="MessageFlow_19wrxbj_di" bpmnElement="MessageFlow_1">
|
||||
<di:waypoint xsi:type="dc:Point" x="326" y="192" />
|
||||
<di:waypoint xsi:type="dc:Point" x="326" y="436" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="281" y="304" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="EndEvent_1ooqi8q_di" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds x="535" y="134" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="508" y="170" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="MessageFlow_15s8xey_di" bpmnElement="MessageFlow_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="553" y="170" />
|
||||
<di:waypoint xsi:type="dc:Point" x="553" y="434" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="508" y="293" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -187,6 +187,43 @@ describe('features/replace - bpmn replace', function() {
|
|||
});
|
||||
|
||||
|
||||
describe('should replace in collaboration', function() {
|
||||
|
||||
var diagramXML = require('./BpmnReplace.collaboration.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
it('expanded with collapsed pool', inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('Participant_1');
|
||||
|
||||
// when
|
||||
var newShape = bpmnReplace.replaceElement(shape, { type: 'bpmn:Participant', isExpanded: false });
|
||||
|
||||
// then
|
||||
expect(isExpanded(newShape)).to.be.false; // collapsed
|
||||
expect(newShape.children).to.be.empty;
|
||||
}));
|
||||
|
||||
|
||||
it('collapsed with expande pool', inject(function(elementRegistry, bpmnReplace) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('Participant_2');
|
||||
|
||||
// when
|
||||
var newShape = bpmnReplace.replaceElement(shape, { type: 'bpmn:Participant', isExpanded: true });
|
||||
|
||||
// then
|
||||
expect(isExpanded(newShape)).to.be.true; // expanded
|
||||
expect(newShape.children).to.be.empty;
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('position and size', function() {
|
||||
|
||||
var diagramXML = require('../../../fixtures/bpmn/features/replace/01_replace.bpmn');
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:bpmn2="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="_biH3sOTeEeS2YerRfpjPrw" targetNamespace="http://activiti.org/bpmn" exporter="camunda modeler" exporterVersion="2.6.0" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
|
||||
<bpmn2:collaboration id="Collaboration">
|
||||
<bpmn2:textAnnotation id="TextAnnotation_Global" />
|
||||
<bpmn2:participant id="Participant" name="Pool" processRef="Process" />
|
||||
<bpmn2:participant id="OtherParticipant" name="Pool" processRef="OtherProcess" />
|
||||
<bpmn2:participant id="CollapsedParticipant" name="Pool" />
|
||||
<bpmn2:textAnnotation id="TextAnnotation_Global" />
|
||||
</bpmn2:collaboration>
|
||||
<bpmn2:process id="Process" isExecutable="false">
|
||||
<bpmn2:startEvent id="StartEvent_None" />
|
||||
|
@ -39,6 +40,7 @@
|
|||
<bpmn2:task id="Task_in_OtherParticipant" />
|
||||
<bpmn2:textAnnotation id="TextAnnotation_OtherParticipant" />
|
||||
</bpmn2:process>
|
||||
<bpmn2:process id="Process_18q5tmq" isExecutable="false" />
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Participant_3" bpmnElement="Participant" isHorizontal="true">
|
||||
|
@ -128,6 +130,9 @@
|
|||
<dc:Bounds x="299" y="114" width="90" height="20" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Participant_09perow_di" bpmnElement="CollapsedParticipant">
|
||||
<dc:Bounds x="125" y="704" width="594" height="117" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
||||
|
|
|
@ -839,6 +839,13 @@ describe('features/modeling/rules - BpmnRules', function() {
|
|||
expectCanDrop('TextAnnotation_Global', 'Participant', true);
|
||||
}));
|
||||
|
||||
it('drop element -> collapsed Participant', inject(function(canvas){
|
||||
expectCanDrop('StartEvent_None', 'CollapsedParticipant', false);
|
||||
expectCanDrop('SubProcess', 'CollapsedParticipant', false);
|
||||
expectCanDrop('Task_in_SubProcess', 'CollapsedParticipant', false);
|
||||
expectCanDrop('TextAnnotation_Global', 'CollapsedParticipant', false);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue