feat(features/modeling): implement bpmn update as command listeners
This commit adds * handling of bpmn update as command listeners * label support Related to bpmn-io/diagram-js#45 BREAKING CHANGE: * rename bpmnModeling -> modeling to achive parity with diagram-js
This commit is contained in:
parent
e1ed479314
commit
d729818b94
|
@ -2,23 +2,47 @@
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var hasExternalLabel = require('../util/Label').hasExternalLabel,
|
var LabelUtil = require('../util/Label');
|
||||||
|
|
||||||
|
var hasExternalLabel = LabelUtil.hasExternalLabel,
|
||||||
|
getExternalLabelBounds = LabelUtil.getExternalLabelBounds,
|
||||||
isExpanded = require('../util/Di').isExpanded;
|
isExpanded = require('../util/Di').isExpanded;
|
||||||
|
|
||||||
|
|
||||||
|
function elementData(semantic, attrs) {
|
||||||
|
return _.extend({
|
||||||
|
id: semantic.id,
|
||||||
|
type: semantic.$type,
|
||||||
|
businessObject: semantic
|
||||||
|
}, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectWaypoints(waypoints) {
|
||||||
|
return _.collect(waypoints, function(p) {
|
||||||
|
return { x: p.x, y: p.y };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An importer that adds bpmn elements to the canvas
|
* An importer that adds bpmn elements to the canvas
|
||||||
*
|
*
|
||||||
* @param {EventBus} eventBus
|
* @param {EventBus} eventBus
|
||||||
* @param {Canvas} canvas
|
* @param {Canvas} canvas
|
||||||
|
* @param {ElementFactory} elementFactory
|
||||||
|
* @param {ElementRegistry} elementRegistry
|
||||||
*/
|
*/
|
||||||
function BpmnImporter(eventBus, canvas, elementFactory) {
|
function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry) {
|
||||||
this._eventBus = eventBus;
|
this._eventBus = eventBus;
|
||||||
this._canvas = canvas;
|
this._canvas = canvas;
|
||||||
|
|
||||||
this._elementFactory = elementFactory;
|
this._elementFactory = elementFactory;
|
||||||
|
this._elementRegistry = elementRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
BpmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory' ];
|
BpmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory', 'elementRegistry' ];
|
||||||
|
|
||||||
|
module.exports = BpmnImporter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,12 +54,13 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
||||||
var di = semantic.di,
|
var di = semantic.di,
|
||||||
element;
|
element;
|
||||||
|
|
||||||
|
// ROOT ELEMENT
|
||||||
// handle the special case that we deal with a
|
// handle the special case that we deal with a
|
||||||
// invisible root element (process or collaboration)
|
// invisible root element (process or collaboration)
|
||||||
if (di.$instanceOf('bpmndi:BPMNPlane')) {
|
if (di.$instanceOf('bpmndi:BPMNPlane')) {
|
||||||
|
|
||||||
// add a virtual element (not being drawn)
|
// add a virtual element (not being drawn)
|
||||||
element = this._elementFactory.createRoot(semantic);
|
element = this._elementFactory.createRoot(elementData(semantic));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHAPE
|
// SHAPE
|
||||||
|
@ -44,18 +69,39 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
||||||
var collapsed = !isExpanded(semantic);
|
var collapsed = !isExpanded(semantic);
|
||||||
var hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
var hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
||||||
|
|
||||||
element = this._elementFactory.createShape(semantic, {
|
var bounds = semantic.di.bounds;
|
||||||
|
|
||||||
|
element = this._elementFactory.createShape(elementData(semantic, {
|
||||||
collapsed: collapsed,
|
collapsed: collapsed,
|
||||||
hidden: hidden
|
hidden: hidden,
|
||||||
});
|
x: bounds.x,
|
||||||
|
y: bounds.y,
|
||||||
|
width: bounds.width,
|
||||||
|
height: bounds.height
|
||||||
|
}));
|
||||||
|
|
||||||
this._canvas.addShape(element, parentElement);
|
this._canvas.addShape(element, parentElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONNECTION
|
// CONNECTION
|
||||||
else {
|
else if (di.$instanceOf('bpmndi:BPMNEdge')) {
|
||||||
element = this._elementFactory.createConnection(semantic, parentElement);
|
|
||||||
|
var source = this._getSource(semantic),
|
||||||
|
target = this._getTarget(semantic);
|
||||||
|
|
||||||
|
if (!source || !target) {
|
||||||
|
throw new Error('source or target not rendered for element <' + semantic.id + '>');
|
||||||
|
}
|
||||||
|
|
||||||
|
element = this._elementFactory.createConnection(elementData(semantic, {
|
||||||
|
source: source,
|
||||||
|
target: target,
|
||||||
|
waypoints: collectWaypoints(semantic.di.waypoint)
|
||||||
|
}));
|
||||||
|
|
||||||
this._canvas.addConnection(element, parentElement);
|
this._canvas.addConnection(element, parentElement);
|
||||||
|
} else {
|
||||||
|
throw new Error('unknown di <' + di.$type + '> for element <' + semantic.id + '>');
|
||||||
}
|
}
|
||||||
|
|
||||||
// (optional) LABEL
|
// (optional) LABEL
|
||||||
|
@ -73,9 +119,66 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
||||||
* add label for an element
|
* add label for an element
|
||||||
*/
|
*/
|
||||||
BpmnImporter.prototype.addLabel = function (semantic, element) {
|
BpmnImporter.prototype.addLabel = function (semantic, element) {
|
||||||
var label = this._elementFactory.createLabel(semantic, element);
|
var bounds = getExternalLabelBounds(semantic, element);
|
||||||
|
|
||||||
|
var label = this._elementFactory.createLabel(elementData(semantic, {
|
||||||
|
id: semantic.id + '_label',
|
||||||
|
labelTarget: element,
|
||||||
|
type: 'label',
|
||||||
|
hidden: element.hidden,
|
||||||
|
x: bounds.x,
|
||||||
|
y: bounds.y,
|
||||||
|
width: bounds.width,
|
||||||
|
height: bounds.height
|
||||||
|
}));
|
||||||
|
|
||||||
return this._canvas.addShape(label, element.parent);
|
return this._canvas.addShape(label, element.parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = BpmnImporter;
|
BpmnImporter.prototype._getSource = function(semantic) {
|
||||||
|
|
||||||
|
var element,
|
||||||
|
elementSemantic = semantic.sourceRef;
|
||||||
|
|
||||||
|
// handle mysterious isMany DataAssociation#sourceRef
|
||||||
|
if (_.isArray(elementSemantic)) {
|
||||||
|
elementSemantic = elementSemantic[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementSemantic && elementSemantic.$instanceOf('bpmn:DataOutput')) {
|
||||||
|
elementSemantic = elementSemantic.$parent.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = elementSemantic && this._getElement(elementSemantic);
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('element <' + elementSemantic.id + '> referenced by <' + semantic.id + '> not yet drawn');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnImporter.prototype._getTarget = function(semantic) {
|
||||||
|
|
||||||
|
var element,
|
||||||
|
elementSemantic = semantic.targetRef;
|
||||||
|
|
||||||
|
if (elementSemantic && elementSemantic.$instanceOf('bpmn:DataInput')) {
|
||||||
|
elementSemantic = elementSemantic.$parent.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = elementSemantic && this._getElement(elementSemantic);
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('element <' + elementSemantic.id + '> referenced by <' + semantic.id + '> not yet drawn');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnImporter.prototype._getElement = function(semantic) {
|
||||||
|
return this._elementRegistry.getById(semantic.id);
|
||||||
|
};
|
|
@ -1,78 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var _ = require('lodash');
|
|
||||||
|
|
||||||
|
|
||||||
var LabelUtil = require('../util/Label');
|
|
||||||
|
|
||||||
var getExternalLabelBounds = LabelUtil.getExternalLabelBounds;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A factory for diagram-js shapes
|
|
||||||
*
|
|
||||||
* @param {ElementFactory} canvas
|
|
||||||
*/
|
|
||||||
function ElementFactory(canvas) {
|
|
||||||
this._canvas = canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
ElementFactory.$inject = [ 'canvas' ];
|
|
||||||
|
|
||||||
module.exports = ElementFactory;
|
|
||||||
|
|
||||||
|
|
||||||
ElementFactory.prototype.createRoot = function(semantic) {
|
|
||||||
|
|
||||||
return this._canvas.create('root', _.extend({
|
|
||||||
id: semantic.id,
|
|
||||||
type: semantic.$type,
|
|
||||||
businessObject: semantic
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ElementFactory.prototype.createLabel = function(semantic, element) {
|
|
||||||
var labelBounds = getExternalLabelBounds(semantic, element);
|
|
||||||
|
|
||||||
var labelData = _.extend({
|
|
||||||
id: semantic.id + '_label',
|
|
||||||
labelTarget: element,
|
|
||||||
type: 'label',
|
|
||||||
hidden: element.hidden,
|
|
||||||
businessObject: semantic
|
|
||||||
}, labelBounds);
|
|
||||||
|
|
||||||
return this._canvas.create('label', labelData);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ElementFactory.prototype.createShape = function(semantic, attrs) {
|
|
||||||
var bounds = semantic.di.bounds;
|
|
||||||
|
|
||||||
var shapeData = _.extend({
|
|
||||||
id: semantic.id,
|
|
||||||
type: semantic.$type,
|
|
||||||
x: bounds.x,
|
|
||||||
y: bounds.y,
|
|
||||||
width: bounds.width,
|
|
||||||
height: bounds.height,
|
|
||||||
businessObject: semantic
|
|
||||||
}, attrs);
|
|
||||||
|
|
||||||
return this._canvas.create('shape', shapeData);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ElementFactory.prototype.createConnection = function(semantic) {
|
|
||||||
var waypoints = _.collect(semantic.di.waypoint, function(p) {
|
|
||||||
return { x: p.x, y: p.y };
|
|
||||||
});
|
|
||||||
|
|
||||||
return this._canvas.create('connection', {
|
|
||||||
id: semantic.id,
|
|
||||||
type: semantic.$type,
|
|
||||||
waypoints: waypoints,
|
|
||||||
businessObject: semantic
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,4 +1,3 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bpmnImporter: [ 'type', require('./BpmnImporter') ],
|
bpmnImporter: [ 'type', require('./BpmnImporter') ]
|
||||||
elementFactory: [ 'type', require('./ElementFactory') ]
|
|
||||||
};
|
};
|
|
@ -1020,7 +1020,7 @@ function BpmnRenderer(events, styles, pathMap) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var sequenceFlow = getSemantic(element);
|
var sequenceFlow = getSemantic(element);
|
||||||
var source = sequenceFlow.sourceRef;
|
var source = element.source.businessObject;
|
||||||
|
|
||||||
// conditional flow marker
|
// conditional flow marker
|
||||||
if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Task')) {
|
if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Task')) {
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var AppendFlowNodeHandler = require('./cmd/AppendFlowNodeHandler');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BPMN 2.0 modeling features activator
|
|
||||||
*
|
|
||||||
* @param {CommandStack} commandStack
|
|
||||||
*/
|
|
||||||
function BpmnModeling(commandStack) {
|
|
||||||
commandStack.registerHandler('shape.appendNode', AppendFlowNodeHandler);
|
|
||||||
this._commandStack = commandStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
BpmnModeling.$inject = [ 'commandStack' ];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append a flow node to the element with the given source
|
|
||||||
* at the specified position.
|
|
||||||
*/
|
|
||||||
BpmnModeling.prototype.appendFlowNode = function(source, parent, type, position) {
|
|
||||||
|
|
||||||
var context = {
|
|
||||||
source: source,
|
|
||||||
type: type,
|
|
||||||
parent: parent,
|
|
||||||
position: position
|
|
||||||
};
|
|
||||||
|
|
||||||
this._commandStack.execute('shape.appendNode', context);
|
|
||||||
|
|
||||||
return context.target;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = BpmnModeling;
|
|
|
@ -1,22 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var getMidPoint = module.exports.getMidPoint = function(bounds) {
|
|
||||||
return {
|
|
||||||
x: bounds.x + bounds.width / 2,
|
|
||||||
y: bounds.y + bounds.height / 2
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.getDirectConnectionPoints = function(boundsA, boundsB) {
|
|
||||||
return [
|
|
||||||
// workaround until we can compute the extend of an element
|
|
||||||
{
|
|
||||||
x: boundsA.x + boundsA.width,
|
|
||||||
y: boundsA.y + boundsA.height / 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: boundsB.x,
|
|
||||||
y: boundsB.y + boundsB.height / 2
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
|
@ -1,215 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var LayoutUtil = require('../LayoutUtil'),
|
|
||||||
Collections = require('diagram-js/lib/util/Collections');
|
|
||||||
|
|
||||||
var hasExternalLabel = require('../../../util/Label').hasExternalLabel;
|
|
||||||
|
|
||||||
var AppendShapeHandler = require('diagram-js/lib/features/modeling/cmd/AppendShapeHandler');
|
|
||||||
|
|
||||||
var Refs = require('object-refs');
|
|
||||||
|
|
||||||
var diRefs = new Refs({ name: 'bpmnElement', enumerable: true }, { name: 'di' });
|
|
||||||
|
|
||||||
|
|
||||||
function AppendFlowNodeHandler(canvas, bpmnFactory, bpmnImporter, elementFactory) {
|
|
||||||
AppendShapeHandler.call(this);
|
|
||||||
|
|
||||||
this._canvas = canvas;
|
|
||||||
|
|
||||||
this._bpmnFactory = bpmnFactory;
|
|
||||||
this._bpmnImporter = bpmnImporter;
|
|
||||||
this._elementFactory = elementFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.prototype = Object.create(AppendShapeHandler.prototype);
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.$inject = [ 'canvas', 'bpmnFactory', 'bpmnImporter', 'elementFactory' ];
|
|
||||||
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.prototype.createShape = function(source, position, parent, context) {
|
|
||||||
|
|
||||||
var bpmnFactory = this._bpmnFactory,
|
|
||||||
elementFactory = this._elementFactory,
|
|
||||||
canvas = this._canvas;
|
|
||||||
|
|
||||||
var sourceSemantic = source.businessObject,
|
|
||||||
parentSemantic = parent.businessObject;
|
|
||||||
|
|
||||||
var target = context.target,
|
|
||||||
targetSemantic,
|
|
||||||
targetDi;
|
|
||||||
|
|
||||||
// we need to create shape + bpmn elements
|
|
||||||
if (!target) {
|
|
||||||
// create semantic
|
|
||||||
targetSemantic = bpmnFactory.create(context.type);
|
|
||||||
|
|
||||||
// create di
|
|
||||||
targetDi = bpmnFactory.createDiShape(targetSemantic, position, {
|
|
||||||
id: targetSemantic.id + '_di'
|
|
||||||
});
|
|
||||||
|
|
||||||
// bind semantic -> di -> semantic
|
|
||||||
diRefs.bind(targetSemantic, 'di');
|
|
||||||
targetSemantic.di = targetDi;
|
|
||||||
|
|
||||||
// create node
|
|
||||||
target = elementFactory.createShape(targetSemantic);
|
|
||||||
|
|
||||||
// add label
|
|
||||||
if (hasExternalLabel(targetSemantic)) {
|
|
||||||
target.label = elementFactory.createLabel(targetSemantic, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load di + semantic from target
|
|
||||||
else {
|
|
||||||
targetSemantic = target.businessObject;
|
|
||||||
targetDi = targetSemantic.di;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reconnect everything
|
|
||||||
|
|
||||||
// wire semantic
|
|
||||||
parentSemantic.get('flowElements').push(targetSemantic);
|
|
||||||
targetSemantic.$parent = parentSemantic;
|
|
||||||
|
|
||||||
// wire di
|
|
||||||
sourceSemantic.di.$parent.get('planeElement').push(targetDi);
|
|
||||||
targetDi.$parent = sourceSemantic.di.$parent;
|
|
||||||
|
|
||||||
canvas.addShape(target, parent);
|
|
||||||
|
|
||||||
if (target.label) {
|
|
||||||
canvas.addShape(target.label, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.prototype.createConnection = function(source, target, parent, context) {
|
|
||||||
|
|
||||||
var bpmnFactory = this._bpmnFactory,
|
|
||||||
elementFactory = this._elementFactory,
|
|
||||||
canvas = this._canvas;
|
|
||||||
|
|
||||||
var sourceSemantic = source.businessObject,
|
|
||||||
targetSemantic = target.businessObject,
|
|
||||||
parentSemantic = parent.businessObject;
|
|
||||||
|
|
||||||
var connection = context.connection,
|
|
||||||
connectionSemantic,
|
|
||||||
connectionDi;
|
|
||||||
|
|
||||||
|
|
||||||
// we need to create connection + bpmn elements
|
|
||||||
if (!connection) {
|
|
||||||
|
|
||||||
// create semantic
|
|
||||||
connectionSemantic = bpmnFactory.create('bpmn:SequenceFlow');
|
|
||||||
|
|
||||||
// create di
|
|
||||||
var waypoints = LayoutUtil.getDirectConnectionPoints(sourceSemantic.di.bounds, targetSemantic.di.bounds);
|
|
||||||
|
|
||||||
connectionDi = bpmnFactory.createDiEdge(connectionSemantic, waypoints, {
|
|
||||||
id: connectionSemantic.id + '_di'
|
|
||||||
});
|
|
||||||
|
|
||||||
// bind semantic -> di -> semantic
|
|
||||||
diRefs.bind(connectionSemantic, 'di');
|
|
||||||
connectionSemantic.di = connectionDi;
|
|
||||||
|
|
||||||
// create connection
|
|
||||||
connection = elementFactory.createConnection(connectionSemantic);
|
|
||||||
|
|
||||||
// add label
|
|
||||||
if (hasExternalLabel(connectionSemantic)) {
|
|
||||||
connection.label = elementFactory.createLabel(connectionSemantic, connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load di + semantic from target
|
|
||||||
else {
|
|
||||||
connectionSemantic = connection.businessObject;
|
|
||||||
connectionDi = connectionSemantic.di;
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect
|
|
||||||
bpmnFactory.connectSequenceFlow(connectionSemantic, sourceSemantic, targetSemantic);
|
|
||||||
|
|
||||||
// TODO(nre): connect connection
|
|
||||||
|
|
||||||
// wire semantic
|
|
||||||
parentSemantic.get('flowElements').push(connectionSemantic);
|
|
||||||
connectionSemantic.$parent = parentSemantic;
|
|
||||||
|
|
||||||
// wire di
|
|
||||||
sourceSemantic.di.$parent.get('planeElement').push(connectionDi);
|
|
||||||
connectionDi.$parent = sourceSemantic.di.$parent;
|
|
||||||
|
|
||||||
canvas.addConnection(connection, parent);
|
|
||||||
|
|
||||||
if (connection.label) {
|
|
||||||
canvas.addShape(connection.label, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.prototype.removeShape = function(shape) {
|
|
||||||
|
|
||||||
var semantic = shape.businessObject,
|
|
||||||
di = semantic.di,
|
|
||||||
parentSemantic = semantic.$parent;
|
|
||||||
|
|
||||||
// undo wire semantic
|
|
||||||
parentSemantic.get('flowElements').splice(parentSemantic.get('flowElements').indexOf(semantic), 1);
|
|
||||||
semantic.$parent = null;
|
|
||||||
|
|
||||||
// undo wire di
|
|
||||||
di.$parent.get('planeElement').splice(di.$parent.get('planeElement').indexOf(di), 1);
|
|
||||||
di.$parent = null;
|
|
||||||
|
|
||||||
// remove label
|
|
||||||
if (shape.label) {
|
|
||||||
this._canvas.removeShape(shape.label);
|
|
||||||
}
|
|
||||||
|
|
||||||
// actual remove shape
|
|
||||||
return this._canvas.removeShape(shape);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AppendFlowNodeHandler.prototype.removeConnection = function(connection) {
|
|
||||||
|
|
||||||
var semantic = connection.businessObject,
|
|
||||||
di = semantic.di,
|
|
||||||
parentSemantic = semantic.$parent;
|
|
||||||
|
|
||||||
// undo wire semantic
|
|
||||||
Collections.remove(parentSemantic.get('flowElements'), semantic);
|
|
||||||
semantic.$parent = null;
|
|
||||||
|
|
||||||
// undo wire di
|
|
||||||
Collections.remove(di.$parent.get('planeElement'), di);
|
|
||||||
di.$parent = null;
|
|
||||||
|
|
||||||
// undo wire refs
|
|
||||||
this._bpmnFactory.disconnectSequenceFlow(semantic);
|
|
||||||
|
|
||||||
// TODO(nre): disconnect connection
|
|
||||||
|
|
||||||
|
|
||||||
// remove label
|
|
||||||
if (connection.label) {
|
|
||||||
this._canvas.removeShape(connection.label);
|
|
||||||
}
|
|
||||||
|
|
||||||
// actual remove connection
|
|
||||||
return this._canvas.removeConnection(connection);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = AppendFlowNodeHandler;
|
|
|
@ -1,9 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
__init__: [ 'bpmnModeling' ],
|
|
||||||
__depends__: [
|
|
||||||
require('../../core'),
|
|
||||||
require('diagram-js/lib/cmd')
|
|
||||||
],
|
|
||||||
bpmnFactory: [ 'type', require('./BpmnFactory') ],
|
|
||||||
bpmnModeling: [ 'type', require('./BpmnModeling') ]
|
|
||||||
};
|
|
|
@ -20,22 +20,22 @@ var images = {
|
||||||
*
|
*
|
||||||
* @param {ContextPad} contextPad
|
* @param {ContextPad} contextPad
|
||||||
*/
|
*/
|
||||||
function ContextPadProvider(contextPad, directEditing, bpmnModeling, selection) {
|
function ContextPadProvider(contextPad, directEditing, modeling, selection) {
|
||||||
|
|
||||||
contextPad.registerProvider(this);
|
contextPad.registerProvider(this);
|
||||||
|
|
||||||
this._selection = selection;
|
this._selection = selection;
|
||||||
this._directEditing = directEditing;
|
this._directEditing = directEditing;
|
||||||
this._bpmnModeling = bpmnModeling;
|
this._modeling = modeling;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextPadProvider.$inject = [ 'contextPad', 'directEditing', 'bpmnModeling', 'selection' ];
|
ContextPadProvider.$inject = [ 'contextPad', 'directEditing', 'modeling', 'selection' ];
|
||||||
|
|
||||||
|
|
||||||
ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||||
|
|
||||||
var directEditing = this._directEditing,
|
var directEditing = this._directEditing,
|
||||||
bpmnModeling = this._bpmnModeling,
|
modeling = this._modeling,
|
||||||
selection = this._selection;
|
selection = this._selection;
|
||||||
|
|
||||||
var actions = {};
|
var actions = {};
|
||||||
|
@ -47,7 +47,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||||
var bpmnElement = element.businessObject;
|
var bpmnElement = element.businessObject;
|
||||||
|
|
||||||
function append(element, type) {
|
function append(element, type) {
|
||||||
var target = bpmnModeling.appendFlowNode(element, null, type);
|
var target = modeling.appendFlowNode(element, type);
|
||||||
|
|
||||||
selection.select(target);
|
selection.select(target);
|
||||||
directEditing.activate(target);
|
directEditing.activate(target);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
__depends__: [
|
__depends__: [
|
||||||
|
require('diagram-js-direct-editing'),
|
||||||
require('diagram-js/lib/features/context-pad'),
|
require('diagram-js/lib/features/context-pad'),
|
||||||
require('diagram-js/lib/features/selection'),
|
require('diagram-js/lib/features/selection'),
|
||||||
require('diagram-js-direct-editing'),
|
require('../modeling')
|
||||||
require('../bpmn-modeling')
|
|
||||||
],
|
],
|
||||||
__init__: [ 'contextPadProvider' ],
|
__init__: [ 'contextPadProvider' ],
|
||||||
contextPadProvider: [ 'type', require('./ContextPadProvider') ]
|
contextPadProvider: [ 'type', require('./ContextPadProvider') ]
|
||||||
|
|
|
@ -2,6 +2,7 @@ module.exports = {
|
||||||
__depends__: [
|
__depends__: [
|
||||||
require('../../core'),
|
require('../../core'),
|
||||||
require('diagram-js/lib/cmd'),
|
require('diagram-js/lib/cmd'),
|
||||||
|
require('diagram-js/lib/features/change-support'),
|
||||||
require('diagram-js-direct-editing')
|
require('diagram-js-direct-editing')
|
||||||
],
|
],
|
||||||
__init__: [ 'labelEditingProvider' ],
|
__init__: [ 'labelEditingProvider' ],
|
||||||
|
|
|
@ -41,22 +41,7 @@ BpmnFactory.prototype.create = function(type, attrs) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BpmnFactory.prototype.createDiShape = function(semantic, position, attrs) {
|
BpmnFactory.prototype.createDiShape = function(semantic, bounds, attrs) {
|
||||||
|
|
||||||
position = position || { x: 0, y: 0 };
|
|
||||||
|
|
||||||
var bounds;
|
|
||||||
|
|
||||||
if (semantic.$instanceOf('bpmn:Task')) {
|
|
||||||
bounds = { width: 100, height: 80 };
|
|
||||||
} else {
|
|
||||||
bounds = { width: 36, height: 36 };
|
|
||||||
}
|
|
||||||
|
|
||||||
_.extend(bounds, {
|
|
||||||
x: (position.x || 0) - bounds.width / 2,
|
|
||||||
y: (position.y || 0) - bounds.height / 2
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.create('bpmndi:BPMNShape', _.extend({
|
return this.create('bpmndi:BPMNShape', _.extend({
|
||||||
bpmnElement: semantic,
|
bpmnElement: semantic,
|
||||||
|
@ -70,45 +55,22 @@ BpmnFactory.prototype.createDiBounds = function(bounds) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnFactory.prototype.createDiWaypoints = function(waypoints) {
|
||||||
|
return _.map(waypoints, function(pos) {
|
||||||
|
return this.createDiWaypoint(pos);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
BpmnFactory.prototype.createDiWaypoint = function(point) {
|
BpmnFactory.prototype.createDiWaypoint = function(point) {
|
||||||
return this.create('dc:Point', point);
|
return this.create('dc:Point', point);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BpmnFactory.prototype.createDiEdge = function(sequenceFlow, points, attrs) {
|
BpmnFactory.prototype.createDiEdge = function(semantic, waypoints, attrs) {
|
||||||
|
|
||||||
var waypoints = _.map(points, function(pos) {
|
|
||||||
return this.createDiWaypoint(pos);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return this.create('bpmndi:BPMNEdge', _.extend({
|
return this.create('bpmndi:BPMNEdge', _.extend({
|
||||||
bpmnElement: sequenceFlow,
|
bpmnElement: semantic
|
||||||
waypoint: waypoints
|
|
||||||
}, attrs));
|
}, attrs));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BpmnFactory.prototype.disconnectSequenceFlow = function(sequenceFlow) {
|
|
||||||
Collections.remove(sequenceFlow.sourceRef && sequenceFlow.sourceRef.get('outgoing'), sequenceFlow);
|
|
||||||
Collections.remove(sequenceFlow.targetRef && sequenceFlow.targetRef.get('incoming'), sequenceFlow);
|
|
||||||
|
|
||||||
_.extend(sequenceFlow, {
|
|
||||||
sourceRef: null,
|
|
||||||
targetRef: null
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
BpmnFactory.prototype.connectSequenceFlow = function(sequenceFlow, source, target) {
|
|
||||||
|
|
||||||
_.extend(sequenceFlow, {
|
|
||||||
sourceRef: source,
|
|
||||||
targetRef: target
|
|
||||||
});
|
|
||||||
|
|
||||||
source.get('outgoing').push(sequenceFlow);
|
|
||||||
target.get('incoming').push(sequenceFlow);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = BpmnFactory;
|
module.exports = BpmnFactory;
|
|
@ -0,0 +1,181 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var Collections = require('diagram-js/lib/util/Collections');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler responsible for updating the underlying BPMN 2.0 XML + DI
|
||||||
|
* once changes on the diagram happen
|
||||||
|
*/
|
||||||
|
function BpmnUpdater(eventBus, bpmnFactory) {
|
||||||
|
|
||||||
|
this._eventBus = eventBus;
|
||||||
|
this._bpmnFactory = bpmnFactory;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.executed('shape.create', function(e) {
|
||||||
|
self.createShapeDi(e.context.shape);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.executed('connection.create', function(e) {
|
||||||
|
self.createConnectionDi(e.context.connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function updateShapeParent(e) {
|
||||||
|
self.updateShapeParent(e.context.shape || e.context.connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.executed([ 'shape.move', 'shape.create', 'connection.create' ], updateShapeParent);
|
||||||
|
this.reverted([ 'shape.move', 'shape.create', 'connection.create' ], updateShapeParent);
|
||||||
|
|
||||||
|
|
||||||
|
function updateConnection(e) {
|
||||||
|
self.updateConnection(e.context.connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.executed([ 'connection.create' ], updateConnection);
|
||||||
|
this.reverted([ 'connection.create' ], updateConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BpmnUpdater;
|
||||||
|
|
||||||
|
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory' ];
|
||||||
|
|
||||||
|
|
||||||
|
/////// implementation //////////////////////////////////
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.createShapeDi = function(shape) {
|
||||||
|
|
||||||
|
var businessObject = shape.businessObject;
|
||||||
|
if (!businessObject.di) {
|
||||||
|
businessObject.di = this._bpmnFactory.createDiShape(businessObject, shape, {
|
||||||
|
id: businessObject.id + '_di'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.createConnectionDi = function(connection) {
|
||||||
|
var businessObject = connection.businessObject;
|
||||||
|
if (!businessObject.di) {
|
||||||
|
businessObject.di = this._bpmnFactory.createDiEdge(businessObject, connection.waypoints, {
|
||||||
|
id: businessObject.id + '_di'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.updateShapeParent = function(shape) {
|
||||||
|
var parentShape = shape.parent;
|
||||||
|
|
||||||
|
var businessObject = shape.businessObject,
|
||||||
|
parentBusinessObject = parentShape && parentShape.businessObject,
|
||||||
|
parentDi = parentBusinessObject && parentBusinessObject.di;
|
||||||
|
|
||||||
|
this.updateSemanticParent(businessObject, parentBusinessObject);
|
||||||
|
|
||||||
|
this.updateDiParent(businessObject.di, parentDi);
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
|
||||||
|
|
||||||
|
if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
|
||||||
|
parentDi = parentDi.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (di.$parent === parentDi) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var planeElements = (parentDi || di.$parent).get('planeElement');
|
||||||
|
|
||||||
|
if (parentDi) {
|
||||||
|
planeElements.push(di);
|
||||||
|
di.$parent = parentDi;
|
||||||
|
} else {
|
||||||
|
Collections.remove(planeElements, di);
|
||||||
|
di.$parent = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
|
||||||
|
|
||||||
|
if (businessObject.$parent === newParent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var children;
|
||||||
|
|
||||||
|
if (businessObject.$parent) {
|
||||||
|
// remove from old parent
|
||||||
|
children = businessObject.$parent.get('flowElements');
|
||||||
|
Collections.remove(children, businessObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newParent) {
|
||||||
|
businessObject.$parent = null;
|
||||||
|
} else {
|
||||||
|
// add to new parent
|
||||||
|
children = newParent.get('flowElements');
|
||||||
|
children.push(businessObject);
|
||||||
|
businessObject.$parent = newParent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.updateConnection = function(connection) {
|
||||||
|
|
||||||
|
var businessObject = connection.businessObject,
|
||||||
|
newSource = connection.source && connection.source.businessObject,
|
||||||
|
newTarget = connection.target && connection.target.businessObject;
|
||||||
|
|
||||||
|
if (businessObject.sourceRef !== newSource) {
|
||||||
|
Collections.remove(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject);
|
||||||
|
|
||||||
|
if (newSource) {
|
||||||
|
newSource.get('outgoing').push(businessObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
businessObject.sourceRef = newSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (businessObject.targetRef !== newTarget) {
|
||||||
|
Collections.remove(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject);
|
||||||
|
|
||||||
|
if (newTarget) {
|
||||||
|
newTarget.get('incoming').push(businessObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
businessObject.targetRef = newTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/////// helpers /////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.pre = function(commands, callback) {
|
||||||
|
this.on(commands, 'preExecute', callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.executed = function(commands, callback) {
|
||||||
|
this.on(commands, 'executed', callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.reverted = function(commands, callback) {
|
||||||
|
this.on(commands, 'reverted', callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnUpdater.prototype.on = function(commands, suffix, callback) {
|
||||||
|
|
||||||
|
commands = _.isArray(commands) ? commands : [ commands ];
|
||||||
|
|
||||||
|
_.forEach(commands, function(c) {
|
||||||
|
this._eventBus.on('commandStack.' + c + '.' + suffix, callback);
|
||||||
|
}, this);
|
||||||
|
};
|
|
@ -0,0 +1,58 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var BaseElementFactory = require('diagram-js/lib/core/ElementFactory');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bpmn-aware factory for diagram-js shapes
|
||||||
|
*/
|
||||||
|
function ElementFactory(bpmnFactory) {
|
||||||
|
BaseElementFactory.call(this);
|
||||||
|
|
||||||
|
this._bpmnFactory = bpmnFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementFactory.prototype = Object.create(BaseElementFactory.prototype);
|
||||||
|
|
||||||
|
module.exports = ElementFactory;
|
||||||
|
|
||||||
|
|
||||||
|
ElementFactory.prototype.createWithBpmn = function(elementType, attrs) {
|
||||||
|
|
||||||
|
attrs = attrs || {};
|
||||||
|
|
||||||
|
var businessObject = attrs.businessObject;
|
||||||
|
|
||||||
|
if (!businessObject) {
|
||||||
|
if (!attrs.type) {
|
||||||
|
throw new Error('no shape type specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
businessObject = this._bpmnFactory.create(attrs.type);
|
||||||
|
|
||||||
|
_.extend(attrs, {
|
||||||
|
businessObject: businessObject,
|
||||||
|
id: businessObject.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.create(elementType, attrs);
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementFactory.prototype.createRoot = function(attrs) {
|
||||||
|
return this.createWithBpmn('root', attrs);
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementFactory.prototype.createLabel = function(attrs) {
|
||||||
|
return this.create('label', _.extend({ type: 'label' }, attrs));
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementFactory.prototype.createShape = function(attrs) {
|
||||||
|
return this.createWithBpmn('shape', attrs);
|
||||||
|
};
|
||||||
|
|
||||||
|
ElementFactory.prototype.createConnection = function(attrs) {
|
||||||
|
return this.createWithBpmn('connection', attrs);
|
||||||
|
};
|
|
@ -0,0 +1,59 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var LabelUtil = require('../../util/Label');
|
||||||
|
|
||||||
|
var hasExternalLabel = LabelUtil.hasExternalLabel,
|
||||||
|
getExternalLabelMid = LabelUtil.getExternalLabelMid;
|
||||||
|
|
||||||
|
|
||||||
|
function LabelSupport(eventBus, modeling, bpmnFactory) {
|
||||||
|
|
||||||
|
eventBus.on([
|
||||||
|
'commandStack.shape.create.postExecute',
|
||||||
|
'commandStack.connection.create.postExecute'
|
||||||
|
], function(e) {
|
||||||
|
var context = e.context;
|
||||||
|
|
||||||
|
var element = context.shape || context.connection,
|
||||||
|
businessObject = element.businessObject;
|
||||||
|
|
||||||
|
var position;
|
||||||
|
|
||||||
|
if (hasExternalLabel(businessObject)) {
|
||||||
|
position = getExternalLabelMid(element);
|
||||||
|
modeling.createLabel(element, position, {
|
||||||
|
id: businessObject.id + '_label',
|
||||||
|
businessObject: businessObject
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
eventBus.on([
|
||||||
|
'commandStack.label.create.executed',
|
||||||
|
'commandStack.label.moved.executed'
|
||||||
|
], function(e) {
|
||||||
|
|
||||||
|
var element = e.context.shape,
|
||||||
|
businessObject = element.businessObject,
|
||||||
|
di = businessObject.di;
|
||||||
|
|
||||||
|
if (!di.label) {
|
||||||
|
di.label = bpmnFactory.create('bpmndi:BPMNLabel', {
|
||||||
|
bounds: bpmnFactory.create('dc:Bounds')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_.extend(di.label.bounds, {
|
||||||
|
x: element.x,
|
||||||
|
y: element.y,
|
||||||
|
width: element.width,
|
||||||
|
height: element.height
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelSupport.$inject = [ 'eventBus', 'modeling', 'bpmnFactory' ];
|
||||||
|
|
||||||
|
module.exports = LabelSupport;
|
|
@ -0,0 +1,50 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
|
||||||
|
|
||||||
|
var AppendShapeHandler = require('./cmd/AppendShapeHandler'),
|
||||||
|
CreateShapeHandler = require('diagram-js/lib/features/modeling/cmd/CreateShapeHandler'),
|
||||||
|
CreateConnectionHandler = require('diagram-js/lib/features/modeling/cmd/CreateConnectionHandler'),
|
||||||
|
CreateLabelHandler = require('diagram-js/lib/features/modeling/cmd/CreateLabelHandler');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN 2.0 modeling features activator
|
||||||
|
*
|
||||||
|
* @param {EventBus} eventBus
|
||||||
|
* @param {CommandStack} commandStack
|
||||||
|
*/
|
||||||
|
function Modeling(eventBus, commandStack) {
|
||||||
|
BaseModeling.call(this, eventBus, commandStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
Modeling.prototype = Object.create(BaseModeling.prototype);
|
||||||
|
|
||||||
|
Modeling.$inject = [ 'eventBus', 'commandStack' ];
|
||||||
|
|
||||||
|
module.exports = Modeling;
|
||||||
|
|
||||||
|
|
||||||
|
Modeling.prototype.registerHandlers = function(commandStack) {
|
||||||
|
commandStack.registerHandler('shape.appendShape', AppendShapeHandler);
|
||||||
|
commandStack.registerHandler('shape.create', CreateShapeHandler);
|
||||||
|
commandStack.registerHandler('connection.create', CreateConnectionHandler);
|
||||||
|
commandStack.registerHandler('label.create', CreateLabelHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a flow node to the element with the given source
|
||||||
|
* at the specified position.
|
||||||
|
*/
|
||||||
|
Modeling.prototype.appendFlowNode = function(source, type, position) {
|
||||||
|
|
||||||
|
position = position || {
|
||||||
|
x: source.x + source.width + 100,
|
||||||
|
y: source.y + source.height / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.appendShape(source, { type: type }, position);
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var BaseAppendShapeHandler = require('diagram-js/lib/features/modeling/cmd/AppendShapeHandler');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bpmn-aware append shape handler
|
||||||
|
*
|
||||||
|
* @param {canvas} Canvas
|
||||||
|
* @param {elementFactory} ElementFactory
|
||||||
|
* @param {modeling} Modeling
|
||||||
|
*/
|
||||||
|
function AppendShapeHandler(modeling) {
|
||||||
|
this._modeling = modeling;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppendShapeHandler.prototype = Object.create(BaseAppendShapeHandler.prototype);
|
||||||
|
|
||||||
|
module.exports = AppendShapeHandler;
|
||||||
|
|
||||||
|
AppendShapeHandler.$inject = [ 'modeling' ];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AppendShapeHandler.prototype.postExecute = function(context) {
|
||||||
|
this._modeling.createConnection(context.source, context.shape, {
|
||||||
|
type: 'bpmn:SequenceFlow',
|
||||||
|
}, context.source.parent);
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
__init__: [ 'modeling', 'bpmnUpdater', 'labelSupport' ],
|
||||||
|
__depends__: [
|
||||||
|
require('../../core'),
|
||||||
|
require('diagram-js/lib/cmd'),
|
||||||
|
require('diagram-js/lib/features/change-support')
|
||||||
|
],
|
||||||
|
bpmnFactory: [ 'type', require('./BpmnFactory') ],
|
||||||
|
bpmnUpdater: [ 'type', require('./BpmnUpdater') ],
|
||||||
|
elementFactory: [ 'type', require('./ElementFactory') ],
|
||||||
|
modeling: [ 'type', require('./Modeling') ],
|
||||||
|
labelSupport: [ 'type', require('./LabelSupport') ],
|
||||||
|
layouter: [ 'type', require('diagram-js/lib/features/modeling/Layouter') ]
|
||||||
|
};
|
|
@ -26,7 +26,7 @@ module.exports.hasExternalLabel = function(semantic) {
|
||||||
* @param {Array<Point>} waypoints
|
* @param {Array<Point>} waypoints
|
||||||
* @return {Point} the mid point
|
* @return {Point} the mid point
|
||||||
*/
|
*/
|
||||||
module.exports.getWaypointsMid = function(waypoints) {
|
var getWaypointsMid = module.exports.getWaypointsMid = function(waypoints) {
|
||||||
|
|
||||||
var mid = waypoints.length / 2 - 1;
|
var mid = waypoints.length / 2 - 1;
|
||||||
|
|
||||||
|
@ -40,6 +40,18 @@ module.exports.getWaypointsMid = function(waypoints) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var getExternalLabelMid = module.exports.getExternalLabelMid = function(element) {
|
||||||
|
|
||||||
|
if (element.waypoints) {
|
||||||
|
return getWaypointsMid(element.waypoints);
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
x: element.x + element.width / 2,
|
||||||
|
y: element.y + element.height - 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the bounds of an elements label, parsed from the elements DI or
|
* Returns the bounds of an elements label, parsed from the elements DI or
|
||||||
* generated from its bounds.
|
* generated from its bounds.
|
||||||
|
@ -69,14 +81,7 @@ module.exports.getExternalLabelBounds = function(semantic, element) {
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (element.waypoints) {
|
mid = getExternalLabelMid(element);
|
||||||
mid = module.exports.getWaypointsMid(element.waypoints);
|
|
||||||
} else {
|
|
||||||
mid = {
|
|
||||||
x: element.x + element.width / 2,
|
|
||||||
y: element.y + element.height - 5
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
size = {
|
size = {
|
||||||
width: 90,
|
width: 90,
|
||||||
|
|
|
@ -8,7 +8,7 @@ var Matchers = require('../../../Matchers'),
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var bpmnFactoryModule = require('../../../../../lib/features/bpmn-modeling');
|
var modelingModule = require('../../../../../lib/features/modeling');
|
||||||
|
|
||||||
|
|
||||||
xdescribe('features - bpmn-factory', function() {
|
xdescribe('features - bpmn-factory', function() {
|
||||||
|
@ -18,7 +18,7 @@ xdescribe('features - bpmn-factory', function() {
|
||||||
|
|
||||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||||
|
|
||||||
var testModules = [ bpmnFactoryModule ];
|
var testModules = [ modelingModule ];
|
||||||
|
|
||||||
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||||
|
|
|
@ -9,8 +9,8 @@ var _ = require('lodash');
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var bpmnFactoryModule = require('../../../../../lib/features/bpmn-modeling'),
|
var modelingModule = require('../../../../../lib/features/modeling'),
|
||||||
bpmnDrawModule = require('../../../../../lib/draw');
|
drawModule = require('../../../../../lib/draw');
|
||||||
|
|
||||||
|
|
||||||
describe('features - bpmn-modeling', function() {
|
describe('features - bpmn-modeling', function() {
|
||||||
|
@ -20,7 +20,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
|
|
||||||
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
var diagramXML = fs.readFileSync('test/fixtures/bpmn/simple.bpmn', 'utf-8');
|
||||||
|
|
||||||
var testModules = [ bpmnFactoryModule, bpmnDrawModule ];
|
var testModules = [ modelingModule, drawModule ];
|
||||||
|
|
||||||
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
beforeEach(bootstrapBpmnJS(diagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ describe('features - bpmn-modeling', function() {
|
||||||
|
|
||||||
describe('shape.appendNode', function() {
|
describe('shape.appendNode', function() {
|
||||||
|
|
||||||
it('should execute', inject(function(elementRegistry, bpmnModeling) {
|
it('should execute', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -44,13 +44,13 @@ describe('features - bpmn-modeling', function() {
|
||||||
expect(target.$instanceOf('bpmn:Task')).toBe(true);
|
expect(target.$instanceOf('bpmn:Task')).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should execute', inject(function(elementRegistry, bpmnModeling) {
|
it('should execute', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -58,7 +58,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
expect(target.$instanceOf('bpmn:ExclusiveGateway')).toBe(true);
|
expect(target.$instanceOf('bpmn:ExclusiveGateway')).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should create DI', inject(function(elementRegistry, bpmnModeling) {
|
it('should create DI', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -68,7 +68,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -77,7 +77,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should add to parent (sub process)', inject(function(elementRegistry, bpmnModeling) {
|
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -87,14 +87,14 @@ describe('features - bpmn-modeling', function() {
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(subProcess.get('flowElements')).toContain(target);
|
expect(subProcess.get('flowElements')).toContain(target);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should add to parent (sub process)', inject(function(elementRegistry, bpmnModeling) {
|
it('should add to parent (sub process)', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -104,7 +104,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -112,7 +112,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should add connection', inject(function(elementRegistry, bpmnModeling) {
|
it('should add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -122,7 +122,33 @@ describe('features - bpmn-modeling', function() {
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
||||||
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(targetShape.label).toBeDefined();
|
||||||
|
expect(elementRegistry.getById(targetShape.label.id)).toBeDefined();
|
||||||
|
|
||||||
|
expect(target.di.label).toBeDefined();
|
||||||
|
|
||||||
|
expect(target.di.label.bounds.x).toBe(targetShape.label.x);
|
||||||
|
expect(target.di.label.bounds.y).toBe(targetShape.label.y);
|
||||||
|
expect(target.di.label.bounds.width).toBe(targetShape.label.width);
|
||||||
|
expect(target.di.label.bounds.height).toBe(targetShape.label.height);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add connection', inject(function(elementRegistry, modeling) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
var subProcessShape = elementRegistry.getById('SubProcess_1');
|
||||||
|
|
||||||
|
var startEvent = startEventShape.businessObject,
|
||||||
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
|
// when
|
||||||
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
@ -137,7 +163,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
|
|
||||||
describe('undo support', function() {
|
describe('undo support', function() {
|
||||||
|
|
||||||
it('should undo add to parent', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should undo add to parent', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -146,7 +172,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
@ -158,7 +184,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should undo add shape label', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should undo add shape label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -167,7 +193,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:EndEvent'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:EndEvent'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
@ -183,11 +209,12 @@ describe('features - bpmn-modeling', function() {
|
||||||
expect(connection.$parent).toBe(null);
|
expect(connection.$parent).toBe(null);
|
||||||
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
expect(subProcess.di.$parent.get('planeElement')).not.toContain(connection.di);
|
||||||
|
|
||||||
expect(elementRegistry.getById(targetShape.label.id)).not.toBeDefined();
|
expect(targetShape.label).not.toBeDefined();
|
||||||
|
expect(elementRegistry.getById(target.id + '_label')).not.toBeDefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should undo add connection', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should undo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -196,7 +223,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
@ -220,7 +247,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should undo add connection label', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should undo add connection label', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -229,7 +256,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
||||||
|
@ -248,7 +275,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
expect(elementRegistry.getById(connection.id + '_label')).not.toBeDefined();
|
expect(elementRegistry.getById(connection.id + '_label')).not.toBeDefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should undo add to parent', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should undo add to parent', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -257,7 +284,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
var targetShape = modeling.appendFlowNode(startEventShape, null, 'bpmn:ExclusiveGateway'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
@ -269,7 +296,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should undo/redo appending multiple shapes', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should redo appending multiple shapes', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -278,10 +305,10 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var targetShape2 = bpmnModeling.appendFlowNode(targetShape, null, 'bpmn:UserTask');
|
var targetShape2 = modeling.appendFlowNode(targetShape, 'bpmn:UserTask');
|
||||||
|
|
||||||
// when
|
// when
|
||||||
commandStack.undo();
|
commandStack.undo();
|
||||||
|
@ -303,7 +330,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should undo/redo add connection', inject(function(elementRegistry, bpmnModeling, commandStack) {
|
it('should redo add connection', inject(function(elementRegistry, modeling, commandStack) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
var startEventShape = elementRegistry.getById('StartEvent_1');
|
var startEventShape = elementRegistry.getById('StartEvent_1');
|
||||||
|
@ -312,7 +339,7 @@ describe('features - bpmn-modeling', function() {
|
||||||
var startEvent = startEventShape.businessObject,
|
var startEvent = startEventShape.businessObject,
|
||||||
subProcess = subProcessShape.businessObject;
|
subProcess = subProcessShape.businessObject;
|
||||||
|
|
||||||
var targetShape = bpmnModeling.appendFlowNode(startEventShape, null, 'bpmn:Task'),
|
var targetShape = modeling.appendFlowNode(startEventShape, 'bpmn:Task'),
|
||||||
target = targetShape.businessObject;
|
target = targetShape.businessObject;
|
||||||
|
|
||||||
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
var connection = _.find(subProcess.get('flowElements'), function(e) {
|
Loading…
Reference in New Issue