aboutsummaryrefslogtreecommitdiffstats
path: root/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation
diff options
context:
space:
mode:
Diffstat (limited to 'sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation')
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/Delegate.js78
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js289
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js173
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js424
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputUpdater.js74
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/ResultVariable.js52
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js89
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js226
-rw-r--r--sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js34
9 files changed, 1439 insertions, 0 deletions
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/Delegate.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/Delegate.js
new file mode 100644
index 00000000..f6a0b247
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/Delegate.js
@@ -0,0 +1,78 @@
+'use strict';
+
+import entryFactory from 'bpmn-js-properties-panel/lib/factory/EntryFactory';
+import cmdHelper from 'bpmn-js-properties-panel/lib/helper/CmdHelper';
+
+const DELEGATE_TYPES = ['class', 'expression', 'delegateExpression'];
+
+const PROPERTIES = {
+ class: 'camunda:class',
+ expression: 'camunda:expression',
+ delegateExpression: 'camunda:delegateExpression'
+};
+
+function isDelegate(type) {
+ return DELEGATE_TYPES.indexOf(type) !== -1;
+}
+
+function getAttribute(type) {
+ return PROPERTIES[type];
+}
+
+export default function(element, bpmnFactory, options, translate) {
+ var getImplementationType = options.getImplementationType,
+ getBusinessObject = options.getBusinessObject;
+
+ function getDelegationLabel(type) {
+ switch (type) {
+ case 'class':
+ return translate('Java Class');
+ case 'expression':
+ return translate('Expression');
+ case 'delegateExpression':
+ return translate('Delegate Expression');
+ default:
+ return '';
+ }
+ }
+
+ var delegateEntry = entryFactory.textField({
+ id: 'delegate',
+ label: translate('Value'),
+ dataValueLabel: 'delegationLabel',
+ modelProperty: 'delegate',
+
+ get: function(element) {
+ var bo = getBusinessObject(element);
+ var type = getImplementationType(element);
+ var attr = getAttribute(type);
+ var label = getDelegationLabel(type);
+ return {
+ delegate: bo.get(attr),
+ delegationLabel: label
+ };
+ },
+
+ set: function(element, values) {
+ var bo = getBusinessObject(element);
+ var type = getImplementationType(element);
+ var attr = getAttribute(type);
+ var prop = {};
+ prop[attr] = values.delegate || '';
+ return cmdHelper.updateBusinessObject(element, bo, prop);
+ },
+
+ validate: function(element, values) {
+ return isDelegate(getImplementationType(element)) &&
+ !values.delegate
+ ? { delegate: 'Must provide a value' }
+ : {};
+ },
+
+ hidden: function(element) {
+ return !isDelegate(getImplementationType(element));
+ }
+ });
+
+ return [delegateEntry];
+}
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js
new file mode 100644
index 00000000..2bbef4f2
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js
@@ -0,0 +1,289 @@
+import inputOutputHelper from './InputOutputHelper';
+var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
+
+var elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
+ extensionElementsHelper = require('bpmn-js-properties-panel/lib/helper/ExtensionElementsHelper'),
+ cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper');
+
+var extensionElementsEntry = require('bpmn-js-properties-panel/lib/provider/camunda/parts/implementation//ExtensionElements');
+
+function getInputOutput(element, insideConnector) {
+ return inputOutputHelper.getInputOutput(element, insideConnector);
+}
+
+function getConnector(element) {
+ return inputOutputHelper.getConnector(element);
+}
+
+function getInputParameters(element, insideConnector) {
+ return inputOutputHelper.getInputParameters(element, insideConnector);
+}
+
+function getOutputParameters(element, insideConnector) {
+ return inputOutputHelper.getOutputParameters(element, insideConnector);
+}
+
+function getInputParameter(element, insideConnector, idx) {
+ return inputOutputHelper.getInputParameter(element, insideConnector, idx);
+}
+
+function getOutputParameter(element, insideConnector, idx) {
+ return inputOutputHelper.getOutputParameter(element, insideConnector, idx);
+}
+
+export function createElement(type, parent, factory, properties) {
+ const el = elementHelper.createElement(type, properties, parent, factory);
+ return el;
+}
+
+export function createInputOutput(parent, bpmnFactory, properties) {
+ return createElement(
+ 'camunda:InputOutput',
+ parent,
+ bpmnFactory,
+ properties
+ );
+}
+
+function createParameter(type, parent, bpmnFactory, properties) {
+ return createElement(type, parent, bpmnFactory, properties);
+}
+
+function ensureInputOutputSupported(element, insideConnector) {
+ return inputOutputHelper.isInputOutputSupported(element, insideConnector);
+}
+
+function ensureOutparameterSupported(element, insideConnector) {
+ return inputOutputHelper.areOutputParametersSupported(
+ element,
+ insideConnector
+ );
+}
+
+export default function(element, bpmnFactory, options, translate) {
+ var TYPE_LABEL = {
+ 'camunda:Map': translate('Map'),
+ 'camunda:List': translate('List'),
+ 'camunda:Script': translate('Script')
+ };
+
+ options = options || {};
+
+ var insideConnector = !!options.insideConnector,
+ idPrefix = options.idPrefix || '';
+
+ var getSelected = function(element, node) {
+ var selection = (inputEntry &&
+ inputEntry.getSelected(element, node)) || { idx: -1 };
+
+ var parameter = getInputParameter(
+ element,
+ insideConnector,
+ selection.idx
+ );
+ if (!parameter && outputEntry) {
+ selection = outputEntry.getSelected(element, node);
+ parameter = getOutputParameter(
+ element,
+ insideConnector,
+ selection.idx
+ );
+ }
+ return parameter;
+ };
+
+ var result = {
+ getSelectedParameter: getSelected
+ };
+
+ var entries = (result.entries = []);
+
+ if (!ensureInputOutputSupported(element)) {
+ return result;
+ }
+
+ var newElement = function(type, prop, elementData) {
+ return function(element, extensionElements, value) {
+ var commands = [];
+
+ var inputOutput = getInputOutput(element, insideConnector);
+ if (!inputOutput) {
+ var parent = !insideConnector
+ ? extensionElements
+ : getConnector(element);
+
+ inputOutput = createInputOutput(parent, bpmnFactory, {
+ inputParameters: [],
+ outputParameters: []
+ });
+
+ if (!insideConnector) {
+ commands.push(
+ cmdHelper.addAndRemoveElementsFromList(
+ element,
+ extensionElements,
+ 'values',
+ 'extensionElements',
+ [inputOutput],
+ []
+ )
+ );
+ } else {
+ commands.push(
+ cmdHelper.updateBusinessObject(element, parent, {
+ inputOutput: inputOutput
+ })
+ );
+ }
+ }
+
+ var newElem = elementData
+ ? createParameter(type, inputOutput, bpmnFactory, elementData)
+ : createParameter(type, inputOutput, bpmnFactory, {
+ name: value
+ });
+
+ commands.push(
+ cmdHelper.addElementsTolist(element, inputOutput, prop, [
+ newElem
+ ])
+ );
+
+ return commands;
+ };
+ };
+
+ var removeElement = function(getter, prop, otherProp) {
+ return function(element, extensionElements, value, idx) {
+ var inputOutput = getInputOutput(element, insideConnector);
+ var parameter = getter(element, insideConnector, idx);
+
+ var commands = [];
+ commands.push(
+ cmdHelper.removeElementsFromList(
+ element,
+ inputOutput,
+ prop,
+ null,
+ [parameter]
+ )
+ );
+
+ var firstLength = inputOutput.get(prop).length - 1;
+ var secondLength = (inputOutput.get(otherProp) || []).length;
+
+ if (!firstLength && !secondLength) {
+ if (!insideConnector) {
+ commands.push(
+ extensionElementsHelper.removeEntry(
+ getBusinessObject(element),
+ element,
+ inputOutput
+ )
+ );
+ } else {
+ var connector = getConnector(element);
+ commands.push(
+ cmdHelper.updateBusinessObject(element, connector, {
+ inputOutput: undefined
+ })
+ );
+ }
+ }
+
+ return commands;
+ };
+ };
+
+ var setOptionLabelValue = function(getter) {
+ return function(element, node, option, property, value, idx) {
+ var parameter = getter(element, insideConnector, idx);
+
+ var suffix = 'Text';
+
+ var definition = parameter.get('definition');
+ if (typeof definition !== 'undefined') {
+ var type = definition.$type;
+ suffix = TYPE_LABEL[type];
+ }
+
+ option.text = (value || '') + ' : ' + suffix;
+ };
+ };
+
+ // input parameters ///////////////////////////////////////////////////////////////
+
+ var inputEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: idPrefix + 'inputs',
+ label: translate('Input Parameters'),
+ modelProperty: 'name',
+ prefix: 'Input',
+ resizable: true,
+
+ createExtensionElement: inputOutputHelper.isCreateDeleteSupported(
+ element
+ )
+ ? newElement('camunda:InputParameter', 'inputParameters')
+ : undefined,
+ removeExtensionElement: inputOutputHelper.isCreateDeleteSupported(
+ element
+ )
+ ? removeElement(
+ getInputParameter,
+ 'inputParameters',
+ 'outputParameters'
+ )
+ : undefined,
+
+ getExtensionElements: function(element) {
+ return getInputParameters(element, insideConnector);
+ },
+
+ onSelectionChange: function(element, node) {
+ outputEntry && outputEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(getInputParameter)
+ });
+ entries.push(inputEntry);
+
+ // output parameters ///////////////////////////////////////////////////////
+
+ if (ensureOutparameterSupported(element, insideConnector)) {
+ var outputEntry = extensionElementsEntry(element, bpmnFactory, {
+ id: idPrefix + 'outputs',
+ label: translate('Output Parameters'),
+ modelProperty: 'name',
+ prefix: 'Output',
+ resizable: true,
+
+ createExtensionElement: inputOutputHelper.isCreateDeleteSupported(
+ element
+ )
+ ? newElement('camunda:OutputParameter', 'outputParameters')
+ : undefined,
+ removeExtensionElement: inputOutputHelper.isCreateDeleteSupported(
+ element
+ )
+ ? removeElement(
+ getOutputParameter,
+ 'outputParameters',
+ 'inputParameters'
+ )
+ : inputOutputHelper.isCreateDeleteSupported(element),
+
+ getExtensionElements: function(element) {
+ return getOutputParameters(element, insideConnector);
+ },
+
+ onSelectionChange: function(element, node) {
+ inputEntry.deselect(element, node);
+ },
+
+ setOptionLabelValue: setOptionLabelValue(getOutputParameter)
+ });
+ entries.push(outputEntry);
+ }
+
+ return result;
+}
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js
new file mode 100644
index 00000000..595ab799
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js
@@ -0,0 +1,173 @@
+var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
+ is = ModelUtil.is,
+ getBusinessObject = ModelUtil.getBusinessObject;
+
+var extensionElementsHelper = require('bpmn-js-properties-panel/lib/helper/ExtensionElementsHelper'),
+ implementationTypeHelper = require('bpmn-js-properties-panel/lib/helper/ImplementationTypeHelper');
+import { implementationType } from './implementationConstants';
+
+var InputOutputHelper = {};
+
+function getElements(bo, type, prop) {
+ var elems = extensionElementsHelper.getExtensionElements(bo, type) || [];
+ return !prop ? elems : (elems[0] || {})[prop] || [];
+}
+
+function getParameters(element, prop, insideConnector) {
+ var inputOutput = InputOutputHelper.getInputOutput(
+ element,
+ insideConnector
+ );
+ return (inputOutput && inputOutput.get(prop)) || [];
+}
+
+/**
+ * Get a inputOutput from the business object
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {ModdleElement} the inputOutput object
+ */
+InputOutputHelper.getInputOutput = function(element, insideConnector) {
+ if (!insideConnector) {
+ var bo = getBusinessObject(element);
+ return (getElements(bo, 'camunda:InputOutput') || [])[0];
+ }
+ var connector = this.getConnector(element);
+
+ return connector && connector.get('inputOutput');
+};
+
+/**
+ * Get a connector from the business object
+ *
+ * @param {djs.model.Base} element
+ *
+ * @return {ModdleElement} the connector object
+ */
+InputOutputHelper.getConnector = function(element) {
+ var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+ return bo && (getElements(bo, 'camunda:Connector') || [])[0];
+};
+
+/**
+ * Return all input parameters existing in the business object, and
+ * an empty array if none exist.
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {Array} a list of input parameter objects
+ */
+InputOutputHelper.getInputParameters = function(element, insideConnector) {
+ return getParameters.apply(this, [
+ element,
+ 'inputParameters',
+ insideConnector
+ ]);
+};
+
+/**
+ * Return all output parameters existing in the business object, and
+ * an empty array if none exist.
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {Array} a list of output parameter objects
+ */
+InputOutputHelper.getOutputParameters = function(element, insideConnector) {
+ return getParameters.apply(this, [
+ element,
+ 'outputParameters',
+ insideConnector
+ ]);
+};
+
+/**
+ * Get a input parameter from the business object at given index
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ * @param {number} idx
+ *
+ * @return {ModdleElement} input parameter
+ */
+InputOutputHelper.getInputParameter = function(element, insideConnector, idx) {
+ return this.getInputParameters(element, insideConnector)[idx];
+};
+
+/**
+ * Get a output parameter from the business object at given index
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ * @param {number} idx
+ *
+ * @return {ModdleElement} output parameter
+ */
+InputOutputHelper.getOutputParameter = function(element, insideConnector, idx) {
+ return this.getOutputParameters(element, insideConnector)[idx];
+};
+
+/**
+ * Returns 'true' if the given element supports inputOutput
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {boolean} a boolean value
+ */
+InputOutputHelper.isInputOutputSupported = function(element, insideConnector) {
+ var bo = getBusinessObject(element);
+ return (
+ insideConnector ||
+ is(bo, 'bpmn:Process') ||
+ (is(bo, 'bpmn:FlowNode') &&
+ !is(bo, 'bpmn:StartEvent') &&
+ !is(bo, 'bpmn:BoundaryEvent') &&
+ !(is(bo, 'bpmn:SubProcess') && bo.get('triggeredByEvent')))
+ );
+};
+
+/**
+ * Returns 'true' if the given element supports output parameters
+ *
+ * @param {djs.model.Base} element
+ * @param {boolean} insideConnector
+ *
+ * @return {boolean} a boolean value
+ */
+InputOutputHelper.areOutputParametersSupported = function(
+ element,
+ insideConnector
+) {
+ var bo = getBusinessObject(element);
+ return (
+ insideConnector || (!is(bo, 'bpmn:EndEvent') && !bo.loopCharacteristics)
+ );
+};
+
+InputOutputHelper.isCreateDeleteSupported = function(element) {
+ const bo = getBusinessObject(element);
+ return (
+ (element.type !== 'bpmn:ServiceTask' ||
+ !bo[implementationType.ACTIVITY]) &&
+ element.type !== 'bpmn:Process'
+ );
+};
+
+InputOutputHelper.isWorkflowTargetSupported = function(element, selected) {
+ const bo = getBusinessObject(element);
+ return (
+ is(bo, 'bpmn:ServiceTask') && is(selected, 'camunda:OutputParameter')
+ );
+};
+
+InputOutputHelper.isWorkflowSourceSupported = function(element, selected) {
+ const bo = getBusinessObject(element);
+ return is(bo, 'bpmn:ServiceTask') && is(selected, 'camunda:InputParameter');
+};
+
+export default InputOutputHelper;
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js
new file mode 100644
index 00000000..10e258e3
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js
@@ -0,0 +1,424 @@
+import inputOutputHelper from './InputOutputHelper';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
+ cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper'),
+ utils = require('bpmn-js-properties-panel/lib/Utils');
+
+var entryFactory = require('bpmn-js-properties-panel/lib/factory/EntryFactory'),
+ script = require('bpmn-js-properties-panel/lib/provider/camunda/parts/implementation/Script')(
+ 'scriptFormat',
+ 'value',
+ true
+ );
+
+function createElement(type, parent, factory, properties) {
+ return elementHelper.createElement(type, properties, parent, factory);
+}
+
+function isScript(elem) {
+ return is(elem, 'camunda:Script');
+}
+
+function isList(elem) {
+ return is(elem, 'camunda:List');
+}
+
+function isMap(elem) {
+ return is(elem, 'camunda:Map');
+}
+
+function ensureInputOutputSupported(element, insideConnector) {
+ return inputOutputHelper.isInputOutputSupported(element, insideConnector);
+}
+
+export default function(element, bpmnFactory, options, translate) {
+ var typeInfo = {
+ 'camunda:Map': {
+ value: 'map',
+ label: translate('Map')
+ },
+ 'camunda:List': {
+ value: 'list',
+ label: translate('List')
+ },
+ 'camunda:Script': {
+ value: 'script',
+ label: translate('Script')
+ }
+ };
+
+ options = options || {};
+
+ var insideConnector = !!options.insideConnector,
+ idPrefix = options.idPrefix || '';
+
+ var getSelected = options.getSelectedParameter;
+
+ if (!ensureInputOutputSupported(element, insideConnector)) {
+ return [];
+ }
+
+ var entries = [];
+
+ var isSelected = function(element, node) {
+ return getSelected(element, node);
+ };
+
+ // parameter name ////////////////////////////////////////////////////////
+
+ entries.push(
+ entryFactory.validationAwareTextField({
+ id: idPrefix + 'parameterName',
+ label: 'Name',
+ modelProperty: 'name',
+
+ getProperty: function(element, node) {
+ return (getSelected(element, node) || {}).name;
+ },
+
+ setProperty: function(element, values, node) {
+ var param = getSelected(element, node);
+ return cmdHelper.updateBusinessObject(element, param, values);
+ },
+
+ validate: function(element, values, node) {
+ var bo = getSelected(element, node);
+
+ var validation = {};
+ if (bo) {
+ var nameValue = values.name;
+
+ if (nameValue) {
+ if (utils.containsSpace(nameValue)) {
+ validation.name = 'Name must not contain spaces';
+ }
+ } else {
+ validation.name = 'Parameter must have a name';
+ }
+ }
+
+ return validation;
+ },
+
+ hidden: function(element, node) {
+ return !isSelected(element, node);
+ },
+ disabled: function(element) {
+ return !inputOutputHelper.isCreateDeleteSupported(element);
+ }
+ })
+ );
+
+ // parameter type //////////////////////////////////////////////////////
+
+ var selectOptions = [
+ { value: 'text', name: 'Text' },
+ { value: 'script', name: 'Script' },
+ { value: 'list', name: 'List' },
+ { value: 'map', name: 'Map' }
+ ];
+
+ entries.push(
+ entryFactory.selectBox({
+ id: idPrefix + 'parameterType',
+ label: 'Type',
+ selectOptions: selectOptions,
+ modelProperty: 'parameterType',
+
+ get: function(element, node) {
+ var bo = getSelected(element, node);
+
+ var parameterType = 'text';
+
+ if (typeof bo !== 'undefined') {
+ var definition = bo.get('definition');
+ if (typeof definition !== 'undefined') {
+ var type = definition.$type;
+ parameterType = typeInfo[type].value;
+ }
+ }
+
+ return {
+ parameterType: parameterType
+ };
+ },
+
+ set: function(element, values, node) {
+ var bo = getSelected(element, node);
+
+ var properties = {
+ value: undefined,
+ definition: undefined
+ };
+
+ var createParameterTypeElem = function(type) {
+ return createElement(type, bo, bpmnFactory);
+ };
+
+ var parameterType = values.parameterType;
+
+ if (parameterType === 'script') {
+ properties.definition = createParameterTypeElem(
+ 'camunda:Script'
+ );
+ } else if (parameterType === 'list') {
+ properties.definition = createParameterTypeElem(
+ 'camunda:List'
+ );
+ } else if (parameterType === 'map') {
+ properties.definition = createParameterTypeElem(
+ 'camunda:Map'
+ );
+ }
+
+ return cmdHelper.updateBusinessObject(element, bo, properties);
+ },
+
+ show: function(element, node) {
+ return isSelected(element, node);
+ },
+ disabled: function(element) {
+ return !inputOutputHelper.isCreateDeleteSupported(element);
+ }
+ })
+ );
+
+ // parameter value (type = text) ///////////////////////////////////////////////////////
+
+ entries.push(
+ entryFactory.textBox({
+ id: idPrefix + 'parameterType-text',
+ label: 'Value',
+ modelProperty: 'value',
+ get: function(element, node) {
+ return {
+ value: (getSelected(element, node) || {}).value
+ };
+ },
+
+ set: function(element, values, node) {
+ var param = getSelected(element, node);
+ values.value = values.value || undefined;
+ return cmdHelper.updateBusinessObject(element, param, values);
+ },
+
+ show: function(element, node) {
+ var bo = getSelected(element, node);
+ return bo && !bo.definition;
+ }
+ })
+ );
+
+ // parameter value (type = script) ///////////////////////////////////////////////////////
+
+ entries.push({
+ id: idPrefix + 'parameterType-script',
+ html: '<div data-show="isScript">' + script.template + '</div>',
+ get: function(element, node) {
+ var bo = getSelected(element, node);
+ return bo && isScript(bo.definition)
+ ? script.get(element, bo.definition)
+ : {};
+ },
+
+ set: function(element, values, node) {
+ var bo = getSelected(element, node);
+ var update = script.set(element, values);
+ return cmdHelper.updateBusinessObject(
+ element,
+ bo.definition,
+ update
+ );
+ },
+
+ validate: function(element, values, node) {
+ var bo = getSelected(element, node);
+ return bo && isScript(bo.definition)
+ ? script.validate(element, bo.definition)
+ : {};
+ },
+
+ isScript: function(element, node) {
+ var bo = getSelected(element, node);
+ return bo && isScript(bo.definition);
+ },
+
+ script: script
+ });
+
+ // parameter value (type = list) ///////////////////////////////////////////////////////
+
+ entries.push(
+ entryFactory.table({
+ id: idPrefix + 'parameterType-list',
+ modelProperties: ['value'],
+ labels: ['Value'],
+
+ getElements: function(element, node) {
+ var bo = getSelected(element, node);
+
+ if (bo && isList(bo.definition)) {
+ return bo.definition.items;
+ }
+
+ return [];
+ },
+
+ updateElement: function(element, values, node, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+ return cmdHelper.updateBusinessObject(element, item, values);
+ },
+
+ addElement: function(element, node) {
+ var bo = getSelected(element, node);
+ var newValue = createElement(
+ 'camunda:Value',
+ bo.definition,
+ bpmnFactory,
+ { value: undefined }
+ );
+ return cmdHelper.addElementsTolist(
+ element,
+ bo.definition,
+ 'items',
+ [newValue]
+ );
+ },
+
+ removeElement: function(element, node, idx) {
+ var bo = getSelected(element, node);
+ return cmdHelper.removeElementsFromList(
+ element,
+ bo.definition,
+ 'items',
+ null,
+ [bo.definition.items[idx]]
+ );
+ },
+
+ editable: function(element, node, prop, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+ return !isMap(item) && !isList(item) && !isScript(item);
+ },
+
+ setControlValue: function(element, node, input, prop, value, idx) {
+ var bo = getSelected(element, node);
+ var item = bo.definition.items[idx];
+
+ if (!isMap(item) && !isList(item) && !isScript(item)) {
+ input.value = value;
+ } else {
+ input.value = typeInfo[item.$type].label;
+ }
+ },
+
+ show: function(element, node) {
+ var bo = getSelected(element, node);
+ return bo && bo.definition && isList(bo.definition);
+ }
+ })
+ );
+
+ // parameter value (type = map) ///////////////////////////////////////////////////////
+
+ entries.push(
+ entryFactory.table({
+ id: idPrefix + 'parameterType-map',
+ modelProperties: ['key', 'value'],
+ labels: ['Key', 'Value'],
+ addLabel: 'Add Entry',
+
+ getElements: function(element, node) {
+ var bo = getSelected(element, node);
+
+ if (bo && isMap(bo.definition)) {
+ return bo.definition.entries;
+ }
+
+ return [];
+ },
+
+ updateElement: function(element, values, node, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+
+ if (
+ isMap(entry.definition) ||
+ isList(entry.definition) ||
+ isScript(entry.definition)
+ ) {
+ values = {
+ key: values.key
+ };
+ }
+
+ return cmdHelper.updateBusinessObject(element, entry, values);
+ },
+
+ addElement: function(element, node) {
+ var bo = getSelected(element, node);
+ var newEntry = createElement(
+ 'camunda:Entry',
+ bo.definition,
+ bpmnFactory,
+ { key: undefined, value: undefined }
+ );
+ return cmdHelper.addElementsTolist(
+ element,
+ bo.definition,
+ 'entries',
+ [newEntry]
+ );
+ },
+
+ removeElement: function(element, node, idx) {
+ var bo = getSelected(element, node);
+ return cmdHelper.removeElementsFromList(
+ element,
+ bo.definition,
+ 'entries',
+ null,
+ [bo.definition.entries[idx]]
+ );
+ },
+
+ editable: function(element, node, prop, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+ return (
+ prop === 'key' ||
+ (!isMap(entry.definition) &&
+ !isList(entry.definition) &&
+ !isScript(entry.definition))
+ );
+ },
+
+ setControlValue: function(element, node, input, prop, value, idx) {
+ var bo = getSelected(element, node);
+ var entry = bo.definition.entries[idx];
+
+ if (
+ prop === 'key' ||
+ (!isMap(entry.definition) &&
+ !isList(entry.definition) &&
+ !isScript(entry.definition))
+ ) {
+ input.value = value;
+ } else {
+ input.value = typeInfo[entry.definition.$type].label;
+ }
+ },
+
+ show: function(element, node) {
+ var bo = getSelected(element, node);
+ return bo && bo.definition && isMap(bo.definition);
+ }
+ })
+ );
+
+ return entries;
+}
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputUpdater.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputUpdater.js
new file mode 100644
index 00000000..056a2dba
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputUpdater.js
@@ -0,0 +1,74 @@
+/*
+* Copyright © 2018 European Support Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*http://www.apache.org/licenses/LICENSE-2.0
+*
+ * Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import cmdHelper from 'bpmn-js-properties-panel/lib/helper/CmdHelper';
+import { createInputOutput, createElement } from './InputOutput';
+import InputOutputHelper from './InputOutputHelper';
+import { INPUT, OUTPUT } from './implementationConstants';
+
+export default ({ element, bo, bpmnFactory, activityInputsOutputs }) => {
+ const commands = [];
+ const existedInputOutput = InputOutputHelper.getInputOutput(element);
+
+ let newInputOutput = createInputOutput(element, bpmnFactory, {
+ inputParameters: [],
+ outputParameters: []
+ });
+
+ const inputs = activityInputsOutputs.inputs.map(({ name, value }) =>
+ createElement(INPUT, newInputOutput, bpmnFactory, {
+ name,
+ type: 'Text',
+ value
+ })
+ );
+
+ const outputs = activityInputsOutputs.outputs.map(({ name, value }) =>
+ createElement(OUTPUT, newInputOutput, bpmnFactory, {
+ name,
+ type: 'Text',
+ value
+ })
+ );
+
+ newInputOutput.inputParameters = inputs;
+ newInputOutput.outputParameters = outputs;
+
+ const objectToRemove = existedInputOutput ? [existedInputOutput] : [];
+ const extensionElements =
+ bo.extensionElements ||
+ createElement('bpmn:ExtensionElements', bo, bpmnFactory, []);
+
+ if (!bo.extensionElements) {
+ commands.push(
+ cmdHelper.updateBusinessObject(element, bo, {
+ extensionElements
+ })
+ );
+ }
+
+ commands.push(
+ cmdHelper.addAndRemoveElementsFromList(
+ element,
+ extensionElements,
+ 'values',
+ 'extensionElements',
+ [newInputOutput],
+ objectToRemove
+ )
+ );
+ return commands;
+};
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/ResultVariable.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/ResultVariable.js
new file mode 100644
index 00000000..a0b425fe
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/ResultVariable.js
@@ -0,0 +1,52 @@
+'use strict';
+
+import { is } from 'bpmn-js/lib/util/ModelUtil';
+
+import assign from 'lodash.assign';
+
+var entryFactory = require('bpmn-js-properties-panel/lib/factory/EntryFactory'),
+ cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper');
+
+export default function(element, bpmnFactory, options, translate) {
+ var getBusinessObject = options.getBusinessObject,
+ hideResultVariable = options.hideResultVariable,
+ id = options.id || 'resultVariable';
+
+ var resultVariableEntry = entryFactory.textField({
+ id: id,
+ label: translate('Result Variable'),
+ modelProperty: 'resultVariable',
+
+ get: function(element) {
+ var bo = getBusinessObject(element);
+ return { resultVariable: bo.get('camunda:resultVariable') };
+ },
+
+ set: function(element, values) {
+ var bo = getBusinessObject(element);
+
+ var resultVariable = values.resultVariable || undefined;
+
+ var props = {
+ 'camunda:resultVariable': resultVariable
+ };
+
+ if (is(bo, 'camunda:DmnCapable') && !resultVariable) {
+ props = assign(
+ { 'camunda:mapDecisionResult': 'resultList' },
+ props
+ );
+ }
+
+ return cmdHelper.updateBusinessObject(element, bo, props);
+ },
+
+ hidden: function() {
+ if (typeof hideResultVariable === 'function') {
+ return hideResultVariable.apply(resultVariableEntry, arguments);
+ }
+ }
+ });
+
+ return [resultVariableEntry];
+}
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js
new file mode 100644
index 00000000..6616f6a4
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js
@@ -0,0 +1,89 @@
+import entryFactory from 'bpmn-js-properties-panel/lib/factory/EntryFactory';
+import cmdHelper from 'bpmn-js-properties-panel/lib/helper/CmdHelper';
+import {
+ implementationType,
+ IMPLEMENTATION_TYPE_VALUE,
+ SERVICE_TASK_NAME
+} from './implementationConstants';
+
+import InputOutputUpdater from './InputOutputUpdater';
+
+const workflowActivity = (element, config, bpmnFactory, options, translate) => {
+ const { getImplementationType, getBusinessObject } = options;
+
+ const isWorkflowActivity = element =>
+ getImplementationType(element) === 'workflowActivity';
+
+ const workflowActivityEntry = entryFactory.selectBox({
+ id: 'activitySelect',
+ label: translate('Activity Spec'),
+ selectOptions: config.activities,
+ emptyParameter: true,
+ modelProperty: 'workflowActivity',
+
+ get: function(element) {
+ var bo = getBusinessObject(element);
+ const value = bo.get(implementationType.ACTIVITY);
+ const activityValue =
+ value && value.indexOf(IMPLEMENTATION_TYPE_VALUE) > -1
+ ? value.substr(IMPLEMENTATION_TYPE_VALUE.length)
+ : '';
+
+ return {
+ workflowActivity: activityValue
+ };
+ },
+
+ set: function(element, values) {
+ var bo = getBusinessObject(element);
+
+ const commands = [];
+ const dataForUpdate = {};
+
+ const activityInputsOutputs = config.getActivityInputsOutputs(
+ values.workflowActivity
+ );
+
+ dataForUpdate[
+ implementationType.ACTIVITY
+ ] = `${IMPLEMENTATION_TYPE_VALUE}${values.workflowActivity}`;
+
+ dataForUpdate[implementationType.EXPRESSION] =
+ implementationType.EXPRESSION_VALUE;
+
+ dataForUpdate[SERVICE_TASK_NAME] = values.workflowActivity;
+
+ commands.push(
+ cmdHelper.updateBusinessObject(element, bo, dataForUpdate)
+ );
+ return [
+ ...commands,
+ ...InputOutputUpdater({
+ element,
+ bo,
+ bpmnFactory,
+ activityInputsOutputs,
+ commands
+ })
+ ];
+ },
+
+ validate: function(element, values) {
+ const hasErrors =
+ isWorkflowActivity(element) && !values.workflowActivity;
+ config.validationUpdate(element, !hasErrors);
+
+ return hasErrors
+ ? { workflowActivity: 'Must provide a value' }
+ : {};
+ },
+
+ hidden: function(element) {
+ return !isWorkflowActivity(element);
+ }
+ });
+
+ return [workflowActivityEntry];
+};
+
+export default workflowActivity;
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js
new file mode 100644
index 00000000..729cc22b
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js
@@ -0,0 +1,226 @@
+var entryFactory = require('bpmn-js-properties-panel/lib/factory/EntryFactory'),
+ cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper'),
+ extensionElementsHelper = require('bpmn-js-properties-panel/lib/helper/ExtensionElementsHelper'),
+ elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper');
+
+var assign = require('lodash.assign');
+var map = require('lodash.map');
+import { implementationType } from './implementationConstants';
+
+var DEFAULT_DELEGATE_PROPS = ['class', 'expression', 'delegateExpression'];
+
+var DELEGATE_PROPS = {
+ 'camunda:class': undefined,
+ 'camunda:expression': undefined,
+ 'camunda:delegateExpression': undefined,
+ 'camunda:resultVariable': undefined
+};
+
+var DMN_CAPABLE_PROPS = {
+ 'camunda:decisionRef': undefined,
+ 'camunda:decisionRefBinding': 'latest',
+ 'camunda:decisionRefVersion': undefined,
+ 'camunda:mapDecisionResult': 'resultList',
+ 'camunda:decisionRefTenantId': undefined
+};
+
+var EXTERNAL_CAPABLE_PROPS = {
+ 'camunda:type': undefined,
+ 'camunda:topic': undefined
+};
+
+const ACTIVITY_PROPS = {};
+
+ACTIVITY_PROPS[implementationType] = undefined;
+
+export default function(element, bpmnFactory, options, translate) {
+ var DEFAULT_OPTIONS = [
+ { value: 'class', name: translate('Java Class') },
+ { value: 'expression', name: translate('Expression') },
+ { value: 'delegateExpression', name: translate('Delegate Expression') }
+ ];
+
+ var DMN_OPTION = [{ value: 'dmn', name: translate('DMN') }];
+
+ var EXTERNAL_OPTION = [{ value: 'external', name: translate('External') }];
+
+ var CONNECTOR_OPTION = [
+ { value: 'connector', name: translate('Connector') }
+ ];
+
+ var SCRIPT_OPTION = [{ value: 'script', name: translate('Script') }];
+
+ var ACTIVITY_OPTION = [
+ { value: 'workflowActivity', name: translate('Activity') }
+ ];
+
+ var getType = options.getImplementationType,
+ getBusinessObject = options.getBusinessObject;
+
+ var hasDmnSupport = options.hasDmnSupport,
+ hasExternalSupport = options.hasExternalSupport,
+ hasServiceTaskLikeSupport = options.hasServiceTaskLikeSupport,
+ hasScriptSupport = options.hasScriptSupport;
+
+ var entries = [];
+
+ var selectOptions = DEFAULT_OPTIONS.concat([]);
+
+ if (hasDmnSupport) {
+ selectOptions = selectOptions.concat(DMN_OPTION);
+ }
+
+ if (hasExternalSupport) {
+ selectOptions = selectOptions.concat(EXTERNAL_OPTION);
+ }
+
+ if (hasServiceTaskLikeSupport) {
+ selectOptions = selectOptions.concat(CONNECTOR_OPTION);
+ }
+
+ if (hasScriptSupport) {
+ selectOptions = selectOptions.concat(SCRIPT_OPTION);
+ }
+
+ selectOptions = selectOptions.concat(ACTIVITY_OPTION);
+
+ selectOptions.push({ value: '' });
+
+ entries.push(
+ entryFactory.selectBox({
+ id: 'implementation',
+ label: translate('Implementation'),
+ selectOptions: selectOptions,
+ modelProperty: 'implType',
+
+ get: function(element) {
+ return {
+ implType: getType(element) || ''
+ };
+ },
+
+ set: function(element, values) {
+ var bo = getBusinessObject(element);
+ var oldType = getType(element);
+ var newType = values.implType;
+ var props = assign({}, DELEGATE_PROPS);
+
+ if (DEFAULT_DELEGATE_PROPS.indexOf(newType) !== -1) {
+ var newValue = '';
+ if (DEFAULT_DELEGATE_PROPS.indexOf(oldType) !== -1) {
+ newValue = bo.get('camunda:' + oldType);
+ }
+
+ props['camunda:' + newType] = newValue;
+ }
+
+ if (hasDmnSupport) {
+ props = assign(props, DMN_CAPABLE_PROPS);
+ if (newType === 'dmn') {
+ props['camunda:decisionRef'] = '';
+ }
+ }
+
+ if (hasExternalSupport) {
+ props = assign(props, EXTERNAL_CAPABLE_PROPS);
+ if (newType === 'external') {
+ props['camunda:type'] = 'external';
+ props['camunda:topic'] = '';
+ }
+ }
+
+ if (hasScriptSupport) {
+ props['camunda:script'] = undefined;
+
+ if (newType === 'script') {
+ props['camunda:script'] = elementHelper.createElement(
+ 'camunda:Script',
+ {},
+ bo,
+ bpmnFactory
+ );
+ }
+ }
+ props = assign(props, ACTIVITY_PROPS);
+ props[implementationType.ACTIVITY] = undefined;
+
+ var commands = [];
+ if (newType === 'workflowActivity') {
+ props[implementationType.ACTIVITY] = '';
+ props[implementationType.RESULT_VARIABLE] = undefined;
+ props[implementationType.EXPRESSION] = undefined;
+ } else {
+ var inputsOutputs = extensionElementsHelper.getExtensionElements(
+ bo,
+ 'camunda:InputOutput'
+ );
+ commands.push(
+ map(inputsOutputs, function(inputOutput) {
+ return extensionElementsHelper.removeEntry(
+ bo,
+ element,
+ inputOutput
+ );
+ })
+ );
+ }
+
+ commands.push(
+ cmdHelper.updateBusinessObject(element, bo, props)
+ );
+
+ if (hasServiceTaskLikeSupport) {
+ var connectors = extensionElementsHelper.getExtensionElements(
+ bo,
+ 'camunda:Connector'
+ );
+ commands.push(
+ map(connectors, function(connector) {
+ return extensionElementsHelper.removeEntry(
+ bo,
+ element,
+ connector
+ );
+ })
+ );
+
+ if (newType === 'connector') {
+ var extensionElements = bo.get('extensionElements');
+ if (!extensionElements) {
+ extensionElements = elementHelper.createElement(
+ 'bpmn:ExtensionElements',
+ { values: [] },
+ bo,
+ bpmnFactory
+ );
+ commands.push(
+ cmdHelper.updateBusinessObject(element, bo, {
+ extensionElements: extensionElements
+ })
+ );
+ }
+ var connector = elementHelper.createElement(
+ 'camunda:Connector',
+ {},
+ extensionElements,
+ bpmnFactory
+ );
+ commands.push(
+ cmdHelper.addAndRemoveElementsFromList(
+ element,
+ extensionElements,
+ 'values',
+ 'extensionElements',
+ [connector],
+ []
+ )
+ );
+ }
+ }
+ return commands;
+ }
+ })
+ );
+
+ return entries;
+}
diff --git a/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js
new file mode 100644
index 00000000..efc70800
--- /dev/null
+++ b/sdc-workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js
@@ -0,0 +1,34 @@
+/*
+* Copyright © 2018 European Support Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*http://www.apache.org/licenses/LICENSE-2.0
+*
+ * Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+export const implementationType = {
+ ACTIVITY: 'implementation',
+ EXPRESSION: 'camunda:expression',
+ EXPRESSION_VALUE: '${ExecuteActivity.execute(execution)}',
+ RESULT_VARIABLE: 'camunda:resultVariable'
+};
+
+export const IMPLEMENTATION_TYPE_VALUE = 'activity:';
+export const SERVICE_TASK_NAME = 'name';
+
+export const serviceTaskEntries = {
+ IMPLEMENTATION: 'implementation',
+ DELEGATE: 'delegate',
+ RESULT_VARIABLE: 'resultVariable'
+};
+
+export const INPUT = 'camunda:InputParameter';
+export const OUTPUT = 'camunda:OutputParameter';