You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

311 lines
7.4 KiB

import inherits from 'inherits-browser';
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
import {
getBusinessObject,
is
} from '../../../util/ModelUtil';
import {
createCategory,
createCategoryValue,
linkCategoryValue,
unlinkCategory,
unlinkCategoryValue
} from './util/CategoryUtil';
var LOWER_PRIORITY = 770;
/**
* BPMN specific Group behavior
*/
export default function GroupBehavior(
bpmnFactory,
bpmnjs,
elementRegistry,
eventBus,
injector,
moddleCopy
) {
injector.invoke(CommandInterceptor, this);
/**
* Returns all group element in the current registry
*
* @return {Array<djs.model.shape>} a list of group shapes
*/
function getGroupElements() {
return elementRegistry.filter(function(e) {
return is(e, 'bpmn:Group');
});
}
/**
* Returns true if given category is referenced in one of the given elements
*
* @param { djs.model.Element[] } elements
* @param { ModdleElement } category
*
* @return { boolean }
*/
function isReferencedCategory(elements, category) {
return elements.some(function(element) {
var businessObject = getBusinessObject(element);
var _category = businessObject.categoryValueRef && businessObject.categoryValueRef.$parent;
return _category === category;
});
}
/**
* Returns true if given categoryValue is referenced in one of the given elements
*
* @param { djs.model.Element[] } elements
* @param { ModdleElement } categoryValue
*
* @return { boolean }
*/
function isReferencedCategoryValue(elements, categoryValue) {
return elements.some(function(element) {
var businessObject = getBusinessObject(element);
return businessObject.categoryValueRef === categoryValue;
});
}
/**
* Remove category value unless it is still referenced
*
* @param {ModdleElement} categoryValue
* @param {ModdleElement} category
* @param {ModdleElement} businessObject
*/
function removeCategoryValue(categoryValue, category, businessObject) {
var groups = getGroupElements().filter(function(element) {
return element.businessObject !== businessObject;
});
if (category && !isReferencedCategory(groups, category)) {
unlinkCategory(category);
}
if (categoryValue && !isReferencedCategoryValue(groups, categoryValue)) {
unlinkCategoryValue(categoryValue);
}
}
/**
* Add category value
*
* @param {ModdleElement} categoryValue
* @param {ModdleElement} category
*/
function addCategoryValue(categoryValue, category) {
return linkCategoryValue(categoryValue, category, bpmnjs.getDefinitions());
}
function setCategoryValue(element, context) {
var businessObject = getBusinessObject(element),
categoryValue = businessObject.categoryValueRef;
if (!categoryValue) {
categoryValue =
businessObject.categoryValueRef =
context.categoryValue = (
context.categoryValue || createCategoryValue(bpmnFactory)
);
}
var category = categoryValue.$parent;
if (!category) {
category =
categoryValue.$parent =
context.category = (
context.category || createCategory(bpmnFactory)
);
}
addCategoryValue(categoryValue, category, bpmnjs.getDefinitions());
}
function unsetCategoryValue(element, context) {
var category = context.category,
categoryValue = context.categoryValue,
businessObject = getBusinessObject(element);
if (categoryValue) {
businessObject.categoryValueRef = null;
removeCategoryValue(categoryValue, category, businessObject);
} else {
removeCategoryValue(null, businessObject.categoryValueRef.$parent, businessObject);
}
}
// ensure category + value exist before label editing
this.execute('label.create', function(event) {
var context = event.context,
labelTarget = context.labelTarget;
if (!is(labelTarget, 'bpmn:Group')) {
return;
}
setCategoryValue(labelTarget, context);
});
this.revert('label.create', function(event) {
var context = event.context,
labelTarget = context.labelTarget;
if (!is(labelTarget, 'bpmn:Group')) {
return;
}
unsetCategoryValue(labelTarget, context);
});
// remove referenced category + value when group was deleted
this.execute('shape.delete', function(event) {
var context = event.context,
shape = context.shape,
businessObject = getBusinessObject(shape);
if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
return;
}
var categoryValue = context.categoryValue = businessObject.categoryValueRef,
category;
if (categoryValue) {
category = context.category = categoryValue.$parent;
removeCategoryValue(categoryValue, category, businessObject);
businessObject.categoryValueRef = null;
}
});
this.reverted('shape.delete', function(event) {
var context = event.context,
shape = context.shape;
if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
return;
}
var category = context.category,
categoryValue = context.categoryValue,
businessObject = getBusinessObject(shape);
if (categoryValue) {
businessObject.categoryValueRef = categoryValue;
addCategoryValue(categoryValue, category);
}
});
// create new category + value when group was created
this.execute('shape.create', function(event) {
var context = event.context,
shape = context.shape;
if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
return;
}
if (getBusinessObject(shape).categoryValueRef) {
setCategoryValue(shape, context);
}
});
this.reverted('shape.create', function(event) {
var context = event.context,
shape = context.shape;
if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
return;
}
if (getBusinessObject(shape).categoryValueRef) {
unsetCategoryValue(shape, context);
}
});
// copy + paste categoryValueRef with group
function copy(bo, clone) {
var targetBo = bpmnFactory.create(bo.$type);
return moddleCopy.copyElement(bo, targetBo, null, clone);
}
eventBus.on('copyPaste.copyElement', LOWER_PRIORITY, function(context) {
var descriptor = context.descriptor,
element = context.element;
if (!is(element, 'bpmn:Group') || element.labelTarget) {
return;
}
var groupBo = getBusinessObject(element);
if (groupBo.categoryValueRef) {
var categoryValue = groupBo.categoryValueRef;
descriptor.categoryValue = copy(categoryValue, true);
if (categoryValue.$parent) {
descriptor.category = copy(categoryValue.$parent, true);
}
}
});
eventBus.on('copyPaste.pasteElement', LOWER_PRIORITY, function(context) {
var descriptor = context.descriptor,
businessObject = descriptor.businessObject,
categoryValue = descriptor.categoryValue,
category = descriptor.category;
if (categoryValue) {
categoryValue = businessObject.categoryValueRef = copy(categoryValue);
}
if (category) {
categoryValue.$parent = copy(category);
}
delete descriptor.category;
delete descriptor.categoryValue;
});
}
GroupBehavior.$inject = [
'bpmnFactory',
'bpmnjs',
'elementRegistry',
'eventBus',
'injector',
'moddleCopy'
];
inherits(GroupBehavior, CommandInterceptor);