feat(global-connect): use rules for connection starting

* remove `BpmnGlobalConnect` provider
* use `connection.start` rule to determine whether
  an element can start a connection

Closes #565
Closes #870

BREAKING CHANGE:

* `BpmnGlobalConnect` got removed. Add `connection.start`
  rule to specify whether connection should be allowed.
This commit is contained in:
Maciej Barelkowski 2018-10-10 17:26:03 +02:00 committed by merge-me[bot]
parent 026fe11ea7
commit ba42e9edde
7 changed files with 88 additions and 127 deletions

View File

@ -3,8 +3,9 @@ import EditorActionsModule from 'diagram-js/lib/features/editor-actions';
import HandToolModule from 'diagram-js/lib/features/hand-tool'; import HandToolModule from 'diagram-js/lib/features/hand-tool';
import LassoToolModule from 'diagram-js/lib/features/lasso-tool'; import LassoToolModule from 'diagram-js/lib/features/lasso-tool';
import SpaceToolModule from 'diagram-js/lib/features/space-tool'; import SpaceToolModule from 'diagram-js/lib/features/space-tool';
import GlobalConnectModule from 'diagram-js/lib/features/global-connect';
import DirectEditingModule from 'diagram-js-direct-editing'; import DirectEditingModule from 'diagram-js-direct-editing';
import GlobalConnectModule from '../global-connect';
import CopyPasteModule from '../copy-paste'; import CopyPasteModule from '../copy-paste';
import DistributeElementsModule from '../distribute-elements'; import DistributeElementsModule from '../distribute-elements';
import SearchModule from '../search'; import SearchModule from '../search';

View File

@ -1,47 +0,0 @@
import {
isAny
} from '../modeling/util/ModelingUtil';
import {
isLabel
} from '../../util/LabelUtil';
/**
* Extention of GlobalConnect tool that implements BPMN specific rules about
* connection start elements.
*/
export default function BpmnGlobalConnect(globalConnect) {
globalConnect.registerProvider(this);
}
BpmnGlobalConnect.$inject = [ 'globalConnect' ];
/**
* Checks if given element can be used for starting connection.
*
* @param {Element} source
* @return {Boolean}
*/
BpmnGlobalConnect.prototype.canStartConnect = function(source) {
if (nonExistantOrLabel(source)) {
return null;
}
var businessObject = source.businessObject;
return isAny(businessObject, [
'bpmn:FlowNode',
'bpmn:InteractionNode',
'bpmn:DataObjectReference',
'bpmn:DataStoreReference'
]);
};
function nonExistantOrLabel(element) {
return !element || isLabel(element);
}

View File

@ -1,11 +0,0 @@
import GlobalConnectModule from 'diagram-js/lib/features/global-connect';
import BpmnGlobalConnect from './BpmnGlobalConnect';
export default {
__depends__: [
GlobalConnectModule
],
__init__: [ 'bpmnGlobalConnect' ],
bpmnGlobalConnect: [ 'type', BpmnGlobalConnect ]
};

View File

