mirror of
https://github.com/sartography/bpmn-js.git
synced 2025-01-22 23:08:49 +00:00
feat(create): create multiple elements
* add <elements.create> rule for creating multiple elements * handle creating multiple elements in CreateParticipantBehavior * create sub process with start event through palette
This commit is contained in:
parent
1f706fd9b8
commit
14bf3a32ee
@ -158,7 +158,9 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||
function appendStart(event, element) {
|
||||
|
||||
var shape = elementFactory.createShape(assign({ type: type }, options));
|
||||
create.start(event, shape, element);
|
||||
create.start(event, shape, {
|
||||
source: element
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
assign,
|
||||
forEach
|
||||
forEach,
|
||||
isObject
|
||||
} from 'min-dash';
|
||||
|
||||
import inherits from 'inherits';
|
||||
@ -164,10 +165,10 @@ ElementFactory.prototype._getDefaultSize = function(semantic) {
|
||||
}
|
||||
|
||||
if (is(semantic, 'bpmn:Participant')) {
|
||||
if (!isExpanded(semantic)) {
|
||||
return { width: 400, height: 60 };
|
||||
} else {
|
||||
if (isExpanded(semantic)) {
|
||||
return { width: 600, height: 250 };
|
||||
} else {
|
||||
return { width: 400, height: 60 };
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,11 +196,23 @@ ElementFactory.prototype._getDefaultSize = function(semantic) {
|
||||
};
|
||||
|
||||
|
||||
ElementFactory.prototype.createParticipantShape = function(collapsed) {
|
||||
/**
|
||||
* Create participant.
|
||||
*
|
||||
* @param {boolean|Object} [attrs] attrs
|
||||
*
|
||||
* @returns {djs.model.Shape}
|
||||
*/
|
||||
ElementFactory.prototype.createParticipantShape = function(attrs) {
|
||||
|
||||
var attrs = { type: 'bpmn:Participant' };
|
||||
if (!isObject(attrs)) {
|
||||
attrs = { isExpanded: attrs };
|
||||
}
|
||||
|
||||
if (!collapsed) {
|
||||
attrs = assign({ type: 'bpmn:Participant' }, attrs || {});
|
||||
|
||||
// participants are expanded by default
|
||||
if (attrs.isExpanded !== false) {
|
||||
attrs.processRef = this._bpmnFactory.create('bpmn:Process');
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,10 @@ import { isLabel } from '../../../util/LabelUtil';
|
||||
|
||||
import { getBBox } from 'diagram-js/lib/util/Elements';
|
||||
|
||||
import { assign } from 'min-dash';
|
||||
import {
|
||||
assign,
|
||||
find
|
||||
} from 'min-dash';
|
||||
|
||||
import { asTRBL } from 'diagram-js/lib/layout/LayoutUtil';
|
||||
|
||||
@ -85,71 +88,122 @@ export default function CreateParticipantBehavior(canvas, eventBus, modeling) {
|
||||
}
|
||||
});
|
||||
|
||||
// turn process into collaboration before adding participant
|
||||
this.preExecute('shape.create', function(context) {
|
||||
function ensureCollaboration(context) {
|
||||
var parent = context.parent,
|
||||
shape = context.shape,
|
||||
position = context.position;
|
||||
collaboration;
|
||||
|
||||
var rootElement = canvas.getRootElement();
|
||||
|
||||
if (
|
||||
is(parent, 'bpmn:Process') &&
|
||||
is(shape, 'bpmn:Participant') &&
|
||||
!is(rootElement, 'bpmn:Collaboration')
|
||||
) {
|
||||
if (is(rootElement, 'bpmn:Collaboration')) {
|
||||
collaboration = rootElement;
|
||||
} else {
|
||||
|
||||
// this is going to detach the process root
|
||||
// and set the returned collaboration element
|
||||
// as the new root element
|
||||
var collaborationElement = modeling.makeCollaboration();
|
||||
// update root element by making collaboration
|
||||
collaboration = 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;
|
||||
// re-use process when creating first participant
|
||||
context.process = parent;
|
||||
}
|
||||
|
||||
context.processRoot = parent;
|
||||
context.parent = collaboration;
|
||||
}
|
||||
|
||||
// turn process into collaboration before adding participant
|
||||
this.preExecute('shape.create', function(context) {
|
||||
var parent = context.parent,
|
||||
shape = context.shape;
|
||||
|
||||
if (is(shape, 'bpmn:Participant') && is(parent, 'bpmn:Process')) {
|
||||
ensureCollaboration(context);
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.execute('shape.create', function(context) {
|
||||
var processRoot = context.processRoot,
|
||||
var process = context.process,
|
||||
shape = context.shape;
|
||||
|
||||
if (processRoot) {
|
||||
if (process) {
|
||||
context.oldProcessRef = shape.businessObject.processRef;
|
||||
|
||||
// assign the participant processRef
|
||||
shape.businessObject.processRef = processRoot.businessObject;
|
||||
// re-use process when creating first participant
|
||||
shape.businessObject.processRef = process.businessObject;
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.revert('shape.create', function(context) {
|
||||
var processRoot = context.processRoot,
|
||||
var process = context.process,
|
||||
shape = context.shape;
|
||||
|
||||
if (processRoot) {
|
||||
if (process) {
|
||||
|
||||
// assign the participant processRef
|
||||
// re-use process when creating first participant
|
||||
shape.businessObject.processRef = context.oldProcessRef;
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.postExecute('shape.create', function(context) {
|
||||
var processRoot = context.processRoot,
|
||||
var process = context.process,
|
||||
shape = context.shape;
|
||||
|
||||
if (processRoot) {
|
||||
if (process) {
|
||||
|
||||
// process root is already detached at this point
|
||||
var processChildren = processRoot.children.slice();
|
||||
// move children from process to participant
|
||||
var processChildren = process.children.slice();
|
||||
|
||||
modeling.moveElements(processChildren, { x: 0, y: 0 }, shape);
|
||||
}
|
||||
|
||||
}, true);
|
||||
|
||||
// turn process into collaboration when creating participants
|
||||
this.preExecute('elements.create', HIGH_PRIORITY, function(context) {
|
||||
var elements = context.elements,
|
||||
parent = context.parent,
|
||||
participant;
|
||||
|
||||
var hasParticipants = findParticipant(elements);
|
||||
|
||||
if (hasParticipants && is(parent, 'bpmn:Process')) {
|
||||
ensureCollaboration(context);
|
||||
|
||||
participant = findParticipant(elements);
|
||||
|
||||
context.oldProcessRef = participant.businessObject.processRef;
|
||||
|
||||
// re-use process when creating first participant
|
||||
participant.businessObject.processRef = parent.businessObject;
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.revert('elements.create', function(context) {
|
||||
var elements = context.elements,
|
||||
process = context.process,
|
||||
participant;
|
||||
|
||||
if (process) {
|
||||
participant = findParticipant(elements);
|
||||
|
||||
// re-use process when creating first participant
|
||||
participant.businessObject.processRef = context.oldProcessRef;
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.postExecute('elements.create', function(context) {
|
||||
var elements = context.elements,
|
||||
process = context.process,
|
||||
participant;
|
||||
|
||||
if (process) {
|
||||
participant = findParticipant(elements);
|
||||
|
||||
// move children from process to first participant
|
||||
var processChildren = process.children.slice();
|
||||
|
||||
modeling.moveElements(processChildren, { x: 0, y: 0 }, participant);
|
||||
}
|
||||
|
||||
}, true);
|
||||
|
||||
}
|
||||
|
||||
CreateParticipantBehavior.$inject = [
|
||||
@ -168,9 +222,14 @@ function getParticipantBounds(shape, childrenBBox) {
|
||||
height: childrenBBox.height + VERTICAL_PARTICIPANT_PADDING * 2
|
||||
};
|
||||
|
||||
var width = Math.max(shape.width, childrenBBox.width),
|
||||
height = Math.max(shape.height, childrenBBox.height);
|
||||
|
||||
return {
|
||||
width: Math.max(shape.width, childrenBBox.width),
|
||||
height: Math.max(shape.height, childrenBBox.height)
|
||||
x: -width / 2,
|
||||
y: -height / 2,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
}
|
||||
|
||||
@ -187,4 +246,10 @@ function getParticipantCreateConstraints(shape, childrenBBox) {
|
||||
|
||||
function isConnection(element) {
|
||||
return !!element.waypoints;
|
||||
}
|
||||
|
||||
function findParticipant(elements) {
|
||||
return find(elements, function(element) {
|
||||
return is(element, 'bpmn:Participant');
|
||||
});
|
||||
}
|
@ -6,37 +6,17 @@ import { is } from '../../../util/ModelUtil';
|
||||
import { isExpanded } from '../../../util/DiUtil.js';
|
||||
|
||||
/**
|
||||
* Add start event child by default when creating an expanded subprocess
|
||||
* with create.start or replacing a task with an expanded subprocess.
|
||||
* Add start event replacing element with expanded sub process.
|
||||
*
|
||||
* @param {Injector} injector
|
||||
* @param {Modeling} modeling
|
||||
*/
|
||||
export default function SubProcessStartEventBehavior(eventBus, modeling) {
|
||||
CommandInterceptor.call(this, eventBus);
|
||||
|
||||
eventBus.on('create.start', function(event) {
|
||||
var shape = event.context.shape,
|
||||
hints = event.context.hints;
|
||||
|
||||
hints.shouldAddStartEvent = is(shape, 'bpmn:SubProcess') && isExpanded(shape);
|
||||
});
|
||||
|
||||
this.postExecuted('shape.create', function(event) {
|
||||
var shape = event.context.shape,
|
||||
hints = event.context.hints,
|
||||
position;
|
||||
|
||||
if (!hints.shouldAddStartEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
position = calculatePositionRelativeToShape(shape);
|
||||
|
||||
modeling.createShape({ type: 'bpmn:StartEvent' }, position, shape);
|
||||
});
|
||||
export default function SubProcessStartEventBehavior(injector, modeling) {
|
||||
injector.invoke(CommandInterceptor, this);
|
||||
|
||||
this.postExecuted('shape.replace', function(event) {
|
||||
var oldShape = event.context.oldShape,
|
||||
newShape = event.context.newShape,
|
||||
position;
|
||||
newShape = event.context.newShape;
|
||||
|
||||
if (
|
||||
!is(newShape, 'bpmn:SubProcess') ||
|
||||
@ -46,14 +26,14 @@ export default function SubProcessStartEventBehavior(eventBus, modeling) {
|
||||
return;
|
||||
}
|
||||
|
||||
position = calculatePositionRelativeToShape(newShape);
|
||||
var position = getStartEventPosition(newShape);
|
||||
|
||||
modeling.createShape({ type: 'bpmn:StartEvent' }, position, newShape);
|
||||
});
|
||||
}
|
||||
|
||||
SubProcessStartEventBehavior.$inject = [
|
||||
'eventBus',
|
||||
'injector',
|
||||
'modeling'
|
||||
];
|
||||
|
||||
@ -61,7 +41,7 @@ inherits(SubProcessStartEventBehavior, CommandInterceptor);
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function calculatePositionRelativeToShape(shape) {
|
||||
function getStartEventPosition(shape) {
|
||||
return {
|
||||
x: shape.x + shape.width / 6,
|
||||
y: shape.y + shape.height / 2
|
||||
|
@ -71,8 +71,26 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
|
||||
};
|
||||
}
|
||||
|
||||
function createParticipant(event, collapsed) {
|
||||
create.start(event, elementFactory.createParticipantShape(collapsed));
|
||||
function createSubprocess(event) {
|
||||
var subProcess = elementFactory.createShape({
|
||||
type: 'bpmn:SubProcess',
|
||||
x: 0,
|
||||
y: 0,
|
||||
isExpanded: true
|
||||
});
|
||||
|
||||
var startEvent = elementFactory.createShape({
|
||||
type: 'bpmn:StartEvent',
|
||||
x: 40,
|
||||
y: 82,
|
||||
parent: subProcess
|
||||
});
|
||||
|
||||
create.start(event, [ subProcess, startEvent ]);
|
||||
}
|
||||
|
||||
function createParticipant(event) {
|
||||
create.start(event, elementFactory.createParticipantShape());
|
||||
}
|
||||
|
||||
assign(actions, {
|
||||
@ -148,11 +166,15 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
|
||||
'bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store',
|
||||
translate('Create DataStoreReference')
|
||||
),
|
||||
'create.subprocess-expanded': createAction(
|
||||
'bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded',
|
||||
translate('Create expanded SubProcess'),
|
||||
{ isExpanded: true }
|
||||
),
|
||||
'create.subprocess-expanded': {
|
||||
group: 'activity',
|
||||
className: 'bpmn-icon-subprocess-expanded',
|
||||
title: translate('Create expanded SubProcess'),
|
||||
action: {
|
||||
dragstart: createSubprocess,
|
||||
click: createSubprocess
|
||||
}
|
||||
},
|
||||
'create.participant-expanded': {
|
||||
group: 'collaboration',
|
||||
className: 'bpmn-icon-participant',
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
} from '../../util/ModelUtil';
|
||||
|
||||
import {
|
||||
getParent,
|
||||
isAny
|
||||
} from '../modeling/util/ModelingUtil';
|
||||
|
||||
@ -117,6 +118,20 @@ BpmnRules.prototype.init = function() {
|
||||
return canResize(shape, newBounds);
|
||||
});
|
||||
|
||||
this.addRule('elements.create', function(context) {
|
||||
var elements = context.elements,
|
||||
position = context.position,
|
||||
target = context.target;
|
||||
|
||||
return every(elements, function(element) {
|
||||
if (isConnection(element)) {
|
||||
return canConnect(element.source, element.target, element);
|
||||
}
|
||||
|
||||
return canCreate(element, target, null, position);
|
||||
});
|
||||
});
|
||||
|
||||
this.addRule('elements.move', function(context) {
|
||||
|
||||
var target = context.target,
|
||||
@ -320,7 +335,7 @@ function isSameScope(a, b) {
|
||||
var scopeParentA = getScopeParent(a),
|
||||
scopeParentB = getScopeParent(b);
|
||||
|
||||
return scopeParentA && (scopeParentA === scopeParentB);
|
||||
return scopeParentA === scopeParentB;
|
||||
}
|
||||
|
||||
function hasEventDefinition(element, eventDefinition) {
|
||||
@ -852,9 +867,9 @@ function canConnectAssociation(source, target) {
|
||||
|
||||
function canConnectMessageFlow(source, target) {
|
||||
|
||||
// handle the case where target does not have a parent,
|
||||
// because it is not dropped within the diagram (bpmn-io/bpmn-js#1033)
|
||||
if (!target.parent) {
|
||||
// during connect user might move mouse out of canvas
|
||||
// https://github.com/bpmn-io/bpmn-js/issues/1033
|
||||
if (getRootElement(source) && !getRootElement(target)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -955,8 +970,11 @@ function isOutgoingEventBasedGatewayConnection(connection) {
|
||||
}
|
||||
|
||||
function areOutgoingEventBasedGatewayConnections(connections) {
|
||||
|
||||
connections = connections || [];
|
||||
|
||||
return connections.some(isOutgoingEventBasedGatewayConnection);
|
||||
}
|
||||
|
||||
function getRootElement(element) {
|
||||
return getParent(element, 'bpmn:Process') || getParent(element, 'bpmn:Collaboration');
|
||||
}
|
@ -277,19 +277,6 @@ describe('features/auto-resize', function() {
|
||||
expect(participantShape).to.have.bounds(originalBounds);
|
||||
}));
|
||||
|
||||
|
||||
it('should not auto-resize when creating with { root: false } hint', inject(function(modeling) {
|
||||
|
||||
// given
|
||||
var taskAttrs = { type: 'bpmn:Task' };
|
||||
|
||||
// when
|
||||
modeling.createShape(taskAttrs, { x: 600, y: 320 }, participantShape, { root: false });
|
||||
|
||||
// then
|
||||
expect(participantShape).to.have.bounds(originalBounds);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ describe('features/modeling - create participant', function() {
|
||||
|
||||
describe('process', function() {
|
||||
|
||||
describe('should turn diagram into collaboration', function() {
|
||||
describe('should turn process into collaboration', function() {
|
||||
|
||||
var processDiagramXML = require('../../../../fixtures/bpmn/collaboration/process-empty.bpmn');
|
||||
|
||||
@ -39,13 +39,17 @@ describe('features/modeling - create participant', function() {
|
||||
collaborationDi,
|
||||
diRoot,
|
||||
participant,
|
||||
participant2,
|
||||
participants,
|
||||
participantBo,
|
||||
participant2Bo,
|
||||
participantDi,
|
||||
participant2Di,
|
||||
process,
|
||||
processBo,
|
||||
processDi;
|
||||
|
||||
beforeEach(inject(function(canvas, elementFactory, modeling) {
|
||||
beforeEach(inject(function(canvas, elementFactory) {
|
||||
|
||||
// given
|
||||
process = canvas.getRootElement();
|
||||
@ -54,48 +58,116 @@ describe('features/modeling - create participant', function() {
|
||||
|
||||
diRoot = processBo.di.$parent;
|
||||
|
||||
participant = elementFactory.createParticipantShape();
|
||||
participant = elementFactory.createParticipantShape({ x: 100, y: 100 });
|
||||
participantBo = participant.businessObject;
|
||||
participantDi = participantBo.di;
|
||||
|
||||
// when
|
||||
modeling.createShape(participant, { x: 350, y: 200 }, process);
|
||||
participant2 = elementFactory.createParticipantShape({ x: 100, y: 400 });
|
||||
participant2Bo = participant2.businessObject;
|
||||
participant2Di = participant2Bo.di;
|
||||
|
||||
collaboration = canvas.getRootElement();
|
||||
collaborationBo = collaboration.businessObject;
|
||||
collaborationDi = collaborationBo.di;
|
||||
participants = [ participant, participant2 ];
|
||||
}));
|
||||
|
||||
|
||||
it('execute', function() {
|
||||
describe('creating one participant', function() {
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).to.equal(collaborationBo);
|
||||
expect(participantBo.processRef).to.equal(processBo);
|
||||
beforeEach(inject(function(canvas, modeling) {
|
||||
|
||||
expect(collaborationBo.$instanceOf('bpmn:Collaboration')).to.be.true;
|
||||
expect(collaborationBo.$parent).to.equal(processBo.$parent);
|
||||
expect(collaborationBo.participants).to.include(participantBo);
|
||||
// when
|
||||
modeling.createShape(participant, { x: 400, y: 225 }, process);
|
||||
|
||||
collaboration = canvas.getRootElement();
|
||||
collaborationBo = collaboration.businessObject;
|
||||
collaborationDi = collaborationBo.di;
|
||||
}));
|
||||
|
||||
|
||||
it('execute', function() {
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).to.equal(collaborationBo);
|
||||
expect(participantBo.processRef).to.equal(processBo);
|
||||
|
||||
expect(collaborationBo.$instanceOf('bpmn:Collaboration')).to.be.true;
|
||||
expect(collaborationBo.$parent).to.equal(processBo.$parent);
|
||||
expect(collaborationBo.participants).to.include(participantBo);
|
||||
|
||||
expect(participantDi.$parent).to.equal(collaborationDi);
|
||||
expect(collaborationDi.$parent).to.equal(diRoot);
|
||||
});
|
||||
|
||||
|
||||
it('undo', inject(function(commandStack) {
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).not.to.exist;
|
||||
expect(participantBo.processRef).not.to.equal(processBo);
|
||||
|
||||
expect(collaborationBo.$parent).not.to.exist;
|
||||
expect(collaborationBo.participants).not.to.include(participantBo);
|
||||
|
||||
expect(processDi.$parent).to.equal(diRoot);
|
||||
}));
|
||||
|
||||
expect(participantDi.$parent).to.equal(collaborationDi);
|
||||
expect(collaborationDi.$parent).to.equal(diRoot);
|
||||
});
|
||||
|
||||
|
||||
it('undo', inject(function(commandStack) {
|
||||
describe('creating two participants', function() {
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
beforeEach(inject(function(canvas, modeling) {
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).not.to.exist;
|
||||
expect(participantBo.processRef).not.to.equal(processBo);
|
||||
// when
|
||||
modeling.createElements(participants, { x: 400, y: 375 }, process);
|
||||
|
||||
expect(collaborationBo.$parent).not.to.exist;
|
||||
expect(collaborationBo.participants).not.to.include(participantBo);
|
||||
collaboration = canvas.getRootElement();
|
||||
collaborationBo = collaboration.businessObject;
|
||||
collaborationDi = collaborationBo.di;
|
||||
}));
|
||||
|
||||
expect(processDi.$parent).to.equal(diRoot);
|
||||
}));
|
||||
|
||||
it('execute', function() {
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).to.equal(collaborationBo);
|
||||
expect(participantBo.processRef).to.equal(processBo);
|
||||
|
||||
expect(participant2Bo.$parent).to.equal(collaborationBo);
|
||||
expect(participant2Bo.processRef).not.to.equal(processBo);
|
||||
|
||||
expect(collaborationBo.$instanceOf('bpmn:Collaboration')).to.be.true;
|
||||
expect(collaborationBo.$parent).to.equal(processBo.$parent);
|
||||
expect(collaborationBo.participants).to.include(participantBo);
|
||||
|
||||
expect(participantDi.$parent).to.equal(collaborationDi);
|
||||
expect(participant2Di.$parent).to.equal(collaborationDi);
|
||||
expect(collaborationDi.$parent).to.equal(diRoot);
|
||||
});
|
||||
|
||||
|
||||
it('undo', inject(function(commandStack) {
|
||||
|
||||
// when
|
||||
commandStack.undo();
|
||||
|
||||
// then
|
||||
expect(participantBo.$parent).not.to.exist;
|
||||
expect(participantBo.processRef).not.to.equal(processBo);
|
||||
|
||||
expect(participant2Bo.$parent).not.to.exist;
|
||||
expect(participant2Bo.processRef).not.to.equal(processBo);
|
||||
|
||||
expect(collaborationBo.$parent).not.to.exist;
|
||||
expect(collaborationBo.participants).not.to.include(participantBo);
|
||||
expect(collaborationBo.participants).not.to.include(participant2Bo);
|
||||
|
||||
expect(processDi.$parent).to.equal(diRoot);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -1,11 +1,17 @@
|
||||
import {
|
||||
bootstrapModeler,
|
||||
getBpmnJS,
|
||||
inject
|
||||
} from 'test/TestHelper';
|
||||
|
||||
import coreModule from 'lib/core';
|
||||
import createModule from 'diagram-js/lib/features/create';
|
||||
import modelingModule from 'lib/features/modeling';
|
||||
import paletteModule from 'lib/features/palette';
|
||||
import coreModule from 'lib/core';
|
||||
|
||||
import { createMoveEvent } from 'diagram-js/lib/features/mouse/Mouse';
|
||||
|
||||
import { is } from 'lib/util/ModelUtil';
|
||||
|
||||
import {
|
||||
query as domQuery,
|
||||
@ -17,12 +23,17 @@ describe('features/palette', function() {
|
||||
|
||||
var diagramXML = require('../../../fixtures/bpmn/features/replace/01_replace.bpmn');
|
||||
|
||||
var testModules = [ coreModule, modelingModule, paletteModule ];
|
||||
var testModules = [
|
||||
coreModule,
|
||||
createModule,
|
||||
modelingModule,
|
||||
paletteModule
|
||||
];
|
||||
|
||||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
||||
|
||||
|
||||
it('should provide BPMN modeling palette', inject(function(canvas, palette) {
|
||||
it('should provide BPMN modeling palette', inject(function(canvas) {
|
||||
|
||||
// when
|
||||
var paletteElement = domQuery('.djs-palette', canvas._container);
|
||||
@ -32,4 +43,35 @@ describe('features/palette', function() {
|
||||
expect(entries.length).to.equal(14);
|
||||
}));
|
||||
|
||||
|
||||
describe('sub process', function() {
|
||||
|
||||
it('should create sub process with start event', inject(function(dragging, palette) {
|
||||
|
||||
// when
|
||||
triggerPaletteEntry('create.subprocess-expanded');
|
||||
|
||||
// then
|
||||
var context = dragging.context(),
|
||||
elements = context.data.elements;
|
||||
|
||||
expect(elements).to.have.length(2);
|
||||
expect(is(elements[0], 'bpmn:SubProcess')).to.be.true;
|
||||
expect(is(elements[1], 'bpmn:StartEvent')).to.be.true;
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function triggerPaletteEntry(id) {
|
||||
getBpmnJS().invoke(function(palette) {
|
||||
var entry = palette.getEntries()[ id ];
|
||||
|
||||
if (entry && entry.action && entry.action.click) {
|
||||
entry.action.click(createMoveEvent(0, 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -20,6 +20,69 @@ describe('features/modeling/rules - BpmnRules', function() {
|
||||
var testModules = [ coreModule, modelingModule ];
|
||||
|
||||
|
||||
describe('create elements', function() {
|
||||
|
||||
var testXML = require('./BpmnRules.process.bpmn');
|
||||
|
||||
beforeEach(bootstrapModeler(testXML, { modules: testModules }));
|
||||
|
||||
|
||||
it('create tasks -> process', inject(function(elementFactory) {
|
||||
|
||||
// given
|
||||
var task1 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
task2 = elementFactory.createShape({ type: 'bpmn:Task' });
|
||||
|
||||
// then
|
||||
expectCanCreate([ task1, task2 ], 'Process', true);
|
||||
}));
|
||||
|
||||
|
||||
it('create tasks -> task', inject(function(elementFactory) {
|
||||
|
||||
// given
|
||||
var task1 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
task2 = elementFactory.createShape({ type: 'bpmn:Task' });
|
||||
|
||||
// then
|
||||
expectCanCreate([ task1, task2 ], 'Task', false);
|
||||
}));
|
||||
|
||||
|
||||
it('create tasks and sequence flow -> process', inject(function(elementFactory) {
|
||||
|
||||
// given
|
||||
var task1 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
task2 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
sequenceFlow = elementFactory.createConnection({
|
||||
type: 'bpmn:SequenceFlow',
|
||||
source: task1,
|
||||
target: task2
|
||||
});
|
||||
|
||||
// then
|
||||
expectCanCreate([ task1, task2, sequenceFlow ], 'Process', true);
|
||||
}));
|
||||
|
||||
|
||||
it('create tasks and message flow -> process', inject(function(elementFactory) {
|
||||
|
||||
// given
|
||||
var task1 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
task2 = elementFactory.createShape({ type: 'bpmn:Task' }),
|
||||
sequenceFlow = elementFactory.createConnection({
|
||||
type: 'bpmn:MessageFlow',
|
||||
source: task1,
|
||||
target: task2
|
||||
});
|
||||
|
||||
// then
|
||||
expectCanCreate([ task1, task2, sequenceFlow ], 'Process', false);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('on process diagram', function() {
|
||||
|
||||
var testXML = require('./BpmnRules.process.bpmn');
|
||||
|
@ -3,7 +3,9 @@ import {
|
||||
} from 'test/TestHelper';
|
||||
|
||||
import {
|
||||
isString
|
||||
isArray,
|
||||
isString,
|
||||
map
|
||||
} from 'min-dash';
|
||||
|
||||
|
||||
@ -47,10 +49,21 @@ export function expectCanDrop(element, target, expectedResult) {
|
||||
}
|
||||
|
||||
|
||||
export function expectCanCreate(element, target, expectedResult) {
|
||||
export function expectCanCreate(shape, target, expectedResult) {
|
||||
|
||||
var result = getBpmnJS().invoke(function(bpmnRules) {
|
||||
return bpmnRules.canCreate(get(element), get(target));
|
||||
var result = getBpmnJS().invoke(function(rules) {
|
||||
|
||||
if (isArray(shape)) {
|
||||
return rules.allowed('elements.create', {
|
||||
elements: get(shape),
|
||||
target: get(target)
|
||||
});
|
||||
}
|
||||
|
||||
return rules.allowed('shape.create', {
|
||||
shape: get(shape),
|
||||
target: get(target)
|
||||
});
|
||||
});
|
||||
|
||||
expect(result).to.eql(expectedResult);
|
||||
@ -94,21 +107,25 @@ export function expectCanMove(elements, target, rules) {
|
||||
* Retrieve element, resolving an ID with
|
||||
* the actual element.
|
||||
*/
|
||||
function get(element) {
|
||||
function get(elementId) {
|
||||
|
||||
var actualElement;
|
||||
|
||||
if (isString(element)) {
|
||||
actualElement = getBpmnJS().invoke(function(elementRegistry) {
|
||||
return elementRegistry.get(element);
|
||||
});
|
||||
|
||||
if (!actualElement) {
|
||||
throw new Error('element #' + element + ' not found');
|
||||
}
|
||||
|
||||
return actualElement;
|
||||
if (isArray(elementId)) {
|
||||
return map(elementId, get);
|
||||
}
|
||||
|
||||
return element;
|
||||
var element;
|
||||
|
||||
if (isString(elementId)) {
|
||||
element = getBpmnJS().invoke(function(elementRegistry) {
|
||||
return elementRegistry.get(elementId);
|
||||
});
|
||||
|
||||
if (!element) {
|
||||
throw new Error('element #' + elementId + ' not found');
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
return elementId;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user