mirror of
https://github.com/sartography/bpmn-js.git
synced 2025-01-11 17:44:12 +00:00
feat(modeling): add participant modeling behavior
This commit adds the ability to model participants from the palette. * Empty diagrams can be used as a start for participant _AND_ process diagram * Process diagrams can be converted to collaboration diagrams by dropping a participant onto them Closes #128
This commit is contained in:
parent
32741868e4
commit
0a03e59866
@ -16,6 +16,9 @@ BpmnFactory.prototype._needsId = function(element) {
|
|||||||
return element.$instanceOf('bpmn:RootElement') ||
|
return element.$instanceOf('bpmn:RootElement') ||
|
||||||
element.$instanceOf('bpmn:FlowElement') ||
|
element.$instanceOf('bpmn:FlowElement') ||
|
||||||
element.$instanceOf('bpmn:Artifact') ||
|
element.$instanceOf('bpmn:Artifact') ||
|
||||||
|
element.$instanceOf('bpmn:Participant') ||
|
||||||
|
element.$instanceOf('bpmn:Process') ||
|
||||||
|
element.$instanceOf('bpmn:Collaboration') ||
|
||||||
element.$instanceOf('bpmndi:BPMNShape') ||
|
element.$instanceOf('bpmndi:BPMNShape') ||
|
||||||
element.$instanceOf('bpmndi:BPMNEdge') ||
|
element.$instanceOf('bpmndi:BPMNEdge') ||
|
||||||
element.$instanceOf('bpmndi:BPMNDiagram') ||
|
element.$instanceOf('bpmndi:BPMNDiagram') ||
|
||||||
@ -81,5 +84,10 @@ BpmnFactory.prototype.createDiEdge = function(semantic, waypoints, attrs) {
|
|||||||
}, attrs));
|
}, attrs));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BpmnFactory.prototype.createDiPlane = function(semantic) {
|
||||||
|
return this.create('bpmndi:BPMNPlane', {
|
||||||
|
bpmnElement: semantic
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = BpmnFactory;
|
module.exports = BpmnFactory;
|
||||||
|
@ -69,7 +69,6 @@ function BpmnUpdater(eventBus, bpmnFactory, connectionDocking) {
|
|||||||
'connection.move',
|
'connection.move',
|
||||||
'connection.delete' ], updateParent);
|
'connection.delete' ], updateParent);
|
||||||
|
|
||||||
|
|
||||||
// update bounds
|
// update bounds
|
||||||
function updateBounds(e) {
|
function updateBounds(e) {
|
||||||
self.updateBounds(e.context.shape);
|
self.updateBounds(e.context.shape);
|
||||||
@ -186,6 +185,13 @@ BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getDefinitions(element) {
|
||||||
|
while (element && !element.$instanceOf('bpmn:Definitions')) {
|
||||||
|
element = element.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
|
BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
|
||||||
|
|
||||||
@ -197,10 +203,6 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
|||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:FlowElement')) {
|
if (businessObject.$instanceOf('bpmn:FlowElement')) {
|
||||||
|
|
||||||
if (businessObject.$parent === newParent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newParent && newParent.$instanceOf('bpmn:Participant')) {
|
if (newParent && newParent.$instanceOf('bpmn:Participant')) {
|
||||||
newParent = newParent.processRef;
|
newParent = newParent.processRef;
|
||||||
}
|
}
|
||||||
@ -226,6 +228,30 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
|||||||
containment = 'artifacts';
|
containment = 'artifacts';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (businessObject.$instanceOf('bpmn:Participant')) {
|
||||||
|
containment = 'participants';
|
||||||
|
|
||||||
|
// make sure the participants process is properly attached / detached
|
||||||
|
// from the XML document
|
||||||
|
|
||||||
|
var process = businessObject.processRef,
|
||||||
|
definitions;
|
||||||
|
|
||||||
|
if (process) {
|
||||||
|
definitions = getDefinitions(businessObject.$parent || newParent);
|
||||||
|
|
||||||
|
if (businessObject.$parent) {
|
||||||
|
Collections.remove(definitions.get('rootElements'), process);
|
||||||
|
process.$parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newParent) {
|
||||||
|
Collections.add(definitions.get('rootElements'), process);
|
||||||
|
process.$parent = definitions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!containment) {
|
if (!containment) {
|
||||||
throw new Error('no parent for ', businessObject, newParent);
|
throw new Error('no parent for ', businessObject, newParent);
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,11 @@ ElementFactory.prototype.create = function(elementType, attrs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!businessObject.di) {
|
if (!businessObject.di) {
|
||||||
|
if (elementType === 'root') {
|
||||||
|
businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], {
|
||||||
|
id: businessObject.id + '_di'
|
||||||
|
});
|
||||||
|
} else
|
||||||
if (elementType === 'connection') {
|
if (elementType === 'connection') {
|
||||||
businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
|
businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
|
||||||
id: businessObject.id + '_di'
|
id: businessObject.id + '_di'
|
||||||
@ -111,5 +116,21 @@ ElementFactory.prototype._getDefaultSize = function(semantic) {
|
|||||||
return { width: 36, height: 36 };
|
return { width: 36, height: 36 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (semantic.$instanceOf('bpmn:Participant')) {
|
||||||
|
return { width: 600, height: 300 };
|
||||||
|
}
|
||||||
|
|
||||||
return { width: 100, height: 80 };
|
return { width: 100, height: 80 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ElementFactory.prototype.createParticipantShape = function(collapsed) {
|
||||||
|
|
||||||
|
var participantShape = this.createShape({ type: 'bpmn:Participant' });
|
||||||
|
|
||||||
|
if (!collapsed) {
|
||||||
|
participantShape.businessObject.processRef = this._bpmnFactory.create('bpmn:Process');
|
||||||
|
}
|
||||||
|
|
||||||
|
return participantShape;
|
||||||
|
};
|
@ -4,7 +4,8 @@ var inherits = require('inherits');
|
|||||||
|
|
||||||
var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
|
var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
|
||||||
|
|
||||||
var UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler');
|
var UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler'),
|
||||||
|
UpdateCanvasRootHandler = require('./cmd/UpdateCanvasRootHandler');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +30,7 @@ Modeling.prototype.getHandlers = function() {
|
|||||||
var handlers = BaseModeling.prototype.getHandlers.call(this);
|
var handlers = BaseModeling.prototype.getHandlers.call(this);
|
||||||
|
|
||||||
handlers['element.updateProperties'] = UpdatePropertiesHandler;
|
handlers['element.updateProperties'] = UpdatePropertiesHandler;
|
||||||
|
handlers['canvas.updateRoot'] = UpdateCanvasRootHandler;
|
||||||
|
|
||||||
return handlers;
|
return handlers;
|
||||||
};
|
};
|
||||||
@ -72,4 +74,43 @@ Modeling.prototype.updateProperties = function(element, properties) {
|
|||||||
element: element,
|
element: element,
|
||||||
properties: properties
|
properties: properties
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the current diagram into a collaboration.
|
||||||
|
*
|
||||||
|
* @return {djs.model.Root} the new root element
|
||||||
|
*/
|
||||||
|
Modeling.prototype.makeCollaboration = function() {
|
||||||
|
|
||||||
|
var collaborationElement = this._create('root', {
|
||||||
|
type: 'bpmn:Collaboration'
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = {
|
||||||
|
newRoot: collaborationElement
|
||||||
|
};
|
||||||
|
|
||||||
|
this._commandStack.execute('canvas.updateRoot', context);
|
||||||
|
|
||||||
|
return collaborationElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the current diagram into a process.
|
||||||
|
*
|
||||||
|
* @return {djs.model.Root} the new root element
|
||||||
|
*/
|
||||||
|
Modeling.prototype.makeProcess = function() {
|
||||||
|
|
||||||
|
var processElement = this._create('root', {
|
||||||
|
type: 'bpmn:Process'
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = {
|
||||||
|
newRoot: processElement
|
||||||
|
};
|
||||||
|
|
||||||
|
this._commandStack.execute('canvas.updateRoot', context);
|
||||||
};
|
};
|
104
lib/features/modeling/behavior/CreateBehavior.js
Normal file
104
lib/features/modeling/behavior/CreateBehavior.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var inherits = require('inherits');
|
||||||
|
|
||||||
|
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
|
||||||
|
|
||||||
|
var getBoundingBox = require('diagram-js/lib/util/Elements').getBBox,
|
||||||
|
assign = require('lodash/object/assign');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN specific create behavior
|
||||||
|
*/
|
||||||
|
function CreateBehavior(eventBus, modeling) {
|
||||||
|
|
||||||
|
CommandInterceptor.call(this, eventBus);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* morph process into collaboration before adding
|
||||||
|
* participant onto collaboration
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.preExecute('shape.create', function(context) {
|
||||||
|
|
||||||
|
var parent = context.parent,
|
||||||
|
shape = context.shape,
|
||||||
|
position = context.position;
|
||||||
|
|
||||||
|
if (parent.businessObject.$instanceOf('bpmn:Process') &&
|
||||||
|
shape.businessObject.$instanceOf('bpmn:Participant')) {
|
||||||
|
|
||||||
|
// update shape size + position of new participant to
|
||||||
|
// encapsulate all existing children
|
||||||
|
if (parent.children.length) {
|
||||||
|
var bbox = getBoundingBox(parent.children);
|
||||||
|
|
||||||
|
assign(shape, {
|
||||||
|
width: bbox.width + 60,
|
||||||
|
height: bbox.height + 40
|
||||||
|
});
|
||||||
|
|
||||||
|
position = {
|
||||||
|
x: bbox.x - 40 + shape.width / 2,
|
||||||
|
y: bbox.y - 20 + shape.height / 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is going to detach the process root
|
||||||
|
// and set the returned collaboration element
|
||||||
|
// as the new root element
|
||||||
|
var collaborationElement = modeling.makeCollaboration();
|
||||||
|
|
||||||
|
// monkey patch the create context
|
||||||
|
// so that the participant is being dropped
|
||||||
|
// onto the new collaboration root instead
|
||||||
|
context.position = position;
|
||||||
|
context.parent = collaborationElement;
|
||||||
|
|
||||||
|
context.processRoot = parent;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
this.execute('shape.create', function(context) {
|
||||||
|
|
||||||
|
var processRoot = context.processRoot,
|
||||||
|
shape = context.shape;
|
||||||
|
|
||||||
|
if (processRoot) {
|
||||||
|
context.oldProcessRef = shape.businessObject.processRef;
|
||||||
|
|
||||||
|
// assign the participant processRef
|
||||||
|
shape.businessObject.processRef = processRoot.businessObject;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
this.revert('shape.create', function(context) {
|
||||||
|
var processRoot = context.processRoot,
|
||||||
|
shape = context.shape;
|
||||||
|
|
||||||
|
if (processRoot) {
|
||||||
|
// assign the participant processRef
|
||||||
|
shape.businessObject.processRef = context.oldProcessRef;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
this.postExecute('shape.create', function(context) {
|
||||||
|
|
||||||
|
var processRoot = context.processRoot,
|
||||||
|
shape = context.shape;
|
||||||
|
|
||||||
|
if (processRoot) {
|
||||||
|
// process root is already detached at this point
|
||||||
|
var processChildren = processRoot.children.slice();
|
||||||
|
modeling.moveShapes(processChildren, { x: 0, y: 0 }, shape);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateBehavior.$inject = [ 'eventBus', 'modeling' ];
|
||||||
|
|
||||||
|
inherits(CreateBehavior, CommandInterceptor);
|
||||||
|
|
||||||
|
module.exports = CreateBehavior;
|
@ -1,18 +1,20 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var forEach = require('lodash/collection/forEach');
|
var forEach = require('lodash/collection/forEach'),
|
||||||
|
inherits = require('inherits');
|
||||||
|
|
||||||
|
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
|
||||||
|
|
||||||
function DropBehavior(eventBus, modeling) {
|
function DropBehavior(eventBus, modeling) {
|
||||||
|
|
||||||
// sequence flow handling
|
CommandInterceptor.call(this, eventBus);
|
||||||
|
|
||||||
eventBus.on([
|
// remove sequence flows that should not be allowed
|
||||||
'commandStack.shapes.move.postExecute'
|
// after a move operation
|
||||||
], function(e) {
|
|
||||||
|
|
||||||
var context = e.context,
|
this.postExecute('shapes.move', function(context) {
|
||||||
closure = context.closure,
|
|
||||||
|
var closure = context.closure,
|
||||||
allConnections = closure.allConnections;
|
allConnections = closure.allConnections;
|
||||||
|
|
||||||
forEach(allConnections, function(c) {
|
forEach(allConnections, function(c) {
|
||||||
@ -22,10 +24,11 @@ function DropBehavior(eventBus, modeling) {
|
|||||||
modeling.removeConnection(c);
|
modeling.removeConnection(c);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inherits(DropBehavior, CommandInterceptor);
|
||||||
|
|
||||||
DropBehavior.$inject = [ 'eventBus', 'modeling' ];
|
DropBehavior.$inject = [ 'eventBus', 'modeling' ];
|
||||||
|
|
||||||
module.exports = DropBehavior;
|
module.exports = DropBehavior;
|
48
lib/features/modeling/behavior/RemoveBehavior.js
Normal file
48
lib/features/modeling/behavior/RemoveBehavior.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var inherits = require('inherits');
|
||||||
|
|
||||||
|
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN specific remove behavior
|
||||||
|
*/
|
||||||
|
function RemoveBehavior(eventBus, modeling) {
|
||||||
|
|
||||||
|
CommandInterceptor.call(this, eventBus);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* morph collaboration diagram into process diagram
|
||||||
|
* after the last participant has been removed
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.preExecute('shape.delete', function(context) {
|
||||||
|
|
||||||
|
var shape = context.shape,
|
||||||
|
parent = shape.parent;
|
||||||
|
|
||||||
|
// activate the behavior if the shape to be removed
|
||||||
|
// is a participant
|
||||||
|
if (shape.businessObject.$instanceOf('bpmn:Participant')) {
|
||||||
|
context.collaborationRoot = parent;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
this.postExecute('shape.delete', function(context) {
|
||||||
|
|
||||||
|
var collaborationRoot = context.collaborationRoot;
|
||||||
|
|
||||||
|
if (collaborationRoot && collaborationRoot.businessObject.participants.length < 2) {
|
||||||
|
// replace empty collaboration with process diagram
|
||||||
|
modeling.makeProcess();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveBehavior.$inject = [ 'eventBus', 'modeling' ];
|
||||||
|
|
||||||
|
inherits(RemoveBehavior, CommandInterceptor);
|
||||||
|
|
||||||
|
module.exports = RemoveBehavior;
|
@ -1,5 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
__init__: [ 'appendBehavior', 'dropBehavior' ],
|
__init__: [ 'appendBehavior', 'dropBehavior', 'createBehavior', 'removeBehavior' ],
|
||||||
appendBehavior: [ 'type', require('./AppendBehavior') ],
|
appendBehavior: [ 'type', require('./AppendBehavior') ],
|
||||||
|
createBehavior: [ 'type', require('./CreateBehavior') ],
|
||||||
|
removeBehavior: [ 'type', require('./RemoveBehavior') ],
|
||||||
dropBehavior: [ 'type', require('./DropBehavior') ]
|
dropBehavior: [ 'type', require('./DropBehavior') ]
|
||||||
};
|
};
|
73
lib/features/modeling/cmd/UpdateCanvasRootHandler.js
Normal file
73
lib/features/modeling/cmd/UpdateCanvasRootHandler.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Collections = require('diagram-js/lib/util/Collections');
|
||||||
|
|
||||||
|
|
||||||
|
function UpdateCanvasRootHandler(canvas, modeling) {
|
||||||
|
this._canvas = canvas;
|
||||||
|
this._modeling = modeling;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateCanvasRootHandler.$inject = [ 'canvas', 'modeling' ];
|
||||||
|
|
||||||
|
module.exports = UpdateCanvasRootHandler;
|
||||||
|
|
||||||
|
|
||||||
|
UpdateCanvasRootHandler.prototype.execute = function(context) {
|
||||||
|
|
||||||
|
var canvas = this._canvas;
|
||||||
|
|
||||||
|
var newRoot = context.newRoot,
|
||||||
|
newRootBusinessObject = newRoot.businessObject,
|
||||||
|
oldRoot = canvas.getRootElement(),
|
||||||
|
oldRootBusinessObject = oldRoot.businessObject,
|
||||||
|
bpmnDefinitions = oldRootBusinessObject.$parent,
|
||||||
|
diPlane = oldRootBusinessObject.di;
|
||||||
|
|
||||||
|
// (1) replace process old <> new root
|
||||||
|
canvas.setRootElement(newRoot, true);
|
||||||
|
|
||||||
|
// (2) update root elements
|
||||||
|
Collections.add(bpmnDefinitions.rootElements, newRootBusinessObject);
|
||||||
|
newRootBusinessObject.$parent = bpmnDefinitions;
|
||||||
|
|
||||||
|
Collections.remove(bpmnDefinitions.rootElements, oldRootBusinessObject);
|
||||||
|
oldRootBusinessObject.$parent = null;
|
||||||
|
|
||||||
|
// (3) wire di
|
||||||
|
oldRootBusinessObject.di = null;
|
||||||
|
|
||||||
|
diPlane.bpmnElement = newRootBusinessObject;
|
||||||
|
newRootBusinessObject.di = diPlane;
|
||||||
|
|
||||||
|
context.oldRoot = oldRoot;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UpdateCanvasRootHandler.prototype.revert = function(context) {
|
||||||
|
|
||||||
|
var canvas = this._canvas;
|
||||||
|
|
||||||
|
var newRoot = context.newRoot,
|
||||||
|
newRootBusinessObject = newRoot.businessObject,
|
||||||
|
oldRoot = context.oldRoot,
|
||||||
|
oldRootBusinessObject = oldRoot.businessObject,
|
||||||
|
bpmnDefinitions = newRootBusinessObject.$parent,
|
||||||
|
diPlane = newRootBusinessObject.di;
|
||||||
|
|
||||||
|
// (1) replace process old <> new root
|
||||||
|
canvas.setRootElement(oldRoot, true);
|
||||||
|
|
||||||
|
// (2) update root elements
|
||||||
|
Collections.remove(bpmnDefinitions.rootElements, newRootBusinessObject);
|
||||||
|
newRootBusinessObject.$parent = null;
|
||||||
|
|
||||||
|
Collections.add(bpmnDefinitions.rootElements, oldRootBusinessObject);
|
||||||
|
oldRootBusinessObject.$parent = bpmnDefinitions;
|
||||||
|
|
||||||
|
// (3) wire di
|
||||||
|
newRootBusinessObject.di = null;
|
||||||
|
|
||||||
|
diPlane.bpmnElement = oldRootBusinessObject;
|
||||||
|
oldRootBusinessObject.di = diPlane;
|
||||||
|
};
|
@ -18,7 +18,6 @@ ModelingRules.$inject = [ 'eventBus' ];
|
|||||||
|
|
||||||
module.exports = ModelingRules;
|
module.exports = ModelingRules;
|
||||||
|
|
||||||
|
|
||||||
ModelingRules.prototype.init = function() {
|
ModelingRules.prototype.init = function() {
|
||||||
|
|
||||||
function nonExistantOrLabel(element) {
|
function nonExistantOrLabel(element) {
|
||||||
@ -173,15 +172,15 @@ ModelingRules.prototype.init = function() {
|
|||||||
newBounds = context.newBounds,
|
newBounds = context.newBounds,
|
||||||
bo = shape.businessObject;
|
bo = shape.businessObject;
|
||||||
|
|
||||||
if (!bo.$instanceOf('bpmn:SubProcess') || !bo.di.isExpanded) {
|
if (bo.$instanceOf('bpmn:SubProcess') && bo.di.isExpanded) {
|
||||||
return false;
|
return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newBounds) {
|
if (bo.$instanceOf('bpmn:Participant')) {
|
||||||
if (newBounds.width < 100 || newBounds.height < 80) {
|
return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,6 +190,14 @@ ModelingRules.prototype.init = function() {
|
|||||||
*/
|
*/
|
||||||
function canDrop(businessObject, targetBusinessObject, targetDi) {
|
function canDrop(businessObject, targetBusinessObject, targetDi) {
|
||||||
|
|
||||||
|
// allow to create new participants on
|
||||||
|
// on existing collaboration and process diagrams
|
||||||
|
if (businessObject.$instanceOf('bpmn:Participant') &&
|
||||||
|
(targetBusinessObject.$instanceOf('bpmn:Process') ||
|
||||||
|
targetBusinessObject.$instanceOf('bpmn:Collaboration'))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:FlowElement') &&
|
if (businessObject.$instanceOf('bpmn:FlowElement') &&
|
||||||
targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer')) {
|
targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer')) {
|
||||||
|
|
||||||
@ -202,15 +209,29 @@ ModelingRules.prototype.init = function() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:TextAnnotation') &&
|
if (targetBusinessObject.$instanceOf('bpmn:Collaboration') &&
|
||||||
targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer')) {
|
!businessObject.$instanceOf('bpmn:Participant') &&
|
||||||
|
!targetBusinessObject.participants.length) {
|
||||||
|
|
||||||
|
// TODO: transform collaboration into process
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (businessObject.$instanceOf('bpmn:FlowElement') &&
|
||||||
|
targetBusinessObject.$instanceOf('bpmn:Participant') &&
|
||||||
|
targetBusinessObject.processRef) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (businessObject.$instanceOf('bpmn:TextAnnotation') &&
|
||||||
|
(targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer') ||
|
||||||
|
targetBusinessObject.$instanceOf('bpmn:Participant'))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:Association') &&
|
if (businessObject.$instanceOf('bpmn:Association') &&
|
||||||
targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer')) {
|
(targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer') ||
|
||||||
|
targetBusinessObject.$instanceOf('bpmn:Participant'))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,11 @@ PaletteProvider.$inject = [ 'palette', 'create', 'elementFactory' ];
|
|||||||
|
|
||||||
PaletteProvider.prototype.getPaletteEntries = function(element) {
|
PaletteProvider.prototype.getPaletteEntries = function(element) {
|
||||||
|
|
||||||
|
var actions = {},
|
||||||
|
create = this._create,
|
||||||
|
elementFactory = this._elementFactory;
|
||||||
|
|
||||||
|
|
||||||
function createAction(type, group, className, title, options) {
|
function createAction(type, group, className, title, options) {
|
||||||
|
|
||||||
function createListener(event) {
|
function createListener(event) {
|
||||||
@ -43,9 +48,9 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var actions = {},
|
function createParticipant(event, collapsed) {
|
||||||
create = this._create,
|
create.start(event, elementFactory.createParticipantShape(collapsed));
|
||||||
elementFactory = this._elementFactory;
|
}
|
||||||
|
|
||||||
|
|
||||||
assign(actions, {
|
assign(actions, {
|
||||||
@ -71,7 +76,16 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
|
|||||||
'create.subprocess-expanded': createAction(
|
'create.subprocess-expanded': createAction(
|
||||||
'bpmn:SubProcess', 'activity', 'icon-subprocess-expanded', 'Sub Process (expanded)',
|
'bpmn:SubProcess', 'activity', 'icon-subprocess-expanded', 'Sub Process (expanded)',
|
||||||
{ isExpanded: true }
|
{ isExpanded: true }
|
||||||
)
|
),
|
||||||
|
'create.participant-expanded': {
|
||||||
|
group: 'collaboration',
|
||||||
|
className: 'icon-participant',
|
||||||
|
title: 'Create a participant',
|
||||||
|
action: {
|
||||||
|
dragstart: createParticipant,
|
||||||
|
click: createParticipant
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return actions;
|
return actions;
|
||||||
|
14
test/fixtures/bpmn/collaboration/collaboration-empty-participant.bpmn
vendored
Normal file
14
test/fixtures/bpmn/collaboration/collaboration-empty-participant.bpmn
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_P58jANhOEeSW1LwlVzMs4g" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:collaboration id="_Collaboration_2">
|
||||||
|
<bpmn2:participant id="_Participant_2" name="Participant" processRef="Process_1"/>
|
||||||
|
</bpmn2:collaboration>
|
||||||
|
<bpmn2:process id="Process_1" isExecutable="false"/>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_2" bpmnElement="_Participant_2" isHorizontal="true">
|
||||||
|
<dc:Bounds height="236.0" width="546.0" x="84.0" y="62.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
90
test/fixtures/bpmn/collaboration/collaboration-message-flows.bpmn
vendored
Normal file
90
test/fixtures/bpmn/collaboration/collaboration-message-flows.bpmn
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_P58jANhOEeSW1LwlVzMs4g" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:collaboration id="_Collaboration_2">
|
||||||
|
<bpmn2:participant id="_Participant_2" name="Participant" processRef="Process_1"/>
|
||||||
|
<bpmn2:participant id="Participant_1" name="Pool" processRef="Process_2"/>
|
||||||
|
<bpmn2:messageFlow id="MessageFlow_1" name="" sourceRef="Task_1" targetRef="Participant_1"/>
|
||||||
|
<bpmn2:messageFlow id="MessageFlow_2" name="" sourceRef="Participant_1" targetRef="_Participant_2"/>
|
||||||
|
<bpmn2:messageFlow id="MessageFlow_3" name="" sourceRef="Task_2" targetRef="_Participant_2"/>
|
||||||
|
</bpmn2:collaboration>
|
||||||
|
<bpmn2:process id="Process_1" isExecutable="false">
|
||||||
|
<bpmn2:subProcess id="SubProcess_1">
|
||||||
|
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||||
|
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||||
|
<bpmn2:task id="Task_1"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:startEvent id="StartEvent_1" name="Start">
|
||||||
|
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||||
|
</bpmn2:startEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="SubProcess_1"/>
|
||||||
|
<bpmn2:endEvent id="EndEvent_1" name="End">
|
||||||
|
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||||
|
</bpmn2:endEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="SubProcess_1" targetRef="EndEvent_1"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmn2:process id="Process_2" isExecutable="false">
|
||||||
|
<bpmn2:subProcess id="SubProcess_2">
|
||||||
|
<bpmn2:task id="Task_2"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="174.0" y="155.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="21.0" width="34.0" x="175.0" y="196.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_2" bpmnElement="SubProcess_1" isExpanded="true">
|
||||||
|
<dc:Bounds height="150.0" width="200.0" x="294.0" y="98.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_2" targetElement="_BPMNShape_SubProcess_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="210.0" y="173.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="294.0" y="173.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="6.0" width="6.0" x="232.0" y="173.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_1">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="314.0" y="131.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="544.0" y="155.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="21.0" width="29.0" x="548.0" y="196.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_SubProcess_2" targetElement="_BPMNShape_EndEvent_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="494.0" y="173.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="544.0" y="173.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="6.0" width="6.0" x="516.0" y="173.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_2" bpmnElement="_Participant_2" isHorizontal="true">
|
||||||
|
<dc:Bounds height="236.0" width="546.0" x="84.0" y="62.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_3" bpmnElement="Participant_1" isHorizontal="true">
|
||||||
|
<dc:Bounds height="157.0" width="546.0" x="84.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_3" bpmnElement="SubProcess_2" isExpanded="true">
|
||||||
|
<dc:Bounds height="137.0" width="200.0" x="396.0" y="370.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_2">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="468.0" y="408.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_MessageFlow_1" bpmnElement="MessageFlow_1" sourceElement="_BPMNShape_Task_2" targetElement="_BPMNShape_Participant_3">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="364.0" y="211.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="364.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_MessageFlow_2" bpmnElement="MessageFlow_2" sourceElement="_BPMNShape_Participant_3" targetElement="_BPMNShape_Participant_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="357.0" y="360.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="357.0" y="298.0"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_MessageFlow_3" bpmnElement="MessageFlow_3" sourceElement="_BPMNShape_Task_3" targetElement="_BPMNShape_Participant_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="518.0" y="408.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="518.0" y="298.0"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
60
test/fixtures/bpmn/collaboration/collaboration-participant.bpmn
vendored
Normal file
60
test/fixtures/bpmn/collaboration/collaboration-participant.bpmn
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_P58jANhOEeSW1LwlVzMs4g" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:collaboration id="_Collaboration_2">
|
||||||
|
<bpmn2:participant id="_Participant_2" name="Participant" processRef="Process_1"/>
|
||||||
|
</bpmn2:collaboration>
|
||||||
|
<bpmn2:process id="Process_1" isExecutable="false">
|
||||||
|
<bpmn2:subProcess id="SubProcess_1">
|
||||||
|
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||||
|
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||||
|
<bpmn2:task id="Task_1"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:startEvent id="StartEvent_1" name="Start">
|
||||||
|
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||||
|
</bpmn2:startEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="SubProcess_1"/>
|
||||||
|
<bpmn2:endEvent id="EndEvent_1" name="End">
|
||||||
|
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||||
|
</bpmn2:endEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="SubProcess_1" targetRef="EndEvent_1"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="174.0" y="155.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="21.0" width="34.0" x="175.0" y="196.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_2" bpmnElement="SubProcess_1" isExpanded="true">
|
||||||
|
<dc:Bounds height="150.0" width="200.0" x="294.0" y="98.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_2" targetElement="_BPMNShape_SubProcess_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="210.0" y="173.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="294.0" y="173.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="6.0" width="6.0" x="232.0" y="173.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_1">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="314.0" y="131.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="544.0" y="155.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="21.0" width="29.0" x="548.0" y="196.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_SubProcess_2" targetElement="_BPMNShape_EndEvent_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="494.0" y="173.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="544.0" y="173.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="6.0" width="6.0" x="516.0" y="173.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_2" bpmnElement="_Participant_2" isHorizontal="true">
|
||||||
|
<dc:Bounds height="236.0" width="546.0" x="84.0" y="62.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
7
test/fixtures/bpmn/collaboration/process-empty.bpmn
vendored
Normal file
7
test/fixtures/bpmn/collaboration/process-empty.bpmn
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_exCZYNkaEeSskpe2jvwgcA" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:process id="Process_1" isExecutable="false"/>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"/>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
48
test/fixtures/bpmn/collaboration/process.bpmn
vendored
Normal file
48
test/fixtures/bpmn/collaboration/process.bpmn
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="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" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_P58jANhOEeSW1LwlVzMs4g" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:process id="Process_1" isExecutable="false">
|
||||||
|
<bpmn2:subProcess id="SubProcess_1">
|
||||||
|
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
|
||||||
|
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
|
||||||
|
<bpmn2:task id="Task_1"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:startEvent id="StartEvent_1" name="Start">
|
||||||
|
<bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
|
||||||
|
</bpmn2:startEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="SubProcess_1"/>
|
||||||
|
<bpmn2:endEvent id="EndEvent_1" name="End">
|
||||||
|
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
|
||||||
|
</bpmn2:endEvent>
|
||||||
|
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="SubProcess_1" targetRef="EndEvent_1"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="192.0" y="129.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="210.0" y="170.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_2" bpmnElement="SubProcess_1" isExpanded="true">
|
||||||
|
<dc:Bounds height="150.0" width="200.0" x="312.0" y="72.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_2" targetElement="_BPMNShape_SubProcess_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="228.0" y="147.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="312.0" y="147.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="6.0" width="6.0" x="250.0" y="147.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="Task_1">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="332.0" y="105.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_2" bpmnElement="EndEvent_1">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="562.0" y="129.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_SubProcess_2" targetElement="_BPMNShape_EndEvent_2">
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="512.0" y="147.0"/>
|
||||||
|
<di:waypoint xsi:type="dc:Point" x="562.0" y="147.0"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
200
test/spec/features/modeling/CreateParticipantSpec.js
Normal file
200
test/spec/features/modeling/CreateParticipantSpec.js
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TestHelper = require('../../../TestHelper');
|
||||||
|
|
||||||
|
/* global bootstrapModeler, inject */
|
||||||
|
|
||||||
|
|
||||||
|
var modelingModule = require('../../../../lib/features/modeling'),
|
||||||
|
coreModule = require('../../../../lib/core');
|
||||||
|
|
||||||
|
|
||||||
|
describe('features/modeling - create participant', function() {
|
||||||
|
|
||||||
|
var testModules = [ coreModule, modelingModule ];
|
||||||
|
|
||||||
|
|
||||||
|
describe('on process diagram', function() {
|
||||||
|
|
||||||
|
describe('should transform diagram into collaboration', function() {
|
||||||
|
|
||||||
|
var processDiagramXML = require('../../../fixtures/bpmn/collaboration/process-empty.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('execute', inject(function(modeling, elementFactory, canvas) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var processShape = canvas.getRootElement(),
|
||||||
|
process = processShape.businessObject,
|
||||||
|
participantShape = elementFactory.createParticipantShape(true),
|
||||||
|
participant = participantShape.businessObject,
|
||||||
|
diRoot = process.di.$parent;
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 200 }, processShape);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participant.processRef).toBe(process);
|
||||||
|
|
||||||
|
var collaborationRoot = canvas.getRootElement(),
|
||||||
|
collaboration = collaborationRoot.businessObject,
|
||||||
|
collaborationDi = collaboration.di;
|
||||||
|
|
||||||
|
expect(collaboration.$instanceOf('bpmn:Collaboration')).toBe(true);
|
||||||
|
|
||||||
|
// participant / collaboration are wired
|
||||||
|
expect(participant.$parent).toBe(collaboration);
|
||||||
|
expect(collaboration.participants).toContain(participant);
|
||||||
|
|
||||||
|
|
||||||
|
// collaboration is added to root elements
|
||||||
|
expect(collaboration.$parent).toBe(process.$parent);
|
||||||
|
|
||||||
|
// di is wired
|
||||||
|
var participantDi = participant.di;
|
||||||
|
|
||||||
|
expect(participantDi.$parent).toBe(collaborationDi);
|
||||||
|
expect(collaborationDi.$parent).toBe(diRoot);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('undo', inject(function(modeling, elementFactory, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var processShape = canvas.getRootElement(),
|
||||||
|
process = processShape.businessObject,
|
||||||
|
processDi = process.di,
|
||||||
|
participantShape = elementFactory.createParticipantShape(true),
|
||||||
|
participant = participantShape.businessObject,
|
||||||
|
oldParticipantProcessRef = participant.processRef,
|
||||||
|
diRoot = process.di.$parent;
|
||||||
|
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 200 }, processShape);
|
||||||
|
|
||||||
|
var collaborationRoot = canvas.getRootElement(),
|
||||||
|
collaboration = collaborationRoot.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participant.processRef).toBe(oldParticipantProcessRef);
|
||||||
|
|
||||||
|
expect(participant.$parent).toBe(null);
|
||||||
|
expect(collaboration.participants).not.toContain(participant);
|
||||||
|
|
||||||
|
// collaboration is detached
|
||||||
|
expect(collaboration.$parent).toBe(null);
|
||||||
|
|
||||||
|
// di is wired
|
||||||
|
expect(processDi.$parent).toBe(diRoot);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('should wrap existing elements', function() {
|
||||||
|
|
||||||
|
var processDiagramXML = require('../../../fixtures/bpmn/collaboration/process.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('execute', inject(function(modeling, elementFactory, canvas) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var processShape = canvas.getRootElement(),
|
||||||
|
process = processShape.businessObject,
|
||||||
|
participantShape = elementFactory.createParticipantShape(true),
|
||||||
|
participant = participantShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 200 }, processShape);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participant.processRef).toBe(process);
|
||||||
|
|
||||||
|
var newRootShape = canvas.getRootElement(),
|
||||||
|
collaboration = newRootShape.businessObject;
|
||||||
|
|
||||||
|
expect(collaboration.$instanceOf('bpmn:Collaboration')).toBe(true);
|
||||||
|
|
||||||
|
expect(participant.$parent).toBe(collaboration);
|
||||||
|
expect(collaboration.participants).toContain(participant);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('undo', inject(function(modeling, elementFactory, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var processShape = canvas.getRootElement(),
|
||||||
|
participantShape = elementFactory.createParticipantShape(true);
|
||||||
|
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 200 }, processShape);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participantShape.children.length).toBe(0);
|
||||||
|
expect(processShape.children.length).toBe(9);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('should add to collaboration', function() {
|
||||||
|
|
||||||
|
var collaborationDiagramXML = require('../../../fixtures/bpmn/collaboration/collaboration-participant.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(collaborationDiagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('execute', inject(function(modeling, elementFactory, canvas) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var collaborationRoot = canvas.getRootElement(),
|
||||||
|
collaboration = collaborationRoot.businessObject,
|
||||||
|
participantShape = elementFactory.createParticipantShape(true),
|
||||||
|
participant = participantShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 500 }, collaborationRoot);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(collaborationRoot.children).toContain(participantShape);
|
||||||
|
|
||||||
|
expect(participant.$parent).toBe(collaboration);
|
||||||
|
expect(collaboration.participants).toContain(participant);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('undo', inject(function(modeling, elementFactory, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var collaborationRoot = canvas.getRootElement(),
|
||||||
|
collaboration = collaborationRoot.businessObject,
|
||||||
|
participantShape = elementFactory.createParticipantShape(true),
|
||||||
|
participant = participantShape.businessObject;
|
||||||
|
|
||||||
|
modeling.createShape(participantShape, { x: 350, y: 500 }, collaborationRoot);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(collaborationRoot.children).not.toContain(participantShape);
|
||||||
|
|
||||||
|
expect(participant.$parent).toBeFalsy();
|
||||||
|
expect(collaboration.participants).not.toContain(participant);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
97
test/spec/features/modeling/DeleteParticipantSpec.js
Normal file
97
test/spec/features/modeling/DeleteParticipantSpec.js
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TestHelper = require('../../../TestHelper');
|
||||||
|
|
||||||
|
/* global bootstrapModeler, inject */
|
||||||
|
|
||||||
|
|
||||||
|
var modelingModule = require('../../../../lib/features/modeling'),
|
||||||
|
coreModule = require('../../../../lib/core');
|
||||||
|
|
||||||
|
|
||||||
|
describe('features/modeling - delete participant', function() {
|
||||||
|
|
||||||
|
var testModules = [ coreModule, modelingModule ];
|
||||||
|
|
||||||
|
|
||||||
|
describe('last remaining', function() {
|
||||||
|
|
||||||
|
describe('should transform diagram into process diagram', function() {
|
||||||
|
|
||||||
|
var processDiagramXML = require('../../../fixtures/bpmn/collaboration/collaboration-empty-participant.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('execute', inject(function(modeling, elementRegistry, canvas) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var participantShape = elementRegistry.get('_Participant_2'),
|
||||||
|
participant = participantShape.businessObject,
|
||||||
|
participantDi = participant.di,
|
||||||
|
process = participant.processRef,
|
||||||
|
collaborationElement = participantShape.parent,
|
||||||
|
collaboration = collaborationElement.businessObject,
|
||||||
|
diPlane = collaboration.di,
|
||||||
|
bpmnDefinitions = collaboration.$parent;
|
||||||
|
|
||||||
|
// when
|
||||||
|
modeling.removeShape(participantShape);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participant.$parent).toBeFalsy();
|
||||||
|
|
||||||
|
var newRootShape = canvas.getRootElement(),
|
||||||
|
newRootBusinessObject = newRootShape.businessObject;
|
||||||
|
|
||||||
|
expect(newRootBusinessObject.$instanceOf('bpmn:Process')).toBe(true);
|
||||||
|
|
||||||
|
// collaboration DI is unwired
|
||||||
|
expect(participantDi.$parent).toBeFalsy();
|
||||||
|
expect(collaboration.di).toBeFalsy();
|
||||||
|
|
||||||
|
expect(bpmnDefinitions.rootElements).not.toContain(process);
|
||||||
|
expect(bpmnDefinitions.rootElements).not.toContain(collaboration);
|
||||||
|
|
||||||
|
// process DI is wired
|
||||||
|
expect(diPlane.bpmnElement).toBe(newRootBusinessObject);
|
||||||
|
expect(newRootBusinessObject.di).toBe(diPlane);
|
||||||
|
|
||||||
|
expect(bpmnDefinitions.rootElements).toContain(newRootBusinessObject);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('undo', inject(function(modeling, elementRegistry, canvas, commandStack) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var participantShape = elementRegistry.get('_Participant_2'),
|
||||||
|
participant = participantShape.businessObject,
|
||||||
|
originalRootElement = participantShape.parent,
|
||||||
|
originalRootElementBo = originalRootElement.businessObject,
|
||||||
|
bpmnDefinitions = originalRootElementBo.$parent,
|
||||||
|
participantDi = participant.di,
|
||||||
|
diPlane = participantDi.$parent;
|
||||||
|
|
||||||
|
modeling.removeShape(participantShape);
|
||||||
|
|
||||||
|
// when
|
||||||
|
commandStack.undo();
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(participant.$parent).toBe(originalRootElementBo);
|
||||||
|
expect(originalRootElementBo.$parent).toBe(bpmnDefinitions);
|
||||||
|
|
||||||
|
expect(canvas.getRootElement()).toBe(originalRootElement);
|
||||||
|
|
||||||
|
// di is unwired
|
||||||
|
expect(participantDi.$parent).toBe(originalRootElementBo.di);
|
||||||
|
|
||||||
|
// new di is wired
|
||||||
|
expect(diPlane.bpmnElement).toBe(originalRootElementBo);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -32,7 +32,7 @@ describe('palette', function() {
|
|||||||
var paletteElement = domQuery('.djs-palette', container);
|
var paletteElement = domQuery('.djs-palette', container);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(domQuery.all('.entry', paletteElement).length).toBe(7);
|
expect(domQuery.all('.entry', paletteElement).length).toBe(8);
|
||||||
|
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user