@ -3,10 +3,9 @@ import CreateModule from 'diagram-js/lib/features/create';
import SpaceToolModule from 'diagram-js/lib/features/space-tool'; import SpaceToolModule from 'diagram-js/lib/features/space-tool';
import LassoToolModule from 'diagram-js/lib/features/lasso-tool'; import LassoToolModule from 'diagram-js/lib/features/lasso-tool';
import HandToolModule from 'diagram-js/lib/features/hand-tool'; import HandToolModule from 'diagram-js/lib/features/hand-tool';
import GlobalConnectModule from 'diagram-js/lib/features/global-connect';
import translate from 'diagram-js/lib/i18n/translate'; import translate from 'diagram-js/lib/i18n/translate';
import GlobalConnectModule from '../global-connect';
import PaletteProvider from './PaletteProvider'; import PaletteProvider from './PaletteProvider';
export default { export default {
@ -16,8 +15,8 @@ export default {
SpaceToolModule, SpaceToolModule,
LassoToolModule, LassoToolModule,
HandToolModule, HandToolModule,
translate, GlobalConnectModule,
GlobalConnectModule translate
], ],
__init__: [ 'paletteProvider' ], __init__: [ 'paletteProvider' ],
paletteProvider: [ 'type', PaletteProvider ] paletteProvider: [ 'type', PaletteProvider ]

View File

@ -49,6 +49,12 @@ BpmnRules.$inject = [ 'eventBus' ];
BpmnRules.prototype.init = function() { BpmnRules.prototype.init = function() {
this.addRule('connection.start', function(context) {
var source = context.source;
return canStartConnection(source);
});
this.addRule('connection.create', function(context) { this.addRule('connection.create', function(context) {
var source = context.source, var source = context.source,
target = context.target, target = context.target,
@ -200,7 +206,28 @@ BpmnRules.prototype.canCopy = canCopy;
* Utility functions for rule checking * Utility functions for rule checking
*/ */
function nonExistantOrLabel(element) { /**
* Checks if given element can be used for starting connection.
*
* @param {Element} source
* @return {Boolean}
*/
function canStartConnection(element) {
if (nonExistingOrLabel(element)) {
return null;
}
var businessObject = element.businessObject;
return isAny(businessObject, [
'bpmn:FlowNode',
'bpmn:InteractionNode',
'bpmn:DataObjectReference',
'bpmn:DataStoreReference'
]);
}
function nonExistingOrLabel(element) {
return !element || isLabel(element); return !element || isLabel(element);
} }
@ -374,7 +401,7 @@ function isParent(possibleParent, element) {
function canConnect(source, target, connection) { function canConnect(source, target, connection) {
if (nonExistantOrLabel(source) || nonExistantOrLabel(target)) { if (nonExistingOrLabel(source) || nonExistingOrLabel(target)) {
return null; return null;
} }

View File

@ -1,62 +0,0 @@
import {
bootstrapModeler,
inject
} from 'test/TestHelper';
import modelingModule from 'lib/features/modeling';
import providerModule from 'lib/features/global-connect';
import coreModule from 'lib/core';
describe('features/bpmn-global-connect-provider', function() {
var diagramXML = require('../../../fixtures/bpmn/simple.bpmn');
var testModules = [ coreModule, modelingModule, providerModule ];
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
it('should allow start for given element types', inject(function(bpmnGlobalConnect, elementFactory) {
// given
var types = [
'bpmn:FlowNode',
'bpmn:InteractionNode',
'bpmn:DataObjectReference',
'bpmn:DataStoreReference'
];
// when
var results = types.map(function(type) {
var e = elementFactory.createShape({ type: type });
return bpmnGlobalConnect.canStartConnect(e);
});
// then
results.forEach(function(r) {
expect(r).to.be.true;
});
}));
it('should ignore label elements', inject(function(canvas, bpmnGlobalConnect, modeling, elementFactory) {
// given
var label = elementFactory.createShape({ type: 'bpmn:FlowNode', labelTarget: {} });
// when
var result = bpmnGlobalConnect.canStartConnect(label);
// then
expect(result).to.be.null;
}));
it('should NOT allow start on unknown element', inject(function(bpmnGlobalConnect) {
// when
var result = bpmnGlobalConnect.canStartConnect({ type: 'bpmn:SomeUnknownType' });
// then
expect(result).to.be.false;
}));
});

View File

@ -1694,4 +1694,58 @@ describe('features/modeling/rules - BpmnRules', function() {
}); });
describe('start connection', function() {
var testXML = require('../../../fixtures/bpmn/simple.bpmn');
beforeEach(bootstrapModeler(testXML, { modules: testModules }));
it('should allow start for given element types', inject(function(elementFactory, rules) {
// given
var types = [
'bpmn:FlowNode',
'bpmn:InteractionNode',
'bpmn:DataObjectReference',
'bpmn:DataStoreReference'
];
// when
var results = types.map(function(type) {
var element = elementFactory.createShape({ type: type });
return rules.allowed('connection.start', { source: element });
});
// then
results.forEach(function(result) {
expect(result).to.be.true;
});
}));
it('should ignore label elements', inject(function(elementFactory, rules) {
// given
var label = elementFactory.createShape({ type: 'bpmn:FlowNode', labelTarget: {} });
// when
var result = rules.allowed('connection.start', { source: label });
// then
expect(result).to.be.null;
}));
it('should NOT allow start on unknown element', inject(function(rules) {
// given
var element = { type: 'bpmn:SomeUnknownType' };
// when
var result = rules.allowed('connection.start', { source: element });
// then
expect(result).to.be.false;
}));
});
}); });