mirror of
https://github.com/sartography/bpmn-js.git
synced 2025-02-18 11:56:30 +00:00
feat(context-pad): show delete only if allowed by rules
Related to bpmn-io/diagram-js#131
This commit is contained in:
parent
eb75fda7e0
commit
9322a6a1e6
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
var assign = require('lodash/object/assign'),
|
var assign = require('lodash/object/assign'),
|
||||||
forEach = require('lodash/collection/forEach'),
|
forEach = require('lodash/collection/forEach'),
|
||||||
|
isArray = require('lodash/lang/isArray'),
|
||||||
is = require('../../util/ModelUtil').is,
|
is = require('../../util/ModelUtil').is,
|
||||||
isAny = require('../modeling/util/ModelingUtil').isAny,
|
isAny = require('../modeling/util/ModelingUtil').isAny,
|
||||||
getChildLanes = require('../modeling/util/LaneUtil').getChildLanes,
|
getChildLanes = require('../modeling/util/LaneUtil').getChildLanes,
|
||||||
@ -14,7 +15,7 @@ var assign = require('lodash/object/assign'),
|
|||||||
*/
|
*/
|
||||||
function ContextPadProvider(contextPad, modeling, elementFactory,
|
function ContextPadProvider(contextPad, modeling, elementFactory,
|
||||||
connect, create, bpmnReplace,
|
connect, create, bpmnReplace,
|
||||||
canvas) {
|
canvas, rules) {
|
||||||
|
|
||||||
contextPad.registerProvider(this);
|
contextPad.registerProvider(this);
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ function ContextPadProvider(contextPad, modeling, elementFactory,
|
|||||||
this._create = create;
|
this._create = create;
|
||||||
this._bpmnReplace = bpmnReplace;
|
this._bpmnReplace = bpmnReplace;
|
||||||
this._canvas = canvas;
|
this._canvas = canvas;
|
||||||
|
this._rules = rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextPadProvider.$inject = [
|
ContextPadProvider.$inject = [
|
||||||
@ -36,7 +38,8 @@ ContextPadProvider.$inject = [
|
|||||||
'connect',
|
'connect',
|
||||||
'create',
|
'create',
|
||||||
'bpmnReplace',
|
'bpmnReplace',
|
||||||
'canvas'
|
'canvas',
|
||||||
|
'rules'
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = ContextPadProvider;
|
module.exports = ContextPadProvider;
|
||||||
@ -51,7 +54,8 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
|||||||
connect = this._connect,
|
connect = this._connect,
|
||||||
create = this._create,
|
create = this._create,
|
||||||
bpmnReplace = this._bpmnReplace,
|
bpmnReplace = this._bpmnReplace,
|
||||||
canvas = this._canvas;
|
canvas = this._canvas,
|
||||||
|
rules = this._rules;
|
||||||
|
|
||||||
var actions = {};
|
var actions = {};
|
||||||
|
|
||||||
@ -270,7 +274,15 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Element Entry
|
// delete element entry, only show if allowed by rules
|
||||||
|
var deleteAllowed = rules.allowed('elements.delete', { elements: [ element ]});
|
||||||
|
|
||||||
|
if (isArray(deleteAllowed)) {
|
||||||
|
// was the element returned as a deletion candidate?
|
||||||
|
deleteAllowed = deleteAllowed[0] === element;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleteAllowed) {
|
||||||
assign(actions, {
|
assign(actions, {
|
||||||
'delete': {
|
'delete': {
|
||||||
group: 'edit',
|
group: 'edit',
|
||||||
@ -282,6 +294,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return actions;
|
return actions;
|
||||||
};
|
};
|
||||||
|
@ -13,14 +13,15 @@ var contextPadModule = require('../../../../lib/features/context-pad'),
|
|||||||
coreModule = require('../../../../lib/core'),
|
coreModule = require('../../../../lib/core'),
|
||||||
modelingModule = require('../../../../lib/features/modeling'),
|
modelingModule = require('../../../../lib/features/modeling'),
|
||||||
popupModule = require('diagram-js/lib/features/popup-menu'),
|
popupModule = require('diagram-js/lib/features/popup-menu'),
|
||||||
replaceModule = require('diagram-js/lib/features/replace');
|
replaceModule = require('diagram-js/lib/features/replace'),
|
||||||
|
rulesModule = require('./rules');
|
||||||
|
|
||||||
|
|
||||||
describe('features - context-pad', function() {
|
describe('features - context-pad', function() {
|
||||||
|
|
||||||
var diagramXML = require('../../../fixtures/bpmn/simple.bpmn');
|
var diagramXML = require('../../../fixtures/bpmn/simple.bpmn');
|
||||||
|
|
||||||
var testModules = [ contextPadModule, coreModule, modelingModule, popupModule, replaceModule ];
|
var testModules = [ contextPadModule, coreModule, modelingModule, popupModule, replaceModule, rulesModule ];
|
||||||
|
|
||||||
beforeEach(bootstrapViewer(diagramXML, { modules: testModules }));
|
beforeEach(bootstrapViewer(diagramXML, { modules: testModules }));
|
||||||
|
|
||||||
@ -34,6 +35,121 @@ describe('features - context-pad', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('remove action rules', function () {
|
||||||
|
|
||||||
|
var deleteAction;
|
||||||
|
|
||||||
|
beforeEach(inject(function (contextPad) {
|
||||||
|
|
||||||
|
deleteAction = function(element) {
|
||||||
|
return domQuery('[data-action="delete"]', contextPad.getPad(element).html);
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should add delete action by default', inject(function (elementRegistry, contextPad) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
contextPad.open(element);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(deleteAction(element)).to.exist;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should include delete action when rule returns true', inject(function (elementRegistry, contextPad, customRules) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
customRules.addRule('elements.delete', function() {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
contextPad.open(element);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(deleteAction(element)).to.exist;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should NOT include delete action when rule returns false', inject(function(elementRegistry, contextPad, customRules) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
customRules.addRule('elements.delete', function() {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
contextPad.open(element);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(deleteAction(element)).to.not.exist;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should call rules with [ element ]', inject(function(elementRegistry, contextPad, customRules) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
customRules.addRule('elements.delete', function(context) {
|
||||||
|
|
||||||
|
// element array is actually passed
|
||||||
|
expect(context.elements).to.eql([ element ]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(function() {
|
||||||
|
contextPad.open(element);
|
||||||
|
}).not.to.throw;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should include delete action when [ element ] is returned from rule', inject(function(elementRegistry, contextPad, customRules) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
customRules.addRule('elements.delete', function(context) {
|
||||||
|
return context.elements;
|
||||||
|
});
|
||||||
|
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
contextPad.open(element);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(deleteAction(element)).to.exist;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should NOT include delete action when [ ] is returned from rule', inject(function(elementRegistry, contextPad, customRules) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
customRules.addRule('elements.delete', function() {
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
var element = elementRegistry.get('StartEvent_1');
|
||||||
|
|
||||||
|
// when
|
||||||
|
contextPad.open(element);
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(deleteAction(element)).to.not.exist;
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('should show replace popup menu in the correct position ', function() {
|
describe('should show replace popup menu in the correct position ', function() {
|
||||||
|
|
||||||
var container;
|
var container;
|
||||||
@ -66,5 +182,7 @@ describe('features - context-pad', function() {
|
|||||||
expect(replaceMenuRect.left).to.be.at.most(padMenuRect.left);
|
expect(replaceMenuRect.left).to.be.at.most(padMenuRect.left);
|
||||||
expect(replaceMenuRect.top).to.be.at.most(padMenuRect.bottom + padding);
|
expect(replaceMenuRect.top).to.be.at.most(padMenuRect.bottom + padding);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
15
test/spec/features/context-pad/rules/CustomRules.js
Normal file
15
test/spec/features/context-pad/rules/CustomRules.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var inherits = require('inherits');
|
||||||
|
|
||||||
|
var RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
|
||||||
|
|
||||||
|
function CustomRules(eventBus) {
|
||||||
|
RuleProvider.call(this, eventBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRules.$inject = [ 'eventBus' ];
|
||||||
|
|
||||||
|
inherits(CustomRules, RuleProvider);
|
||||||
|
|
||||||
|
module.exports = CustomRules;
|
4
test/spec/features/context-pad/rules/index.js
Normal file
4
test/spec/features/context-pad/rules/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
module.exports = {
|
||||||
|
__init__: [ 'customRules' ],
|
||||||
|
customRules: [ 'type', require('./CustomRules') ]
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user