123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import {
- forEach,
- find,
- matchPattern
- } from 'min-dash';
- import inherits from 'inherits';
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
- import { is } from '../../../util/ModelUtil';
- export default function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules, injector) {
- CommandInterceptor.call(this, eventBus);
- var dragging = injector.get('dragging', false);
- function fixConnection(connection) {
- var source = connection.source,
- target = connection.target,
- parent = connection.parent;
- // do not do anything if connection
- // is already deleted (may happen due to other
- // behaviors plugged-in before)
- if (!parent) {
- return;
- }
- var replacementType,
- remove;
- /**
- * Check if incoming or outgoing connections
- * can stay or could be substituted with an
- * appropriate replacement.
- *
- * This holds true for SequenceFlow <> MessageFlow.
- */
- if (is(connection, 'bpmn:SequenceFlow')) {
- if (!bpmnRules.canConnectSequenceFlow(source, target)) {
- remove = true;
- }
- if (bpmnRules.canConnectMessageFlow(source, target)) {
- replacementType = 'bpmn:MessageFlow';
- }
- }
- // transform message flows into sequence flows, if possible
- if (is(connection, 'bpmn:MessageFlow')) {
- if (!bpmnRules.canConnectMessageFlow(source, target)) {
- remove = true;
- }
- if (bpmnRules.canConnectSequenceFlow(source, target)) {
- replacementType = 'bpmn:SequenceFlow';
- }
- }
- if (is(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
- remove = true;
- }
- // remove invalid connection,
- // unless it has been removed already
- if (remove) {
- modeling.removeConnection(connection);
- }
- // replace SequenceFlow <> MessageFlow
- if (replacementType) {
- modeling.connect(source, target, {
- type: replacementType,
- waypoints: connection.waypoints.slice()
- });
- }
- }
- function replaceReconnectedConnection(event) {
- var context = event.context,
- connection = context.connection,
- source = context.newSource || connection.source,
- target = context.newTarget || connection.target,
- allowed,
- replacement;
- allowed = bpmnRules.canConnect(source, target);
- if (!allowed || allowed.type === connection.type) {
- return;
- }
- replacement = modeling.connect(source, target, {
- type: allowed.type,
- waypoints: connection.waypoints.slice()
- });
- // remove old connection
- modeling.removeConnection(connection);
- // replace connection in context to reconnect end/start
- context.connection = replacement;
- if (dragging) {
- cleanDraggingSelection(connection, replacement);
- }
- }
- // monkey-patch selection saved in dragging in order to re-select it when operation is finished
- function cleanDraggingSelection(oldConnection, newConnection) {
- var context = dragging.context(),
- previousSelection = context && context.payload.previousSelection,
- index;
- // do nothing if not dragging or no selection was present
- if (!previousSelection || !previousSelection.length) {
- return;
- }
- index = previousSelection.indexOf(oldConnection);
- if (index === -1) {
- return;
- }
- previousSelection.splice(index, 1, newConnection);
- }
- // lifecycle hooks
- this.postExecuted('elements.move', function(context) {
- var closure = context.closure,
- allConnections = closure.allConnections;
- forEach(allConnections, fixConnection);
- }, true);
- this.preExecute('connection.reconnect', replaceReconnectedConnection);
- this.postExecuted('element.updateProperties', function(event) {
- var context = event.context,
- properties = context.properties,
- element = context.element,
- businessObject = element.businessObject,
- connection;
- // remove condition on change to default
- if (properties.default) {
- connection = find(
- element.outgoing,
- matchPattern({ id: element.businessObject.default.id })
- );
- if (connection) {
- modeling.updateProperties(connection, { conditionExpression: undefined });
- }
- }
- // remove default from source on change to conditional
- if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) {
- modeling.updateProperties(element.source, { default: undefined });
- }
- });
- }
- inherits(ReplaceConnectionBehavior, CommandInterceptor);
- ReplaceConnectionBehavior.$inject = [
- 'eventBus',
- 'modeling',
- 'bpmnRules',
- 'injector'
- ];
|