feat(global-connect): connect distant elements

Closes #474, #394
This commit is contained in:
Vladimirs Katusenoks 2016-04-13 12:36:19 +02:00
parent bb06a0386d
commit 1923a6bdda
10 changed files with 166 additions and 8 deletions

View File

@ -183,6 +183,7 @@ Modeler.prototype._modelingModules = [
require('diagram-js/lib/features/space-tool'),
require('diagram-js/lib/features/lasso-tool'),
require('diagram-js/lib/features/hand-tool'),
require('./features/global-connect'),
require('./features/keyboard'),
require('./features/snapping'),
require('./features/modeling'),

View File

@ -0,0 +1,49 @@
'use strict';
var isAny = require('../modeling/util/ModelingUtil').isAny;
/**
* Extention of GlobalConnect tool that implements BPMN specific rules about
* connection start elements.
*/
function BpmnGlobalConnect(globalConnect) {
globalConnect.registerProvider(this);
}
BpmnGlobalConnect.$inject = [ 'globalConnect' ];
module.exports = BpmnGlobalConnect;
/**
* 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);
}
function isLabel(element) {
return element.labelTarget;
}

View File

@ -0,0 +1,7 @@
module.exports = {
__depends__: [
require('diagram-js/lib/features/global-connect')
],
__init__: [ 'bpmnGlobalConnect' ],
bpmnGlobalConnect: [ 'type', require('./BpmnGlobalConnect') ]
};

View File

@ -1,6 +1,6 @@
'use strict';
function BpmnKeyBindings(keyboard, spaceTool, lassoTool, handTool, directEditing,
function BpmnKeyBindings(keyboard, spaceTool, lassoTool, handTool, globalConnect, directEditing,
searchPad, selection, canvas, elementRegistry, editorActions) {
var actions = {
@ -24,6 +24,9 @@ function BpmnKeyBindings(keyboard, spaceTool, lassoTool, handTool, directEditing
handTool: function() {
handTool.toggle();
},
globalConnectTool: function() {
globalConnect.toggle();
},
directEditing: function() {
var currentSelection = selection.get();
@ -79,6 +82,13 @@ function BpmnKeyBindings(keyboard, spaceTool, lassoTool, handTool, directEditing
return true;
}
// c -> activate global connect tool
if (key === 67) {
editorActions.trigger('globalConnectTool');
return true;
}
// e -> activate direct editing
if (key === 69) {
editorActions.trigger('directEditing');
@ -93,6 +103,7 @@ BpmnKeyBindings.$inject = [
'spaceTool',
'lassoTool',
'handTool',
'globalConnect',
'directEditing',
'searchPad',
'selection',

View File

@ -1,6 +1,7 @@
module.exports = {
__depends__: [
require('diagram-js/lib/features/keyboard')
require('diagram-js/lib/features/keyboard'),
require('../global-connect')
],
__init__: [ 'bpmnKeyBindings' ],
bpmnKeyBindings: [ 'type', require('./BpmnKeyBindings') ]

View File

@ -5,7 +5,7 @@ var assign = require('lodash/object/assign');
/**
* A palette provider for BPMN 2.0 elements.
*/
function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, translate) {
function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) {
this._palette = palette;
this._create = create;
@ -13,6 +13,7 @@ function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool,
this._spaceTool = spaceTool;
this._lassoTool = lassoTool;
this._handTool = handTool;
this._globalConnect = globalConnect;
this._translate = translate;
palette.registerProvider(this);
@ -27,8 +28,8 @@ PaletteProvider.$inject = [
'spaceTool',
'lassoTool',
'handTool',
'translate',
'eventBus'
'globalConnect',
'translate'
];
@ -40,6 +41,7 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
spaceTool = this._spaceTool,
lassoTool = this._lassoTool,
handTool = this._handTool,
globalConnect = this._globalConnect,
translate = this._translate;
function createAction(type, group, className, title, options) {
@ -106,6 +108,16 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
group: 'tools',
separator: true
},
'global-connect-tool': {
group: 'tools',
className: 'bpmn-icon-connection-multi',
title: translate('Activate the global connect tool'),
action: {
click: function(event) {
globalConnect.toggle(event);
}
}
},
'create.start-event': createAction(
'bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none'
),

View File

@ -5,7 +5,8 @@ module.exports = {
require('diagram-js/lib/features/space-tool'),
require('diagram-js/lib/features/lasso-tool'),
require('diagram-js/lib/features/hand-tool'),
require('diagram-js/lib/i18n/translate')
require('diagram-js/lib/i18n/translate'),
require('../global-connect')
],
__init__: [ 'paletteProvider' ],
paletteProvider: [ 'type', require('./PaletteProvider') ]

View File

@ -0,0 +1,61 @@
'use strict';
/* global bootstrapModeler, inject */
var modelingModule = require('../../../../lib/features/modeling'),
providerModule = require('../../../../lib/features/global-connect'),
coreModule = require('../../../../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

@ -46,7 +46,22 @@ describe('features - keyboard', function() {
it('should include triggers inside editorActions', inject(function(editorActions) {
// then
expect(editorActions.length()).to.equal(12);
expect(editorActions.length()).to.equal(13);
}));
it('should trigger lasso tool', inject(function(keyboard, globalConnect) {
sinon.spy(globalConnect, 'toggle');
// given
var e = createKeyEvent(container, 67, false);
// when
keyboard._keyHandler(e);
// then
expect(globalConnect.toggle.calledOnce).to.be.true;
}));

View File

@ -27,7 +27,7 @@ describe('features/palette', function() {
var entries = domQuery.all('.entry', paletteElement);
// then
expect(entries.length).to.equal(12);
expect(entries.length).to.equal(13);
}));
});