wf composition
Issue-ID: SDC-1591
Change-Id: I3d1c1e08094a2088b8e474b0c6f3616088ded4ee
Signed-off-by: Stanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
diff --git a/workflow-designer-ui/src/main/frontend/package.json b/workflow-designer-ui/src/main/frontend/package.json
index e3c657e..5271dc5 100644
--- a/workflow-designer-ui/src/main/frontend/package.json
+++ b/workflow-designer-ui/src/main/frontend/package.json
@@ -14,9 +14,8 @@
},
"dependencies": {
"axios": "^0.18.0",
- "bpmn-js": "^2.3.0",
- "bpmn-js-properties-panel": "^0.20.0",
- "camunda-bpmn-moddle": "^3.0.0",
+ "bpmn-js": "^2.4.1",
+ "bpmn-js-properties-panel": "^0.26.1",
"classnames": "^2.2.6",
"d3-hierarchy": "^1.1.6",
"d3-selection": "^1.3.0",
@@ -25,7 +24,12 @@
"enzyme-adapter-react-16": "^1.1.1",
"file-saver": "^1.3.8",
"http-proxy-middleware": "^0.17.4",
- "lodash": "^3.0.1",
+ "inherits": "^2.0.3",
+ "lodash.assign": "^4.2.0",
+ "lodash.isempty": "^4.4.0",
+ "lodash.map": "^4.6.0",
+ "lodash.merge": "^4.6.1",
+ "lodash.set": "^4.3.2",
"md5": "^2.2.1",
"moment": "^2.18.1",
"prop-types": "^15.6.1",
diff --git a/workflow-designer-ui/src/main/frontend/resources/scss/common/_customVariables.scss b/workflow-designer-ui/src/main/frontend/resources/scss/common/_customVariables.scss
index 1a532c8..5e5bef8 100644
--- a/workflow-designer-ui/src/main/frontend/resources/scss/common/_customVariables.scss
+++ b/workflow-designer-ui/src/main/frontend/resources/scss/common/_customVariables.scss
@@ -1,6 +1,9 @@
$cursor-disabled: not-allowed !default;
$cursor-pointer: pointer;
+$camunda-panel-error-border-color: #cc3333;
+$camunda-panel-error-background-color: #f0c2c2;
+
@mixin body-1-emphasis() {
@include base-font-semibold;
font-size: $body-font-1;
diff --git a/workflow-designer-ui/src/main/frontend/resources/scss/features/_composition.scss b/workflow-designer-ui/src/main/frontend/resources/scss/features/_composition.scss
index 119bbf0..6554219 100644
--- a/workflow-designer-ui/src/main/frontend/resources/scss/features/_composition.scss
+++ b/workflow-designer-ui/src/main/frontend/resources/scss/features/_composition.scss
@@ -7,19 +7,37 @@
flex-grow: 1
}
.bpmn-sidebar {
+ background-color: $light-silver;
height: 100%;
width: 320px;
+ height: 100%;
+ label {
+ @include body-1;
+ }
+ .group-label {
+ @include heading-4-emphasis;
+ font-size: 110%;
+ }
.properties-panel {
+ background-color: $light-silver;
+ max-height: 888px;
+ overflow-y: auto;
&, .bpp-properties-panel {
- height: 100%;
+ background-color: $light-silver;
+ #camunda-activitySelect-select {
+ &.invalid {
+ border-color: $camunda-panel-error-border-color;
+ background-color: $camunda-panel-error-background-color;
+ }
+ }
}
}
.composition-buttons {
position: fixed;
- background-color: #fafafa;
+ background-color: $light-silver;
left: 265px;
bottom: 46px;
- border: 1px solid lightgray;
+ border: 1px solid $light-gray;
width: 189px;
display: flex;
flex-direction: row;
@@ -29,7 +47,7 @@
padding: 10px;
.divider {
height: 35px;
- border: 1px solid $silver;
+ border: 1px solid $light-gray;
}
.diagram-btn {
diff --git a/workflow-designer-ui/src/main/frontend/resources/scss/features/_overview.scss b/workflow-designer-ui/src/main/frontend/resources/scss/features/_overview.scss
index 24f632d..e299fa3 100644
--- a/workflow-designer-ui/src/main/frontend/resources/scss/features/_overview.scss
+++ b/workflow-designer-ui/src/main/frontend/resources/scss/features/_overview.scss
@@ -59,10 +59,27 @@
}
.overview-header {
- @include heading-1;
- text-transform: uppercase;
- margin: 63px 0 35px 56px;
+ display: flex;
+ margin: 35px 60px 35px 60px;
color: $blue;
+ justify-content: space-between;
+ .title {
+ @include heading-1;
+ text-transform: uppercase;
+ }
+ .go-catalog-btn {
+ fill: $blue;
+ @include heading-4;
+ &:hover {
+ fill: $light-blue;
+ color: $light-blue;
+ cursor: pointer;
+ }
+ .svg-icon {
+ width: 16px;
+ height: 16px;
+ }
+ }
}
@mixin version-page-box-shadow() {
diff --git a/workflow-designer-ui/src/main/frontend/src/config/Configuration.js b/workflow-designer-ui/src/main/frontend/src/config/Configuration.js
index 3e558da..36ad33d 100644
--- a/workflow-designer-ui/src/main/frontend/src/config/Configuration.js
+++ b/workflow-designer-ui/src/main/frontend/src/config/Configuration.js
@@ -53,6 +53,10 @@
'restCatalogPrefix',
configuration.get('defaultRestCatalogPrefix')
);
+ configuration.set(
+ 'activitiesRestPrefix',
+ configuration.get('activitiesRestPrefix')
+ );
configuration.set('appContextPath', configuration.get('appContextPath'));
})(configuration);
diff --git a/workflow-designer-ui/src/main/frontend/src/config/config.json b/workflow-designer-ui/src/main/frontend/src/config/config.json
index f112144..eb7d181 100644
--- a/workflow-designer-ui/src/main/frontend/src/config/config.json
+++ b/workflow-designer-ui/src/main/frontend/src/config/config.json
@@ -1,5 +1,6 @@
{
"version": "0.1",
"appContextPath" : "/",
- "defaultRestPrefix": "/wf"
+ "defaultRestPrefix": "/wf",
+ "activitiesRestPrefix": "/v1.0"
}
diff --git a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesActions.js b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesActions.js
index ab0a3c4..833f6e5 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesActions.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesActions.js
@@ -1,6 +1,25 @@
-import { SET_ACTIVITIES_LIST } from './activitiesConstants';
+/*
+* 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 { SET_ACTIVITIES_LIST, GET_ACTIVITIES } from './activitiesConstants';
export const setActivitiesList = payload => ({
type: SET_ACTIVITIES_LIST,
payload
});
+
+export const getActivitiesList = () => ({
+ type: GET_ACTIVITIES
+});
diff --git a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesApi.js b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesApi.js
index 8e1afc1..10141e0 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesApi.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesApi.js
@@ -13,13 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import RestfulAPIUtil from 'services/restAPIUtil';
+import Configuration from 'config/Configuration.js';
+import { activityStatus } from './activitiesConstants';
-const mockActivities = {
- results: []
-};
+function baseUrl() {
+ const restPrefix = Configuration.get('activitiesRestPrefix');
+ return `${restPrefix}/activity-spec`;
+}
export default {
fetchActivities: () => {
- return Promise.resolve(mockActivities);
+ return RestfulAPIUtil.fetch(
+ `${baseUrl()}?status=${activityStatus.CERTIFIED}`
+ );
+ },
+
+ fetchActivity: id => {
+ return RestfulAPIUtil.fetch(`${baseUrl()}/${id}/versions/latest`);
}
};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesConstants.js b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesConstants.js
index 54aed6a..f99789c 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesConstants.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesConstants.js
@@ -14,3 +14,11 @@
* limitations under the License.
*/
export const SET_ACTIVITIES_LIST = 'activites/SET_ACTIVITIES_LIST';
+export const GET_ACTIVITIES = 'activities/GET_ACTIVITIES';
+
+export const activityStatus = {
+ CERTIFIED: 'Certified',
+ DRAFT: 'Draft',
+ DEPRICATED: 'Depricated',
+ DELETED: 'Deleted'
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSaga.js b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSaga.js
new file mode 100644
index 0000000..2350b9c
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSaga.js
@@ -0,0 +1,41 @@
+/*
+* 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 { call, put, takeEvery, all } from 'redux-saga/effects';
+import { genericNetworkErrorAction } from 'src/appConstants';
+import { GET_ACTIVITIES } from './activitiesConstants';
+import activitiesApi from './activitiesApi';
+import { setActivitiesList } from './activitiesActions';
+
+function* fetchActivities() {
+ try {
+ const activitiesList = yield call(activitiesApi.fetchActivities);
+ const updatedActivitiesList = yield all(
+ activitiesList.items.map(item =>
+ call(activitiesApi.fetchActivity, item.id)
+ )
+ );
+
+ yield put(setActivitiesList(updatedActivitiesList));
+ } catch (error) {
+ yield put(genericNetworkErrorAction(error));
+ }
+}
+
+function* activitiesSaga() {
+ yield takeEvery(GET_ACTIVITIES, fetchActivities);
+}
+
+export default activitiesSaga;
diff --git a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSelectors.js b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSelectors.js
index 47a0975..fc0c55a 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSelectors.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/activities/activitiesSelectors.js
@@ -14,4 +14,9 @@
* limitations under the License.
*/
-export const activitiesSelector = state => state && state.activities;
+export const activitiesSelector = state =>
+ state &&
+ state.activities.map(item => ({
+ ...item,
+ value: item.name
+ }));
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js
index d322207..ef48acd 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js
@@ -21,12 +21,14 @@
import { getComposition } from './compositionSelectors';
import { getWorkflowName } from '../../workflow/workflowSelectors';
import { activitiesSelector } from 'features/activities/activitiesSelectors';
+import { getInputOutputForComposition } from 'features/version/inputOutput/inputOutputSelectors';
function mapStateToProps(state) {
return {
composition: getComposition(state),
name: getWorkflowName(state),
- activities: activitiesSelector(state)
+ activities: activitiesSelector(state),
+ inputOutput: getInputOutputForComposition(state)
};
}
@@ -40,7 +42,7 @@
title: I18n.t('workflow.composition.bpmnError'),
body: msg,
withButtons: true,
- closeButtonText: 'Ok'
+ closeButtonText: I18n.t('buttons.okBtn')
})
)
};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js
index f47a6ec..012ee76 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js
@@ -17,23 +17,28 @@
import fileSaver from 'file-saver';
import CustomModeler from './custom-modeler';
import propertiesPanelModule from 'bpmn-js-properties-panel';
-import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
-import camundaModuleDescriptor from 'camunda-bpmn-moddle/resources/camunda';
+import propertiesProviderModule from './custom-properties-provider/provider/camunda';
+import camundaModuleDescriptor from './custom-properties-provider/descriptors/camunda';
import newDiagramXML from './newDiagram.bpmn';
import PropTypes from 'prop-types';
import CompositionButtons from './components/CompositionButtonsPanel';
+import { setElementInputsOutputs } from './bpmnUtils.js';
+import { I18n } from 'react-redux-i18n';
class CompositionView extends Component {
static propTypes = {
compositionUpdate: PropTypes.func,
showErrorModal: PropTypes.func,
- composition: PropTypes.bool,
- name: PropTypes.string
+ composition: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
+ name: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
+ inputOutput: PropTypes.object,
+ activities: PropTypes.array
};
constructor() {
super();
this.generatedId = 'bpmn-container' + Date.now();
this.fileInput = React.createRef();
+ this.selectedElement = false;
this.state = {
diagram: false
};
@@ -52,44 +57,59 @@
],
moddleExtensions: {
camunda: camundaModuleDescriptor
+ },
+ workflow: {
+ activities: this.props.activities,
+ onChange: this.onActivityChanged
}
});
- window.modeler = this.modeler;
- this.modeler.attachTo('#' + this.generatedId);
- this.setDiagram(composition ? composition : newDiagramXML);
- var eventBus = this.modeler.get('eventBus');
- eventBus.on('element.out', () => {
- this.exportDiagramToStore();
- });
- }
- setDiagram = diagram => {
- this.setState(
- {
- diagram
- },
- this.importXML
+ this.modeler.attachTo('#' + this.generatedId);
+ this.setDiagramToBPMN(composition ? composition : newDiagramXML);
+ this.modeler.on('element.out', () => this.exportDiagramToStore());
+ }
+ onActivityChanged = async (bo, selectedValue) => {
+ const selectedActivity = this.props.activities.find(
+ el => el.name === selectedValue
);
+
+ if (selectedActivity) {
+ const inputsOutputs = {
+ inputs: selectedActivity.inputs,
+ outputs: selectedActivity.outputs
+ };
+ setElementInputsOutputs(
+ bo,
+ inputsOutputs,
+ this.modeler.get('moddle')
+ );
+ }
};
- importXML = () => {
- const { diagram } = this.state;
+ setDiagramToBPMN = diagram => {
let modeler = this.modeler;
this.modeler.importXML(diagram, err => {
if (err) {
- //TDOD add i18n
- return this.props.showErrorModal('could not import diagram');
+ return this.props.showErrorModal(
+ I18n.t('workflow.composition.importErrorMsg')
+ );
}
let canvas = modeler.get('canvas');
canvas.zoom('fit-viewport');
+ setElementInputsOutputs(
+ canvas._rootElement.businessObject,
+ this.props.inputOutput,
+ this.modeler.get('moddle')
+ );
});
};
exportDiagramToStore = () => {
this.modeler.saveXML({ format: true }, (err, xml) => {
if (err) {
- //TODO add i18n
- return this.props.showErrorModal('could not save diagram');
+ return this.props.showErrorModal(
+ I18n.t('workflow.composition.saveErrorMsg')
+ );
}
return this.props.compositionUpdate(xml);
});
@@ -99,8 +119,9 @@
const { name, showErrorModal } = this.props;
this.modeler.saveXML({ format: true }, (err, xml) => {
if (err) {
- //TODO add i18n
- return showErrorModal('could not save diagram');
+ return showErrorModal(
+ I18n.t('workflow.composition.exportErrorMsg')
+ );
}
const blob = new Blob([xml], { type: 'text/html;charset=utf-8' });
fileSaver.saveAs(blob, `${name}-diagram.bpmn`);
@@ -108,7 +129,7 @@
};
loadNewDiagram = () => {
- this.setDiagram(newDiagramXML);
+ this.setDiagramToBPMN(newDiagramXML);
};
uploadDiagram = () => {
@@ -120,7 +141,7 @@
const reader = new FileReader();
reader.onloadend = event => {
var xml = event.target.result;
- this.setDiagram(xml);
+ this.setDiagramToBPMN(xml);
this.fileInput.value = '';
};
reader.readAsText(file);
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/bpmnUtils.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/bpmnUtils.js
new file mode 100644
index 0000000..adc4286
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/bpmnUtils.js
@@ -0,0 +1,77 @@
+/*
+* 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 { bpmnElementsTypes } from './compositionConstants';
+function getExtension(element, type) {
+ if (!element.extensionElements || !element.extensionElements.values) {
+ return null;
+ }
+
+ return element.extensionElements.values.filter(function(e) {
+ return e.$instanceOf(type);
+ })[0];
+}
+
+export function updatedData(moddle, inputData, existingArray, type) {
+ return inputData.map(item => {
+ const existingInput = existingArray.find(el => el.name === item.name);
+ return moddle.create(
+ type,
+ existingInput ? { ...item, value: existingInput.value } : item
+ );
+ });
+}
+
+export function setElementInputsOutputs(businessObject, inputOutput, moddle) {
+ const { inputs = [], outputs = [] } = inputOutput;
+
+ if (!businessObject.extensionElements) {
+ businessObject.extensionElements = moddle.create(
+ bpmnElementsTypes.EXTENSION_ElEMENTS
+ );
+ }
+
+ const existingInputOutput = getExtension(
+ businessObject,
+ bpmnElementsTypes.INPUT_OUTPUT
+ );
+
+ const processInputs = updatedData(
+ moddle,
+ inputs,
+ (existingInputOutput && existingInputOutput.inputParameters) || [],
+ bpmnElementsTypes.INPUT_PARAMETER
+ );
+
+ const processOutputs = updatedData(
+ moddle,
+ outputs,
+ (existingInputOutput && existingInputOutput.outputParameters) || [],
+ bpmnElementsTypes.OUTPUT_PARAMETER
+ );
+
+ const processInputOutput = moddle.create(bpmnElementsTypes.INPUT_OUTPUT);
+ processInputOutput.inputParameters = [...processInputs];
+ processInputOutput.outputParameters = [...processOutputs];
+
+ const extensionElements = businessObject.extensionElements.get('values');
+
+ businessObject.extensionElements.set(
+ 'values',
+ extensionElements
+ .filter(item => item.$type !== bpmnElementsTypes.INPUT_OUTPUT)
+ .concat(processInputOutput)
+ );
+}
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js
index 74cab0c..499e8ef 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js
@@ -14,3 +14,10 @@
* limitations under the License.
*/
export const SET_COMPOSITION = 'composition/SET_COMPOSITION';
+
+export const bpmnElementsTypes = {
+ EXTENSION_ElEMENTS: 'bpmn:ExtensionElements',
+ INPUT_OUTPUT: 'camunda:InputOutput',
+ INPUT_PARAMETER: 'camunda:InputParameter',
+ OUTPUT_PARAMETER: 'camunda:OutputParameter'
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/descriptors/camunda.json b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/descriptors/camunda.json
new file mode 100644
index 0000000..80e876a
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/descriptors/camunda.json
@@ -0,0 +1,1020 @@
+{
+ "name": "Camunda",
+ "uri": "http://camunda.org/schema/1.0/bpmn",
+ "prefix": "camunda",
+ "xml": {
+ "tagAlias": "lowerCase"
+ },
+ "associations": [],
+ "types": [
+ {
+ "name": "InOutBinding",
+ "superClass": ["Element"],
+ "isAbstract": true,
+ "properties": [
+ {
+ "name": "source",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "sourceExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "target",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "businessKey",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "local",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "variables",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "In",
+ "superClass": ["InOutBinding"],
+ "meta": {
+ "allowedIn": ["bpmn:CallActivity"]
+ }
+ },
+ {
+ "name": "Out",
+ "superClass": ["InOutBinding"],
+ "meta": {
+ "allowedIn": ["bpmn:CallActivity"]
+ }
+ },
+ {
+ "name": "AsyncCapable",
+ "isAbstract": true,
+ "extends": ["bpmn:Activity", "bpmn:Gateway", "bpmn:Event"],
+ "properties": [
+ {
+ "name": "async",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "asyncBefore",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "asyncAfter",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ },
+ {
+ "name": "exclusive",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": true
+ }
+ ]
+ },
+ {
+ "name": "JobPriorized",
+ "isAbstract": true,
+ "extends": ["bpmn:Process", "camunda:AsyncCapable"],
+ "properties": [
+ {
+ "name": "jobPriority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "SignalEventDefinition",
+ "isAbstract": true,
+ "extends": ["bpmn:SignalEventDefinition"],
+ "properties": [
+ {
+ "name": "async",
+ "isAttr": true,
+ "type": "Boolean",
+ "default": false
+ }
+ ]
+ },
+ {
+ "name": "ErrorEventDefinition",
+ "isAbstract": true,
+ "extends": ["bpmn:ErrorEventDefinition"],
+ "properties": [
+ {
+ "name": "errorCodeVariable",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "errorMessageVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "PotentialStarter",
+ "superClass": ["Element"],
+ "properties": [
+ {
+ "name": "resourceAssignmentExpression",
+ "type": "bpmn:ResourceAssignmentExpression"
+ }
+ ]
+ },
+ {
+ "name": "FormSupported",
+ "isAbstract": true,
+ "extends": ["bpmn:StartEvent", "bpmn:UserTask"],
+ "properties": [
+ {
+ "name": "formHandlerClass",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "formKey",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "TemplateSupported",
+ "isAbstract": true,
+ "extends": ["bpmn:Process", "bpmn:FlowElement"],
+ "properties": [
+ {
+ "name": "modelerTemplate",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Initiator",
+ "isAbstract": true,
+ "extends": ["bpmn:StartEvent"],
+ "properties": [
+ {
+ "name": "initiator",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ScriptTask",
+ "isAbstract": true,
+ "extends": ["bpmn:ScriptTask"],
+ "properties": [
+ {
+ "name": "resultVariable",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Process",
+ "isAbstract": true,
+ "extends": ["bpmn:Process"],
+ "properties": [
+ {
+ "name": "candidateStarterGroups",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateStarterUsers",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "versionTag",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "historyTimeToLive",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "EscalationEventDefinition",
+ "isAbstract": true,
+ "extends": ["bpmn:EscalationEventDefinition"],
+ "properties": [
+ {
+ "name": "escalationCodeVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "FormalExpression",
+ "isAbstract": true,
+ "extends": ["bpmn:FormalExpression"],
+ "properties": [
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Assignable",
+ "extends": ["bpmn:UserTask"],
+ "properties": [
+ {
+ "name": "assignee",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateUsers",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "candidateGroups",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "dueDate",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "followUpDate",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "priority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "CallActivity",
+ "extends": ["bpmn:CallActivity"],
+ "properties": [
+ {
+ "name": "calledElementBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "calledElementVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "calledElementTenantId",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseRef",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "caseVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "caseTenantId",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableMappingClass",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableMappingDelegateExpression",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ServiceTaskLike",
+ "extends": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask",
+ "bpmn:MessageEventDefinition"
+ ],
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "workflowActivity",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resultVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "DmnCapable",
+ "extends": ["bpmn:BusinessRuleTask"],
+ "properties": [
+ {
+ "name": "decisionRef",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "decisionRefBinding",
+ "isAttr": true,
+ "type": "String",
+ "default": "latest"
+ },
+ {
+ "name": "decisionRefVersion",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "mapDecisionResult",
+ "isAttr": true,
+ "type": "String",
+ "default": "resultList"
+ },
+ {
+ "name": "decisionRefTenantId",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ExternalCapable",
+ "extends": ["camunda:ServiceTaskLike"],
+ "properties": [
+ {
+ "name": "type",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "topic",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "TaskPriorized",
+ "extends": ["bpmn:Process", "camunda:ExternalCapable"],
+ "properties": [
+ {
+ "name": "taskPriority",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Properties",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": ["*"]
+ },
+ "properties": [
+ {
+ "name": "values",
+ "type": "Property",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Property",
+ "superClass": ["Element"],
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "value",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "Connector",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "inputOutput",
+ "type": "InputOutput"
+ },
+ {
+ "name": "connectorId",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "WorkflowActivity",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "activityId",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "InputOutput",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:UserTask",
+ "bpmn:ServiceTask",
+ "bpmn:SendTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ReceiveTask",
+ "bpmn:ScriptTask",
+ "bpmn:ManualTask",
+ "bpmn:GlobalUserTask",
+ "bpmn:GlobalScriptTask",
+ "bpmn:GlobalBusinessRuleTask",
+ "bpmn:GlobalTask",
+ "bpmn:GlobalManualTask",
+ "bpmn:SubProcess",
+ "bpmn:Transaction",
+ "bpmn:IntermediateCatchEvent",
+ "bpmn:IntermediateThrowEvent",
+ "bpmn:EndEvent",
+ "bpmn:ThrowEvent",
+ "bpmn:CatchEvent",
+ "bpmn:ImplicitThrowEvent",
+ "bpmn:CallActivity"
+ ]
+ },
+ "properties": [
+ {
+ "name": "inputOutput",
+ "type": "InputOutput"
+ },
+ {
+ "name": "connectorId",
+ "type": "String"
+ },
+ {
+ "name": "inputParameters",
+ "isMany": true,
+ "type": "InputParameter"
+ },
+ {
+ "name": "outputParameters",
+ "isMany": true,
+ "type": "OutputParameter"
+ }
+ ]
+ },
+ {
+ "name": "InputOutputParameter",
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ },
+ {
+ "name": "definition",
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "InputOutputParameterDefinition",
+ "isAbstract": true
+ },
+ {
+ "name": "List",
+ "superClass": ["InputOutputParameterDefinition"],
+ "properties": [
+ {
+ "name": "items",
+ "isMany": true,
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "Map",
+ "superClass": ["InputOutputParameterDefinition"],
+ "properties": [
+ {
+ "name": "entries",
+ "isMany": true,
+ "type": "Entry"
+ }
+ ]
+ },
+ {
+ "name": "Entry",
+ "properties": [
+ {
+ "name": "key",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ },
+ {
+ "name": "definition",
+ "type": "InputOutputParameterDefinition"
+ }
+ ]
+ },
+ {
+ "name": "Value",
+ "superClass": ["InputOutputParameterDefinition"],
+ "properties": [
+ {
+ "name": "id",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Script",
+ "superClass": ["InputOutputParameterDefinition"],
+ "properties": [
+ {
+ "name": "scriptFormat",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "resource",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "value",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "Field",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:ServiceTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:SendTask"
+ ]
+ },
+ "properties": [
+ {
+ "name": "name",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "expression",
+ "type": "String"
+ },
+ {
+ "name": "stringValue",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "string",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "InputParameter",
+ "superClass": ["InputOutputParameter"]
+ },
+ {
+ "name": "OutputParameter",
+ "superClass": ["InputOutputParameter"]
+ },
+ {
+ "name": "Collectable",
+ "isAbstract": true,
+ "extends": ["bpmn:MultiInstanceLoopCharacteristics"],
+ "superClass": ["camunda:AsyncCapable"],
+ "properties": [
+ {
+ "name": "collection",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "elementVariable",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "FailedJobRetryTimeCycle",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:ServiceTask",
+ "bpmn:SendTask",
+ "bpmn:UserTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ScriptTask",
+ "bpmn:ReceiveTask",
+ "bpmn:CallActivity",
+ "bpmn:TimerEventDefinition",
+ "bpmn:SignalEventDefinition",
+ "bpmn:MultiInstanceLoopCharacteristics"
+ ]
+ },
+ "properties": [
+ {
+ "name": "body",
+ "isBody": true,
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "ExecutionListener",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": [
+ "bpmn:Task",
+ "bpmn:ServiceTask",
+ "bpmn:UserTask",
+ "bpmn:BusinessRuleTask",
+ "bpmn:ScriptTask",
+ "bpmn:ReceiveTask",
+ "bpmn:ManualTask",
+ "bpmn:ExclusiveGateway",
+ "bpmn:SequenceFlow",
+ "bpmn:ParallelGateway",
+ "bpmn:InclusiveGateway",
+ "bpmn:EventBasedGateway",
+ "bpmn:StartEvent",
+ "bpmn:IntermediateCatchEvent",
+ "bpmn:IntermediateThrowEvent",
+ "bpmn:EndEvent",
+ "bpmn:BoundaryEvent",
+ "bpmn:CallActivity",
+ "bpmn:SubProcess"
+ ]
+ },
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "event",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "type": "Script"
+ },
+ {
+ "name": "fields",
+ "type": "Field",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "TaskListener",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": ["bpmn:UserTask"]
+ },
+ "properties": [
+ {
+ "name": "expression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "class",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "delegateExpression",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "event",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "script",
+ "type": "Script"
+ },
+ {
+ "name": "fields",
+ "type": "Field",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "FormProperty",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": ["bpmn:StartEvent", "bpmn:UserTask"]
+ },
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "type",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "required",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "readable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "writable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "variable",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "expression",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "datePattern",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "default",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "values",
+ "type": "Value",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "FormData",
+ "superClass": ["Element"],
+ "meta": {
+ "allowedIn": ["bpmn:StartEvent", "bpmn:UserTask"]
+ },
+ "properties": [
+ {
+ "name": "fields",
+ "type": "FormField",
+ "isMany": true
+ },
+ {
+ "name": "businessKey",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "FormField",
+ "superClass": ["Element"],
+ "properties": [
+ {
+ "name": "id",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "label",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "type",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "datePattern",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "defaultValue",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "properties",
+ "type": "Properties"
+ },
+ {
+ "name": "validation",
+ "type": "Validation"
+ },
+ {
+ "name": "values",
+ "type": "Value",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Validation",
+ "superClass": ["Element"],
+ "properties": [
+ {
+ "name": "constraints",
+ "type": "Constraint",
+ "isMany": true
+ }
+ ]
+ },
+ {
+ "name": "Constraint",
+ "superClass": ["Element"],
+ "properties": [
+ {
+ "name": "name",
+ "type": "String",
+ "isAttr": true
+ },
+ {
+ "name": "config",
+ "type": "String",
+ "isAttr": true
+ }
+ ]
+ },
+ {
+ "name": "ConditionalEventDefinition",
+ "isAbstract": true,
+ "extends": ["bpmn:ConditionalEventDefinition"],
+ "properties": [
+ {
+ "name": "variableName",
+ "isAttr": true,
+ "type": "String"
+ },
+ {
+ "name": "variableEvent",
+ "isAttr": true,
+ "type": "String"
+ }
+ ]
+ }
+ ],
+ "emumerations": []
+}
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/WorkflowPropertiesProvider.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/WorkflowPropertiesProvider.js
new file mode 100644
index 0000000..98a5797
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/WorkflowPropertiesProvider.js
@@ -0,0 +1,301 @@
+import inherits from 'inherits';
+import CamundaPropertiesProvider from 'bpmn-js-properties-panel/lib/provider/camunda/CamundaPropertiesProvider';
+
+import { is, getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
+
+import asyncCapableHelper from 'bpmn-js-properties-panel/lib/helper/AsyncCapableHelper';
+import eventDefinitionHelper from 'bpmn-js-properties-panel/lib/helper/EventDefinitionHelper';
+import implementationTypeHelper from 'bpmn-js-properties-panel/lib/helper/ImplementationTypeHelper';
+
+import idProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/IdProps';
+import nameProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/NameProps';
+import processProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/ProcessProps';
+import executableProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/ExecutableProps';
+import linkProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/LinkProps';
+import eventProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/EventProps';
+import documentationProps from 'bpmn-js-properties-panel/lib/provider/bpmn/parts/DocumentationProps';
+
+import elementTemplateChooserProps from 'bpmn-js-properties-panel/lib/provider/camunda/element-templates/parts/ChooserProps';
+import elementTemplateCustomProps from 'bpmn-js-properties-panel/lib/provider/camunda/element-templates/parts/CustomProps';
+
+import versionTag from 'bpmn-js-properties-panel/lib/provider/camunda/parts/VersionTagProps';
+import userTaskProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/UserTaskProps';
+import scriptProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/ScriptTaskProps';
+import callActivityProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/CallActivityProps';
+import conditionalProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/ConditionalProps';
+import startEventInitiator from 'bpmn-js-properties-panel/lib/provider/camunda/parts/StartEventInitiator';
+import multiInstanceProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/MultiInstanceLoopProps';
+import asynchronousContinuationProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/AsynchronousContinuationProps';
+import jobConfiguration from 'bpmn-js-properties-panel/lib/provider/camunda/parts/JobConfigurationProps';
+import externalTaskConfiguration from 'bpmn-js-properties-panel/lib/provider/camunda/parts/ExternalTaskConfigurationProps';
+import candidateStarter from 'bpmn-js-properties-panel/lib/provider/camunda/parts/CandidateStarterProps';
+import historyTimeToLive from 'bpmn-js-properties-panel/lib/provider/camunda/parts/HistoryTimeToLiveProps';
+
+import createInputOutputTabGroups from './parts/createInputOutputTabGroups';
+import workflowServiceTaskDelegateProps from './parts/WorkflowServiceTaskDelegateProps';
+
+const PROCESS_KEY_HINT = 'This maps to the process definition key.';
+
+const isExternalTaskPriorityEnabled = function(element) {
+ const businessObject = getBusinessObject(element);
+
+ // show only if element is a process, a participant ...
+ if (
+ is(element, 'bpmn:Process') ||
+ (is(element, 'bpmn:Participant') && businessObject.get('processRef'))
+ ) {
+ return true;
+ }
+
+ const externalBo = implementationTypeHelper.getServiceTaskLikeBusinessObject(
+ element
+ ),
+ isExternalTask =
+ implementationTypeHelper.getImplementationType(externalBo) ===
+ 'external';
+
+ // ... or an external task with selected external implementation type
+ return (
+ !!implementationTypeHelper.isExternalCapable(externalBo) &&
+ isExternalTask
+ );
+};
+
+const isJobConfigEnabled = element => {
+ const businessObject = getBusinessObject(element);
+
+ if (
+ is(element, 'bpmn:Process') ||
+ (is(element, 'bpmn:Participant') && businessObject.get('processRef'))
+ ) {
+ return true;
+ }
+
+ // async behavior
+ const bo = getBusinessObject(element);
+ if (
+ asyncCapableHelper.isAsyncBefore(bo) ||
+ asyncCapableHelper.isAsyncAfter(bo)
+ ) {
+ return true;
+ }
+
+ // timer definition
+ if (is(element, 'bpmn:Event')) {
+ return !!eventDefinitionHelper.getTimerEventDefinition(element);
+ }
+
+ return false;
+};
+
+function createGeneralTabGroups(
+ element,
+ config,
+ bpmnFactory,
+ elementRegistry,
+ elementTemplates,
+ translate
+) {
+ // refer to target element for external labels
+ element = element.labelTarget || element;
+
+ const generalGroup = {
+ id: 'general',
+ label: translate('General'),
+ entries: []
+ };
+
+ let idOptions;
+ let processOptions;
+
+ if (is(element, 'bpmn:Process')) {
+ idOptions = { description: PROCESS_KEY_HINT };
+ }
+
+ if (is(element, 'bpmn:Participant')) {
+ processOptions = { processIdDescription: PROCESS_KEY_HINT };
+ }
+
+ idProps(generalGroup, element, translate, idOptions);
+ nameProps(generalGroup, element, translate);
+ processProps(generalGroup, element, translate, processOptions);
+ versionTag(generalGroup, element, translate);
+ executableProps(generalGroup, element, translate);
+ elementTemplateChooserProps(
+ generalGroup,
+ element,
+ elementTemplates,
+ translate
+ );
+
+ const customFieldsGroups = elementTemplateCustomProps(
+ element,
+ elementTemplates,
+ bpmnFactory,
+ translate
+ );
+
+ const detailsGroup = {
+ id: 'details',
+ label: translate('Details'),
+ entries: []
+ };
+ workflowServiceTaskDelegateProps(
+ detailsGroup,
+ element,
+ config,
+ bpmnFactory,
+ translate
+ );
+ userTaskProps(detailsGroup, element, translate);
+ scriptProps(detailsGroup, element, bpmnFactory, translate);
+ linkProps(detailsGroup, element, translate);
+ callActivityProps(detailsGroup, element, bpmnFactory, translate);
+ eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);
+ conditionalProps(detailsGroup, element, bpmnFactory, translate);
+ startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group!
+
+ const multiInstanceGroup = {
+ id: 'multiInstance',
+ label: translate('Multi Instance'),
+ entries: []
+ };
+ multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate);
+
+ const asyncGroup = {
+ id: 'async',
+ label: translate('Asynchronous Continuations'),
+ entries: []
+ };
+ asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate);
+
+ const jobConfigurationGroup = {
+ id: 'jobConfiguration',
+ label: translate('Job Configuration'),
+ entries: [],
+ enabled: isJobConfigEnabled
+ };
+ jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate);
+
+ const externalTaskGroup = {
+ id: 'externalTaskConfiguration',
+ label: translate('External Task Configuration'),
+ entries: [],
+ enabled: isExternalTaskPriorityEnabled
+ };
+ externalTaskConfiguration(
+ externalTaskGroup,
+ element,
+ bpmnFactory,
+ translate
+ );
+
+ const candidateStarterGroup = {
+ id: 'candidateStarterConfiguration',
+ label: translate('Candidate Starter Configuration'),
+ entries: []
+ };
+ candidateStarter(candidateStarterGroup, element, bpmnFactory, translate);
+
+ const historyTimeToLiveGroup = {
+ id: 'historyConfiguration',
+ label: translate('History Configuration'),
+ entries: []
+ };
+ historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate);
+
+ const documentationGroup = {
+ id: 'documentation',
+ label: translate('Documentation'),
+ entries: []
+ };
+ documentationProps(documentationGroup, element, bpmnFactory, translate);
+
+ const groups = [];
+ groups.push(generalGroup);
+ customFieldsGroups.forEach(function(group) {
+ groups.push(group);
+ });
+ groups.push(detailsGroup);
+ groups.push(externalTaskGroup);
+ groups.push(multiInstanceGroup);
+ groups.push(asyncGroup);
+ groups.push(jobConfigurationGroup);
+ groups.push(candidateStarterGroup);
+ groups.push(historyTimeToLiveGroup);
+ groups.push(documentationGroup);
+
+ return groups;
+}
+
+function WorkflowPropertiesProvider(
+ config,
+ eventBus,
+ bpmnFactory,
+ elementRegistry,
+ elementTemplates,
+ translate
+) {
+ CamundaPropertiesProvider.call(
+ this,
+ eventBus,
+ bpmnFactory,
+ elementRegistry,
+ elementTemplates,
+ translate
+ );
+
+ this.getTabs = function(element) {
+ const camundaPropertiesProvider = new CamundaPropertiesProvider(
+ eventBus,
+ bpmnFactory,
+ elementRegistry,
+ elementTemplates,
+ translate
+ );
+
+ const tabs = camundaPropertiesProvider
+ .getTabs(element)
+ .filter(tab => tab.id !== 'general' && tab.id !== 'input-output');
+
+ const generalTab = {
+ id: 'general',
+ label: translate('General'),
+ groups: createGeneralTabGroups(
+ element,
+ config,
+ bpmnFactory,
+ elementRegistry,
+ elementTemplates,
+ translate
+ )
+ };
+
+ const inputOutputTab = {
+ id: 'input-output',
+ label: translate('Input/Output'),
+ groups: createInputOutputTabGroups(
+ element,
+ bpmnFactory,
+ elementRegistry,
+ translate
+ )
+ };
+ tabs.unshift(inputOutputTab);
+ tabs.unshift(generalTab);
+ return tabs;
+ };
+}
+
+WorkflowPropertiesProvider.$inject = [
+ 'config.workflow',
+ 'eventBus',
+ 'bpmnFactory',
+ 'elementRegistry',
+ 'elementTemplates',
+ 'translate'
+];
+
+inherits(WorkflowPropertiesProvider, CamundaPropertiesProvider);
+
+export default WorkflowPropertiesProvider;
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/index.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/index.js
new file mode 100644
index 0000000..bc60c58
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/index.js
@@ -0,0 +1,10 @@
+import ElementTemplates from 'bpmn-js-properties-panel/lib/provider/camunda/element-templates';
+import Translate from 'diagram-js/lib/i18n/translate';
+
+import WorkflowPropertiesProvider from './WorkflowPropertiesProvider';
+
+export default {
+ __depends__: [ElementTemplates, Translate],
+ __init__: ['propertiesProvider'],
+ propertiesProvider: ['type', WorkflowPropertiesProvider]
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputParameterProps.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputParameterProps.js
new file mode 100644
index 0000000..a1f1efb
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputParameterProps.js
@@ -0,0 +1,15 @@
+'use strict';
+
+import inputOutputParameter from './implementation/InputOutputParameter';
+import assign from 'lodash.assign';
+
+module.exports = function(group, element, bpmnFactory, options, translate) {
+ group.entries = group.entries.concat(
+ inputOutputParameter(
+ element,
+ bpmnFactory,
+ assign({}, options),
+ translate
+ )
+ );
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputProps.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputProps.js
new file mode 100644
index 0000000..df1e543
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/InputOutputProps.js
@@ -0,0 +1,13 @@
+'use strict';
+
+var inputOutput = require('./implementation/InputOutput');
+
+module.exports = function(group, element, bpmnFactory, translate) {
+ var inputOutputEntry = inputOutput(element, bpmnFactory, {}, translate);
+
+ group.entries = group.entries.concat(inputOutputEntry.entries);
+
+ return {
+ getSelectedParameter: inputOutputEntry.getSelectedParameter
+ };
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/WorkflowServiceTaskDelegateProps.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/WorkflowServiceTaskDelegateProps.js
new file mode 100644
index 0000000..dbd12cb
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/WorkflowServiceTaskDelegateProps.js
@@ -0,0 +1,85 @@
+import inherits from 'inherits';
+
+import ImplementationTypeHelper from 'bpmn-js-properties-panel/lib/helper/ImplementationTypeHelper';
+import ServiceTaskDelegateProps from 'bpmn-js-properties-panel/lib/provider/camunda/parts/ServiceTaskDelegateProps';
+import workflowImplementationType from './implementation/WorkflowImplementationType';
+import workflowActivity from './implementation/WorkflowActivity';
+import { implementationType as implementationTypeConst } from './implementation/implementationConstants';
+
+const getImplementationType = element => {
+ let implementationType = ImplementationTypeHelper.getImplementationType(
+ element
+ );
+
+ if (!implementationType) {
+ const bo = getBusinessObject(element);
+ if (bo) {
+ if (
+ typeof bo.get(implementationTypeConst.ACTIVITY) !== 'undefined'
+ ) {
+ return 'workflowActivity';
+ }
+ }
+ }
+
+ return implementationType;
+};
+
+const getBusinessObject = element =>
+ ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
+
+const isDmnCapable = element => ImplementationTypeHelper.isDmnCapable(element);
+
+const isExternalCapable = element =>
+ ImplementationTypeHelper.isExternalCapable(element);
+
+const isServiceTaskLike = element =>
+ ImplementationTypeHelper.isServiceTaskLike(element);
+
+function WorkflowServiceTaskDelegateProps(
+ group,
+ element,
+ config,
+ bpmnFactory,
+ translate
+) {
+ ServiceTaskDelegateProps.call(this, group, element, bpmnFactory, translate);
+
+ if (isServiceTaskLike(getBusinessObject(element))) {
+ group.entries = group.entries.filter(
+ entry => entry.id !== 'implementation'
+ );
+
+ group.entries = [
+ ...workflowImplementationType(
+ element,
+ bpmnFactory,
+ {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType,
+ hasDmnSupport: isDmnCapable(element),
+ hasExternalSupport: isExternalCapable(
+ getBusinessObject(element)
+ ),
+ hasServiceTaskLikeSupport: true
+ },
+ translate
+ ),
+ ...group.entries,
+ ...workflowActivity(
+ element,
+ config,
+ bpmnFactory,
+ {
+ getBusinessObject: getBusinessObject,
+ getImplementationType: getImplementationType
+ },
+ translate
+ )
+ ];
+ }
+}
+
+inherits(WorkflowServiceTaskDelegateProps, ServiceTaskDelegateProps);
+
+export default WorkflowServiceTaskDelegateProps;
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/createInputOutputTabGroups.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/createInputOutputTabGroups.js
new file mode 100644
index 0000000..f14e359
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/createInputOutputTabGroups.js
@@ -0,0 +1,57 @@
+let inputOutputParameter = require('./InputOutputParameterProps');
+let inputOutput = require('./InputOutputProps');
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var getInputOutputParameterLabel = function(param, translate) {
+ if (is(param, 'camunda:InputParameter')) {
+ return translate('Input Parameter');
+ }
+
+ if (is(param, 'camunda:OutputParameter')) {
+ return translate('Output Parameter');
+ }
+
+ return '';
+};
+
+export default function createInputOutputTabGroups(
+ element,
+ bpmnFactory,
+ elementRegistry,
+ translate
+) {
+ var inputOutputGroup = {
+ id: 'input-output',
+ label: translate('Parameters'),
+ entries: []
+ };
+
+ var options = inputOutput(
+ inputOutputGroup,
+ element,
+ bpmnFactory,
+ translate
+ );
+
+ var inputOutputParameterGroup = {
+ id: 'input-output-parameter',
+ entries: [],
+ enabled: function(element, node) {
+ return options.getSelectedParameter(element, node);
+ },
+ label: function(element, node) {
+ var param = options.getSelectedParameter(element, node);
+ return getInputOutputParameterLabel(param, translate);
+ }
+ };
+
+ inputOutputParameter(
+ inputOutputParameterGroup,
+ element,
+ bpmnFactory,
+ options,
+ translate
+ );
+
+ return [inputOutputGroup, inputOutputParameterGroup];
+}
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js
new file mode 100644
index 0000000..555b4af
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutput.js
@@ -0,0 +1,297 @@
+'use strict';
+import {
+ IMPLEMENTATION_TYPE_VALUE,
+ implementationType
+} from './implementationConstants';
+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'),
+ inputOutputHelper = require('./InputOutputHelper'),
+ cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper');
+
+var extensionElementsEntry = require('bpmn-js-properties-panel/lib/provider/camunda/parts/implementation//ExtensionElements');
+
+function isCreateDeleteSupported(element) {
+ const bo = getBusinessObject(element);
+ return (
+ (element.type !== 'bpmn:ServiceTask' ||
+ bo[implementationType.ACTIVITY] !== IMPLEMENTATION_TYPE_VALUE) &&
+ element.type !== 'bpmn:Process'
+ );
+}
+
+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);
+}
+
+function createElement(type, parent, factory, properties) {
+ const el = elementHelper.createElement(type, properties, parent, factory);
+ return el;
+}
+
+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
+ );
+}
+
+module.exports = 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
+ });
+
+ console.log(newElem);
+
+ 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: isCreateDeleteSupported(element)
+ ? newElement('camunda:InputParameter', 'inputParameters')
+ : undefined,
+ removeExtensionElement: 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: isCreateDeleteSupported(element)
+ ? newElement('camunda:OutputParameter', 'outputParameters')
+ : undefined,
+ removeExtensionElement: isCreateDeleteSupported(element)
+ ? removeElement(
+ getOutputParameter,
+ 'outputParameters',
+ 'inputParameters'
+ )
+ : 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/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js
new file mode 100644
index 0000000..e294351
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputHelper.js
@@ -0,0 +1,153 @@
+'use strict';
+
+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');
+
+var InputOutputHelper = {};
+
+module.exports = 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)
+ );
+};
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js
new file mode 100644
index 0000000..da949dd
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/InputOutputParameter.js
@@ -0,0 +1,433 @@
+'use strict';
+
+var is = require('bpmn-js/lib/util/ModelUtil').is;
+
+var elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
+ inputOutputHelper = require('./InputOutputHelper'),
+ 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 isElementDisabled(element) {
+ return (
+ (element.type === 'bpmn:ServiceTask' &&
+ element.businessObject.workflowActivity) ||
+ element.type === 'bpmn:Process'
+ );
+}
+
+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);
+}
+
+module.exports = 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 isElementDisabled(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 isElementDisabled(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/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js
new file mode 100644
index 0000000..90fe84f
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js
@@ -0,0 +1,58 @@
+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
+} from './implementationConstants';
+
+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);
+ return {
+ workflowActivity: bo.get(implementationType.ACTIVITY_RESOURCE)
+ };
+ },
+
+ set: function(element, values) {
+ var bo = getBusinessObject(element);
+ config.onChange(bo, values.workflowActivity);
+ const commands = [];
+ const dataForUpdate = {};
+ dataForUpdate[implementationType.ACTIVITY_RESOURCE] =
+ values.workflowActivity;
+ dataForUpdate[
+ implementationType.ACTIVITY
+ ] = IMPLEMENTATION_TYPE_VALUE;
+ commands.push(
+ cmdHelper.updateBusinessObject(element, bo, dataForUpdate)
+ );
+ return commands;
+ },
+
+ validate: function(element, values) {
+ return isWorkflowActivity(element) && !values.workflowActivity
+ ? { workflowActivity: 'Must provide a value' }
+ : {};
+ },
+
+ hidden: function(element) {
+ return !isWorkflowActivity(element);
+ }
+ });
+
+ return [workflowActivityEntry];
+};
+
+export default workflowActivity;
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js
new file mode 100644
index 0000000..11e8fcb
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowImplementationType.js
@@ -0,0 +1,227 @@
+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;
+
+module.exports = 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.ACTIVITY_RESOURCE] = '';
+ } 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/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js
new file mode 100644
index 0000000..054017f
--- /dev/null
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/implementationConstants.js
@@ -0,0 +1,6 @@
+export const implementationType = {
+ ACTIVITY: 'implementation',
+ ACTIVITY_RESOURCE: 'resourses'
+};
+
+export const IMPLEMENTATION_TYPE_VALUE = 'activity';
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputConstants.js b/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputConstants.js
index 6f29992..30f80a6 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputConstants.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputConstants.js
@@ -19,11 +19,11 @@
export const INPUTS = 'inputs';
export const OUTPUTS = 'outputs';
-export const STRING = 'String';
+export const STRING = 'string';
export const DEFAULT_STRING = 'STRING';
-export const BOOLEAN = 'Boolean';
-export const INTEGER = 'Integer';
-export const FLOAT = 'Float';
+export const BOOLEAN = 'boolean';
+export const INTEGER = 'integer';
+export const FLOAT = 'float';
export const NAMESPACE = 'inputOutput';
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputSelectors.js b/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputSelectors.js
index db07bce..3a6c9e8 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputSelectors.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/inputOutputSelectors.js
@@ -15,13 +15,23 @@
*/
import { createSelector } from 'reselect';
-import { isEmpty } from 'lodash';
+import isEmpty from 'lodash.isempty';
import { INPUTS } from 'features/version/inputOutput/inputOutputConstants';
export const getInputOutput = state => state.currentVersion.inputOutput;
export const getInputs = createSelector(getInputOutput, data => data.inputs);
export const getOutputs = createSelector(getInputOutput, data => data.outputs);
+export const getInputOutputForComposition = state => ({
+ inputs: getInputs(state).map(item => ({
+ ...item,
+ type: item.type.toLowerCase()
+ })),
+ outputs: getOutputs(state).map(item => ({
+ ...item,
+ type: item.type.toLowerCase()
+ }))
+});
export const getCurrent = createSelector(
getInputOutput,
inputOutput => inputOutput.current
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/versionController/views/VersionSelect.js b/workflow-designer-ui/src/main/frontend/src/features/version/versionController/views/VersionSelect.js
index 2c67946..d8a6d02 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/versionController/views/VersionSelect.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/versionController/views/VersionSelect.js
@@ -16,7 +16,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { isEmpty } from 'lodash';
+import isEmpty from 'lodash.isempty';
const VersionSelect = props => {
const {
diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js b/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js
index d8d7fd8..7ae5e1e 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js
+++ b/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js
@@ -33,11 +33,11 @@
import overviewApi from '../workflow/overview/overviewApi';
import { versionListFetchAction } from '../workflow/overview/overviewConstansts';
import { updateComposition } from 'features/version/composition/compositionActions';
-import activitiesApi from 'features/activities/activitiesApi';
-import { setActivitiesList } from 'features/activities/activitiesActions';
+import { getActivitiesList } from 'features/activities/activitiesActions';
function* fetchVersion(action) {
try {
+ yield put(getActivitiesList());
const data = yield call(versionApi.fetchVersion, action.payload);
const { inputs, outputs, ...rest } = data;
let composition = false;
@@ -48,12 +48,11 @@
action.payload
);
}
- const activitiesList = yield call(activitiesApi.fetchActivities);
+
yield all([
put(setWorkflowVersionAction(rest)),
put(setInputsOutputs({ inputs, outputs })),
- put(updateComposition(composition)),
- put(setActivitiesList(activitiesList.results))
+ put(updateComposition(composition))
]);
} catch (error) {
yield put(genericNetworkErrorAction(error));
diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/OverviewView.jsx b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/OverviewView.jsx
index d0bbdef..3166cad 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/OverviewView.jsx
+++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/OverviewView.jsx
@@ -78,16 +78,18 @@
versions,
selectedVersion,
workflow,
- isVersionsCertifies
+ isVersionsCertifies,
+ history
} = this.props;
const nodeVersions = versions.map(version => ({
id: version.id,
name: version.name,
parent: version.baseId || ''
}));
+
return (
<div className="overview-page">
- <WorkflowHeader name={workflow.name} />
+ <WorkflowHeader history={history} name={workflow.name} />
<div className="overview-content">
<WorkflowDetails
name={workflow.name}
diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/__tests__/__snapshots__/OverviewView_snapshot-test.js.snap b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/__tests__/__snapshots__/OverviewView_snapshot-test.js.snap
index dea9c1c..4f9df72 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/__tests__/__snapshots__/OverviewView_snapshot-test.js.snap
+++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/__tests__/__snapshots__/OverviewView_snapshot-test.js.snap
@@ -7,9 +7,27 @@
<div
className="overview-header"
>
- wf1
- -
- title
+ <div
+ className="title"
+ >
+ wf1
+ -
+ title
+ </div>
+ <div
+ className="svg-icon-wrapper go-catalog-btn clickable right"
+ disabled={undefined}
+ onClick={[Function]}
+ >
+ <test-file-stub
+ className="svg-icon __back"
+ />
+ <span
+ className="svg-icon-label "
+ >
+ backBtnLabel
+ </span>
+ </div>
</div>
<div
className="overview-content"
diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowHeader.jsx b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowHeader.jsx
index 06c67bc..f5bfc3d 100644
--- a/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowHeader.jsx
+++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowHeader.jsx
@@ -16,17 +16,43 @@
import React from 'react';
import PropTypes from 'prop-types';
import { I18n } from 'react-redux-i18n';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon';
-const WorkflowHeader = ({ name }) => {
+const BackBtn = ({ history }) => (
+ <SVGIcon
+ onClick={() => history.push('/')}
+ label={I18n.t('workflow.overview.backBtnLabel')}
+ className="go-catalog-btn"
+ labelPosition="right"
+ name="back"
+ />
+);
+
+BackBtn.propTypes = {
+ history: PropTypes.object
+};
+
+const Title = ({ name }) => (
+ <div className="title">
+ {name} - {I18n.t('workflow.overview.title')}
+ </div>
+);
+Title.propTypes = {
+ name: PropTypes.string
+};
+
+const WorkflowHeader = ({ name, history }) => {
return (
<div className="overview-header">
- {name} - {I18n.t('workflow.overview.title')}
+ <Title name={name} />
+ <BackBtn history={history} />
</div>
);
};
WorkflowHeader.propTypes = {
- name: PropTypes.string
+ name: PropTypes.string,
+ history: PropTypes.object
};
export default WorkflowHeader;
diff --git a/workflow-designer-ui/src/main/frontend/src/i18n/I18n.js b/workflow-designer-ui/src/main/frontend/src/i18n/I18n.js
index f07ae17..fdf28ff 100644
--- a/workflow-designer-ui/src/main/frontend/src/i18n/I18n.js
+++ b/workflow-designer-ui/src/main/frontend/src/i18n/I18n.js
@@ -15,8 +15,8 @@
*/
import languagesData from 'wfapp/i18n/languages.json';
-import merge from 'lodash/object/merge.js';
-import setPath from 'lodash/object/set.js';
+import merge from 'lodash.merge';
+import setPath from 'lodash.set';
let languagesObj = {};
let language = null;
diff --git a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json
index 96e64ae..ea99452 100644
--- a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json
+++ b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json
@@ -19,7 +19,8 @@
"cancelBtn": "Cancel",
"certifyBtn": "Certify",
"undoBtn": "Undo",
- "closeBtn": "Close"
+ "closeBtn": "Close",
+ "okBtn": "Ok"
},
"form": {
"name": "Name",
@@ -44,7 +45,8 @@
"versionList": "Versions",
"newVersion": "Create New Version",
"title": "Overview",
- "lastEdited": "Last Edited On"
+ "lastEdited": "Last Edited On",
+ "backBtnLabel": "WORKFLOW CATALOG"
},
"inputOutput": {
"name": "Name",
@@ -65,7 +67,10 @@
"emptyName": "Field is required"
},
"composition": {
- "bpmnError" : "BPMN.IO Error"
+ "bpmnError" : "BPMN.IO Error",
+ "exportErrorMsg": "Could not export diagram",
+ "saveErrorMsg": "Could not save diagram",
+ "importErrorMsg": "Could not import diagram"
}
},
"version": {
diff --git a/workflow-designer-ui/src/main/frontend/src/rootSaga.js b/workflow-designer-ui/src/main/frontend/src/rootSaga.js
index c280010..0ea0782 100644
--- a/workflow-designer-ui/src/main/frontend/src/rootSaga.js
+++ b/workflow-designer-ui/src/main/frontend/src/rootSaga.js
@@ -21,6 +21,8 @@
import { watchWorkflow } from 'features/workflow/create/createWorkflowSaga';
import { watchNotifications } from 'shared/notifications/notificationsSagas';
import versionSaga from 'features/version/versionSaga';
+import activitiesSaga from 'features/activities/activitiesSaga';
+
import { watchOverview } from 'features/workflow/overview/overviewSagas';
export default function* rootSaga() {
@@ -30,6 +32,7 @@
fork(watchWorkflow),
fork(watchNotifications),
fork(versionSaga),
- fork(watchOverview)
+ fork(watchOverview),
+ fork(activitiesSaga)
]);
}
diff --git a/workflow-designer-ui/src/main/frontend/src/shared/components/Select/index.js b/workflow-designer-ui/src/main/frontend/src/shared/components/Select/index.js
index dcf11f2..df30fad 100644
--- a/workflow-designer-ui/src/main/frontend/src/shared/components/Select/index.js
+++ b/workflow-designer-ui/src/main/frontend/src/shared/components/Select/index.js
@@ -15,7 +15,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { isEmpty } from 'lodash';
+import isEmpty from 'lodash.isempty';
const Select = props => {
const { dataObj, selectedItemValue, disabled, label } = props;
diff --git a/workflow-designer-ui/src/main/frontend/tools/proxy-server.js b/workflow-designer-ui/src/main/frontend/tools/proxy-server.js
index 397b0ba..bdec886 100644
--- a/workflow-designer-ui/src/main/frontend/tools/proxy-server.js
+++ b/workflow-designer-ui/src/main/frontend/tools/proxy-server.js
@@ -13,29 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-'use strict'
+'use strict';
-const proxy = require('http-proxy-middleware')
-const devConfig = require('./getDevConfig')
+const proxy = require('http-proxy-middleware');
+const devConfig = require('./getDevConfig');
module.exports = function(server) {
let proxyConfigDefaults = {
changeOrigin: true,
secure: false,
onProxyReq: (proxyReq, req, res) => {
- proxyReq.setHeader('USER_ID', devConfig.proxyConfig.cookies.USER_ID)
- },
- }
+ proxyReq.setHeader(
+ 'USER_ID',
+ devConfig.proxyConfig.cookies.USER_ID
+ );
+ }
+ };
- let middlewares = []
+ let middlewares = [];
middlewares.push(
proxy(
- ['/wf'],
+ ['/wf', '/v1.0/activity-spec'],
Object.assign({}, proxyConfigDefaults, {
- target: devConfig.proxyTarget,
- }),
- ),
- )
- server.use(middlewares)
-}
+ target: devConfig.proxyTarget
+ })
+ )
+ );
+ server.use(middlewares);
+};
diff --git a/workflow-designer-ui/src/main/frontend/yarn.lock b/workflow-designer-ui/src/main/frontend/yarn.lock
index 86a6301..f156658 100644
--- a/workflow-designer-ui/src/main/frontend/yarn.lock
+++ b/workflow-designer-ui/src/main/frontend/yarn.lock
@@ -2065,25 +2065,25 @@
version "0.8.0"
resolved "https://registry.yarnpkg.com/bpmn-font/-/bpmn-font-0.8.0.tgz#85b18715faede345cd33c8a48f50bbe557ff76c2"
-bpmn-js-properties-panel@^0.20.0:
- version "0.20.0"
- resolved "https://registry.yarnpkg.com/bpmn-js-properties-panel/-/bpmn-js-properties-panel-0.20.0.tgz#0d1c3d46bde968d97f02e662a73e781efbda1263"
+bpmn-js-properties-panel@^0.26.1:
+ version "0.26.1"
+ resolved "https://registry.yarnpkg.com/bpmn-js-properties-panel/-/bpmn-js-properties-panel-0.26.1.tgz#893d9fe7027958a719a5d3973ec2d2e2c68a65eb"
dependencies:
- ids "^0.2.0"
+ ids "^0.2.2"
inherits "^2.0.1"
- lodash "^3.0.1"
- min-dom "^0.2.0"
- scroll-tabs "^0.2.1"
+ lodash "^4.17.10"
+ min-dom "^3.1.0"
+ scroll-tabs "^1.0.0"
selection-update "^0.1.2"
-bpmn-js@^2.3.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/bpmn-js/-/bpmn-js-2.3.1.tgz#1374c466f7c19ae4652dca52979200c293241863"
+bpmn-js@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/bpmn-js/-/bpmn-js-2.4.1.tgz#7e1530f54e0848959ec84789ca11eaac672eab6f"
dependencies:
bpmn-font "^0.8.0"
bpmn-moddle "^5.1.5"
css.escape "^1.5.1"
- diagram-js "^2.4.0"
+ diagram-js "^2.5.1"
diagram-js-direct-editing "^1.3.0"
ids "^0.2.0"
inherits "^2.0.1"
@@ -2390,12 +2390,6 @@
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
-camunda-bpmn-moddle@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/camunda-bpmn-moddle/-/camunda-bpmn-moddle-3.0.0.tgz#8ffcc44856643a6a4f85bec9cc6653bd97f342dd"
- dependencies:
- min-dash "^3.0.0"
-
caniuse-api@^1.5.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"
@@ -2852,31 +2846,6 @@
version "3.2.0"
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.2.0.tgz#f36f23aacc539da0e3e0f71af46ce5b953a6ae76"
-component-classes@^1.2.3:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/component-classes/-/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691"
- dependencies:
- component-indexof "0.0.3"
-
-component-closest@*:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/component-closest/-/component-closest-1.0.1.tgz#1ed0464132fc88a3510a2dabec079695789fb1b5"
- dependencies:
- component-matches-selector "~0.1.6"
-
-component-closest@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/component-closest/-/component-closest-0.1.4.tgz#5b72fc52d90607e75115cafdc3b07e27348de71b"
- dependencies:
- component-matches-selector "~0.1.5"
-
-component-delegate@^0.2.3:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/component-delegate/-/component-delegate-0.2.4.tgz#dc5028759ea681bea84a3d6bbd650207c3beb138"
- dependencies:
- component-closest "*"
- component-event "*"
-
component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
@@ -2889,20 +2858,6 @@
version "0.1.4"
resolved "https://registry.yarnpkg.com/component-event/-/component-event-0.1.4.tgz#3de78fc28782381787e24bf2a7c536bf0142c9b4"
-component-indexof@0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24"
-
-component-matches-selector@^0.1.5, component-matches-selector@~0.1.5, component-matches-selector@~0.1.6:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/component-matches-selector/-/component-matches-selector-0.1.6.tgz#7b630e04e7e0c3b0019f31749fd70af5ed8b972e"
- dependencies:
- component-query "*"
-
-component-query@*, component-query@^0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/component-query/-/component-query-0.0.3.tgz#07f49dab7071fa9606725df53e607f468acdaacf"
-
compressible@~2.0.13:
version "2.0.13"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9"
@@ -3544,9 +3499,9 @@
min-dash "^3.0.0"
min-dom "^3.0.0"
-diagram-js@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/diagram-js/-/diagram-js-2.4.0.tgz#f067fd956641297e3d540885fc5065046b3064c9"
+diagram-js@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/diagram-js/-/diagram-js-2.5.1.tgz#51c828f132da18a04f233a686495244ce0c2f42b"
dependencies:
css.escape "^1.5.1"
didi "^4.0.0"
@@ -4187,7 +4142,7 @@
version "3.1.0"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
-events@^1.0.0, events@^1.1.0:
+events@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
@@ -5551,7 +5506,7 @@
dependencies:
harmony-reflect "^1.4.6"
-ids@^0.2.0:
+ids@^0.2.0, ids@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/ids/-/ids-0.2.2.tgz#c23140dd06f5e5e95b1a5e5e98877ea734965540"
dependencies:
@@ -7050,6 +7005,10 @@
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
+lodash.isempty@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
+
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
@@ -7062,10 +7021,18 @@
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
+lodash.map@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
+lodash.merge@^4.6.1:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
+
lodash.mergewith@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
@@ -7074,6 +7041,10 @@
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+lodash.set@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
+
lodash.some@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
@@ -7108,7 +7079,7 @@
dependencies:
lodash._root "^3.0.0"
-lodash@^3.0.1, lodash@^3.10.1:
+lodash@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
@@ -7465,7 +7436,7 @@
version "1.0.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
-min-dash@^3.0.0:
+min-dash@^3.0.0, min-dash@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/min-dash/-/min-dash-3.1.0.tgz#ba1d0f06dd233f163ac8041f115e3bb08ba7fda9"
@@ -7475,21 +7446,9 @@
dependencies:
dom-walk "^0.1.0"
-min-dom@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/min-dom/-/min-dom-0.2.0.tgz#7f1a3f8ac85c05adee7b3f40e00c52803075cd5d"
- dependencies:
- component-classes "^1.2.3"
- component-closest "^0.1.4"
- component-delegate "^0.2.3"
- component-event "^0.1.4"
- component-matches-selector "^0.1.5"
- component-query "^0.0.3"
- domify "^1.3.1"
-
-min-dom@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/min-dom/-/min-dom-3.1.0.tgz#9f8075423e6f8799d642d9bdd65622dd3589f6d5"
+min-dom@^3.0.0, min-dom@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/min-dom/-/min-dom-3.1.1.tgz#53440d23d32a0a8bb6b2e657ca4cfd39d998a29a"
dependencies:
closest "0.0.1"
component-event "^0.1.4"
@@ -7592,6 +7551,10 @@
stream-each "^1.1.0"
through2 "^2.0.0"
+mitt@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.3.tgz#528c506238a05dce11cd914a741ea2cc332da9b8"
+
mixin-deep@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
@@ -10371,14 +10334,13 @@
version "1.0.0"
resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
-scroll-tabs@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/scroll-tabs/-/scroll-tabs-0.2.1.tgz#770d462b40f633b9cae6eee3521f785c49da8f6f"
+scroll-tabs@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/scroll-tabs/-/scroll-tabs-1.0.1.tgz#bac04e4a1725e8a03344bae644dd6d7cdc192452"
dependencies:
- events "^1.1.0"
- inherits "^2.0.1"
- lodash "^3.10.1"
- min-dom "^0.2.0"
+ min-dash "^3.1.0"
+ min-dom "^3.1.0"
+ mitt "^1.1.3"
scss-tokenizer@^0.2.3:
version "0.2.3"
@@ -11304,12 +11266,12 @@
resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07"
tiny-stack@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/tiny-stack/-/tiny-stack-1.0.0.tgz#e058ed1daff2e733da2dcc8879d6b01d26e2c1f6"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/tiny-stack/-/tiny-stack-1.1.0.tgz#a5d65c5753709ea43b29e903e6f6323185b9ac21"
tiny-svg@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/tiny-svg/-/tiny-svg-2.1.0.tgz#2323a150874c6702c6927a62ab17198402aeb886"
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/tiny-svg/-/tiny-svg-2.1.2.tgz#607c73004d3c807ba7d69ba9616d433190d2baf7"
tmp@^0.0.33:
version "0.0.33"