UNPKG

bpmn-js-properties-panel

Version:
331 lines (248 loc) 9.4 kB
'use strict'; var findExtension = require('../Helper').findExtension, findExtensions = require('../Helper').findExtensions; var createCamundaProperty = require('../CreateHelper').createCamundaProperty, createInputParameter = require('../CreateHelper').createInputParameter, createOutputParameter = require('../CreateHelper').createOutputParameter, createCamundaIn = require('../CreateHelper').createCamundaIn, createCamundaOut = require('../CreateHelper').createCamundaOut, createCamundaInWithBusinessKey = require('../CreateHelper').createCamundaInWithBusinessKey, createCamundaExecutionListenerScript = require('../CreateHelper').createCamundaExecutionListenerScript; var CAMUNDA_SERVICE_TASK_LIKE = [ 'camunda:class', 'camunda:delegateExpression', 'camunda:expression' ]; /** * A handler that changes the modeling template of a BPMN element. */ function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) { function getOrCreateExtensionElements(element) { var bo = element.businessObject; var extensionElements = bo.extensionElements; // add extension elements if (!extensionElements) { extensionElements = bpmnFactory.create('bpmn:ExtensionElements', { values: [] }); modeling.updateProperties(element, { extensionElements: extensionElements }); } return extensionElements; } function updateModelerTemplate(element, newTemplate) { modeling.updateProperties(element, { 'camunda:modelerTemplate': newTemplate && newTemplate.id }); } function updateIoMappings(element, newTemplate) { var extensionElements; var newMappings = createInputOutputMappings(newTemplate, bpmnFactory), oldMappings; if (newMappings) { extensionElements = getOrCreateExtensionElements(element); oldMappings = findExtension(element, 'camunda:InputOutput'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: [ newMappings ], objectsToRemove: oldMappings ? [ oldMappings ] : [] }); } } function updateCamundaProperties(element, newTemplate) { var extensionElements; var newProperties = createCamundaProperties(newTemplate, bpmnFactory), oldProperties; if (newProperties) { extensionElements = getOrCreateExtensionElements(element); oldProperties = findExtension(element, 'camunda:Properties'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: [ newProperties ], objectsToRemove: oldProperties ? [ oldProperties ] : [] }); } } function updateProperties(element, newTemplate) { var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory); if (Object.keys(newProperties).length > 0) { modeling.updateProperties(element, newProperties); } } function updateInOut(element, newTemplate) { var extensionElements; var newInOut = createCamundaInOut(newTemplate, bpmnFactory), oldInOut; if (newInOut) { extensionElements = getOrCreateExtensionElements(element); oldInOut = findExtensions(extensionElements, [ 'camunda:In', 'camunda:Out' ]); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: newInOut, objectsToRemove: oldInOut }); } } function updateExecutionListener(element, newTemplate) { var newExecutionListeners = createCamundaExecutionListener(newTemplate, bpmnFactory), oldExecutionsListeners; if (newExecutionListeners.length) { var extensionElements = getOrCreateExtensionElements(element); oldExecutionsListeners = findExtensions(extensionElements, [ 'camunda:ExecutionListener' ]); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: newExecutionListeners, objectsToRemove: oldExecutionsListeners }); } } /** * Compose an element template change action, updating all * necessary underlying properties. * * @param {Object} context * @param {Object} context.element * @param {Object} context.oldTemplate * @param {Object} context.newTemplate */ this.preExecute = function(context) { var element = context.element, newTemplate = context.newTemplate; // update camunda:modelerTemplate attribute updateModelerTemplate(element, newTemplate); if (newTemplate) { // update camunda:inputOutput updateIoMappings(element, newTemplate); // update camunda:properties updateCamundaProperties(element, newTemplate); // update other properties (bpmn:condition, camunda:async, ...) updateProperties(element, newTemplate); // update camunda:in and camunda:out updateInOut(element, newTemplate); // update camunda:executionListener updateExecutionListener(element, newTemplate); } }; } ChangeElementTemplateHandler.$inject = [ 'modeling', 'commandStack', 'bpmnFactory' ]; module.exports = ChangeElementTemplateHandler; /////// helpers ///////////////////////////// function createBpmnPropertyUpdates(template, bpmnFactory) { var propertyUpdates = {}; template.properties.forEach(function(p) { var binding = p.binding, bindingTarget = binding.name, propertyValue; if (binding.type === 'property') { if (bindingTarget === 'conditionExpression') { propertyValue = bpmnFactory.create('bpmn:FormalExpression', { body: p.value, language: binding.scriptFormat }); } else { propertyValue = p.value; } // assigning camunda:async to true|false // assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... } propertyUpdates[bindingTarget] = propertyValue; // make sure we unset other "implementation types" // when applying a camunda:class template onto a preconfigured // camunda:delegateExpression element if (CAMUNDA_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) { CAMUNDA_SERVICE_TASK_LIKE.forEach(function(prop) { if (prop !== bindingTarget) { propertyUpdates[prop] = undefined; } }); } } }); return propertyUpdates; } function createCamundaProperties(template, bpmnFactory) { var properties = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:property') { properties.push(createCamundaProperty( binding, p.value, bpmnFactory )); } }); if (properties.length) { return bpmnFactory.create('camunda:Properties', { values: properties }); } } function createInputOutputMappings(template, bpmnFactory) { var inputParameters = [], outputParameters = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:inputParameter') { inputParameters.push(createInputParameter( binding, p.value, bpmnFactory )); } if (bindingType === 'camunda:outputParameter') { outputParameters.push(createOutputParameter( binding, p.value, bpmnFactory )); } }); // do we need to create new ioMappings (?) if (outputParameters.length || inputParameters.length) { return bpmnFactory.create('camunda:InputOutput', { inputParameters: inputParameters, outputParameters: outputParameters }); } } function createCamundaInOut(template, bpmnFactory) { var inOuts = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:in') { inOuts.push(createCamundaIn( binding, p.value, bpmnFactory )); } else if (bindingType === 'camunda:out') { inOuts.push(createCamundaOut( binding, p.value, bpmnFactory )); } else if (bindingType === 'camunda:in:businessKey') { inOuts.push(createCamundaInWithBusinessKey( binding, p.value, bpmnFactory )); } }); return inOuts; } function createCamundaExecutionListener(template, bpmnFactory) { var executionListener = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:executionListener') { executionListener.push(createCamundaExecutionListenerScript( binding, p.value, bpmnFactory )); } }); return executionListener; }