8962a3096d9eea1b8de5933da860b8a1fd547c61
[sdc/sdc-workflow-designer.git] /
1 import inputOutputHelper from './InputOutputHelper';
2 var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
3
4 var elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
5     extensionElementsHelper = require('bpmn-js-properties-panel/lib/helper/ExtensionElementsHelper'),
6     cmdHelper = require('bpmn-js-properties-panel/lib/helper/CmdHelper');
7
8 var extensionElementsEntry = require('bpmn-js-properties-panel/lib/provider/camunda/parts/implementation//ExtensionElements');
9
10 function getInputOutput(element, insideConnector) {
11     return inputOutputHelper.getInputOutput(element, insideConnector);
12 }
13
14 function getConnector(element) {
15     return inputOutputHelper.getConnector(element);
16 }
17
18 function getInputParameters(element, insideConnector) {
19     return inputOutputHelper.getInputParameters(element, insideConnector);
20 }
21
22 function getOutputParameters(element, insideConnector) {
23     return inputOutputHelper.getOutputParameters(element, insideConnector);
24 }
25
26 function getInputParameter(element, insideConnector, idx) {
27     return inputOutputHelper.getInputParameter(element, insideConnector, idx);
28 }
29
30 function getOutputParameter(element, insideConnector, idx) {
31     return inputOutputHelper.getOutputParameter(element, insideConnector, idx);
32 }
33
34 function createElement(type, parent, factory, properties) {
35     const el = elementHelper.createElement(type, properties, parent, factory);
36     return el;
37 }
38
39 function createInputOutput(parent, bpmnFactory, properties) {
40     return createElement(
41         'camunda:InputOutput',
42         parent,
43         bpmnFactory,
44         properties
45     );
46 }
47
48 function createParameter(type, parent, bpmnFactory, properties) {
49     return createElement(type, parent, bpmnFactory, properties);
50 }
51
52 function ensureInputOutputSupported(element, insideConnector) {
53     return inputOutputHelper.isInputOutputSupported(element, insideConnector);
54 }
55
56 function ensureOutparameterSupported(element, insideConnector) {
57     return inputOutputHelper.areOutputParametersSupported(
58         element,
59         insideConnector
60     );
61 }
62
63 export default function(element, bpmnFactory, options, translate) {
64     var TYPE_LABEL = {
65         'camunda:Map': translate('Map'),
66         'camunda:List': translate('List'),
67         'camunda:Script': translate('Script')
68     };
69
70     options = options || {};
71
72     var insideConnector = !!options.insideConnector,
73         idPrefix = options.idPrefix || '';
74
75     var getSelected = function(element, node) {
76         var selection = (inputEntry &&
77             inputEntry.getSelected(element, node)) || { idx: -1 };
78
79         var parameter = getInputParameter(
80             element,
81             insideConnector,
82             selection.idx
83         );
84         if (!parameter && outputEntry) {
85             selection = outputEntry.getSelected(element, node);
86             parameter = getOutputParameter(
87                 element,
88                 insideConnector,
89                 selection.idx
90             );
91         }
92         return parameter;
93     };
94
95     var result = {
96         getSelectedParameter: getSelected
97     };
98
99     var entries = (result.entries = []);
100
101     if (!ensureInputOutputSupported(element)) {
102         return result;
103     }
104
105     var newElement = function(type, prop, elementData) {
106         return function(element, extensionElements, value) {
107             var commands = [];
108
109             var inputOutput = getInputOutput(element, insideConnector);
110             if (!inputOutput) {
111                 var parent = !insideConnector
112                     ? extensionElements
113                     : getConnector(element);
114
115                 inputOutput = createInputOutput(parent, bpmnFactory, {
116                     inputParameters: [],
117                     outputParameters: []
118                 });
119
120                 if (!insideConnector) {
121                     commands.push(
122                         cmdHelper.addAndRemoveElementsFromList(
123                             element,
124                             extensionElements,
125                             'values',
126                             'extensionElements',
127                             [inputOutput],
128                             []
129                         )
130                     );
131                 } else {
132                     commands.push(
133                         cmdHelper.updateBusinessObject(element, parent, {
134                             inputOutput: inputOutput
135                         })
136                     );
137                 }
138             }
139
140             var newElem = elementData
141                 ? createParameter(type, inputOutput, bpmnFactory, elementData)
142                 : createParameter(type, inputOutput, bpmnFactory, {
143                       name: value
144                   });
145
146             commands.push(
147                 cmdHelper.addElementsTolist(element, inputOutput, prop, [
148                     newElem
149                 ])
150             );
151
152             return commands;
153         };
154     };
155
156     var removeElement = function(getter, prop, otherProp) {
157         return function(element, extensionElements, value, idx) {
158             var inputOutput = getInputOutput(element, insideConnector);
159             var parameter = getter(element, insideConnector, idx);
160
161             var commands = [];
162             commands.push(
163                 cmdHelper.removeElementsFromList(
164                     element,
165                     inputOutput,
166                     prop,
167                     null,
168                     [parameter]
169                 )
170             );
171
172             var firstLength = inputOutput.get(prop).length - 1;
173             var secondLength = (inputOutput.get(otherProp) || []).length;
174
175             if (!firstLength && !secondLength) {
176                 if (!insideConnector) {
177                     commands.push(
178                         extensionElementsHelper.removeEntry(
179                             getBusinessObject(element),
180                             element,
181                             inputOutput
182                         )
183                     );
184                 } else {
185                     var connector = getConnector(element);
186                     commands.push(
187                         cmdHelper.updateBusinessObject(element, connector, {
188                             inputOutput: undefined
189                         })
190                     );
191                 }
192             }
193
194             return commands;
195         };
196     };
197
198     var setOptionLabelValue = function(getter) {
199         return function(element, node, option, property, value, idx) {
200             var parameter = getter(element, insideConnector, idx);
201
202             var suffix = 'Text';
203
204             var definition = parameter.get('definition');
205             if (typeof definition !== 'undefined') {
206                 var type = definition.$type;
207                 suffix = TYPE_LABEL[type];
208             }
209
210             option.text = (value || '') + ' : ' + suffix;
211         };
212     };
213
214     // input parameters ///////////////////////////////////////////////////////////////
215
216     var inputEntry = extensionElementsEntry(element, bpmnFactory, {
217         id: idPrefix + 'inputs',
218         label: translate('Input Parameters'),
219         modelProperty: 'name',
220         prefix: 'Input',
221         resizable: true,
222
223         createExtensionElement: inputOutputHelper.isCreateDeleteSupported(
224             element
225         )
226             ? newElement('camunda:InputParameter', 'inputParameters')
227             : undefined,
228         removeExtensionElement: inputOutputHelper.isCreateDeleteSupported(
229             element
230         )
231             ? removeElement(
232                   getInputParameter,
233                   'inputParameters',
234                   'outputParameters'
235               )
236             : undefined,
237
238         getExtensionElements: function(element) {
239             return getInputParameters(element, insideConnector);
240         },
241
242         onSelectionChange: function(element, node) {
243             outputEntry && outputEntry.deselect(element, node);
244         },
245
246         setOptionLabelValue: setOptionLabelValue(getInputParameter)
247     });
248     entries.push(inputEntry);
249
250     // output parameters ///////////////////////////////////////////////////////
251
252     if (ensureOutparameterSupported(element, insideConnector)) {
253         var outputEntry = extensionElementsEntry(element, bpmnFactory, {
254             id: idPrefix + 'outputs',
255             label: translate('Output Parameters'),
256             modelProperty: 'name',
257             prefix: 'Output',
258             resizable: true,
259
260             createExtensionElement: inputOutputHelper.isCreateDeleteSupported(
261                 element
262             )
263                 ? newElement('camunda:OutputParameter', 'outputParameters')
264                 : undefined,
265             removeExtensionElement: inputOutputHelper.isCreateDeleteSupported(
266                 element
267             )
268                 ? removeElement(
269                       getOutputParameter,
270                       'outputParameters',
271                       'inputParameters'
272                   )
273                 : inputOutputHelper.isCreateDeleteSupported(element),
274
275             getExtensionElements: function(element) {
276                 return getOutputParameters(element, insideConnector);
277             },
278
279             onSelectionChange: function(element, node) {
280                 inputEntry.deselect(element, node);
281             },
282
283             setOptionLabelValue: setOptionLabelValue(getOutputParameter)
284         });
285         entries.push(outputEntry);
286     }
287
288     return result;
289 }