Skip to content

Commit 438f2e4

Browse files
GilbertCherriejeffibm
authored andcommitted
Convert order service form
1 parent 6bb35eb commit 438f2e4

File tree

17 files changed

+1254
-4
lines changed

17 files changed

+1254
-4
lines changed

app/controllers/catalog_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ def svc_catalog_provision
734734
ra, st, svc_catalog_provision_finish_submit_endpoint
735735
)
736736
@in_a_form = true
737+
@dialog_locals = options[:dialog_locals]
738+
# require 'byebug'
739+
# byebug
737740
replace_right_cell(:action => "dialog_provision", :dialog_locals => options[:dialog_locals])
738741
else
739742
# if catalog item has no dialog and provision button was pressed from list view

app/helpers/application_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module ApplicationHelper
1414
include Title
1515
include ReactjsHelper
1616
include Webpack
17+
include OrderServiceHelper
1718

1819
VALID_PERF_PARENTS = {
1920
"EmsCluster" => :ems_cluster,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module OrderServiceHelper
2+
def order_service_data(dialog)
3+
{
4+
5+
:apiSubmitEndpoint => dialog[:api_submit_endpoint],
6+
:apiAction => dialog[:api_action],
7+
:cancelEndPoint => dialog[:cancel_endpoint],
8+
:dialogId => dialog[:dialog_id],
9+
:finishSubmitEndpoint => dialog[:finish_submit_endpoint],
10+
:openUrl => dialog[:open_url],
11+
:resourceActionId => dialog[:resource_action_id],
12+
:realTargetType => dialog[:real_target_type],
13+
:targetId => dialog[:target_id],
14+
:targetType => dialog[:target_type],
15+
}
16+
end
17+
end
Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
import { componentTypes } from '@@ddf';
2+
// eslint-disable-next-line import/no-cycle
3+
import { buildFields } from './helper';
4+
5+
let dynamicFields = {};
6+
7+
const generateDynamicFields = (field) => {
8+
dynamicFields = { ...dynamicFields, [field.name]: null };
9+
};
10+
11+
/** Function to build a text box. */
12+
export const buildTextBox = (field, validate, setData) => {
13+
let component = {};
14+
generateDynamicFields(field);
15+
16+
if (field.options.protected) {
17+
component = {
18+
component: 'password-field',
19+
id: field.id,
20+
name: field.name,
21+
label: field.label,
22+
hideField: !field.visible,
23+
isRequired: field.required,
24+
isDisabled: field.read_only,
25+
initialValue: field.default_value,
26+
description: field.description,
27+
validate,
28+
};
29+
} else {
30+
component = {
31+
component: componentTypes.TEXT_FIELD,
32+
id: field.id,
33+
name: field.name,
34+
label: field.label,
35+
hideField: !field.visible,
36+
isRequired: field.required,
37+
isDisabled: field.read_only,
38+
initialValue: field.default_value,
39+
description: field.description,
40+
validate,
41+
resolveProps: (props, { meta, input }, formOptions) => {
42+
dynamicFields[input.name] = input.value;
43+
},
44+
// resolveProps: (props, { meta, input }, formOptions) => {
45+
// console.log(props);
46+
// console.log(meta);
47+
// console.log(input);
48+
// console.log(formOptions);
49+
// if (!formOptions.pristine) {
50+
// if (field.dialog_field_responders.length > 0) {
51+
// field.dialog_field_responders.forEach((tempField) => {
52+
// console.log(tempField);
53+
// dynamicFields.forEach((fieldToRefresh) => {
54+
// if (fieldToRefresh.field === tempField) {
55+
// const refreshData = {
56+
// action: 'refresh_dialog_fields',
57+
// resource: {
58+
// dialog_fields: {
59+
// // credential: null,
60+
// hosts: 'localhost0',
61+
// // param_provider_id: '38',
62+
// // param_miq_username: 'admin',
63+
// // param_miq_password: 'smartvm',
64+
// // check_box_1: 't',
65+
// // dropdown_list_1_1: null,
66+
// // textarea_box_1: '',
67+
// // date_time_control_1: '2022-10-12T20:50:45.180Z',
68+
// // date_time_control_2: '2022-10-12T20:50:45.180Z',
69+
// // date_control_1: '2022-10-12',
70+
// // date_control_2_1: '2022-09-27',
71+
// },
72+
// fields: ['credential'],
73+
// resource_action_id: '2018',
74+
// target_id: '14',
75+
// target_type: 'service_template',
76+
// real_target_type: 'ServiceTemplate',
77+
// },
78+
// };
79+
// fieldToRefresh.values = API.post(`/api/service_dialogs/10`, refreshData).then((data) => {
80+
// console.log(data);
81+
// });
82+
// console.log(fieldToRefresh);
83+
// }
84+
// });
85+
// });
86+
// }
87+
// }
88+
// },
89+
};
90+
}
91+
return component;
92+
};
93+
94+
/** Function to build a text area */
95+
export const buildTextAreaBox = (field, validate) => ({
96+
component: componentTypes.TEXTAREA,
97+
id: field.id,
98+
name: field.name,
99+
label: field.label,
100+
hideField: !field.visible,
101+
isRequired: field.required,
102+
isDisabled: field.read_only,
103+
initialValue: field.default_value,
104+
description: field.description,
105+
validate,
106+
});
107+
108+
/** Function to build a check box. */
109+
export const buildCheckBox = (field, validate) => ({
110+
component: componentTypes.CHECKBOX,
111+
id: field.id,
112+
name: field.name,
113+
label: field.label,
114+
hideField: !field.visible,
115+
isRequired: field.required,
116+
isDisabled: field.read_only,
117+
initialValue: field.default_value,
118+
description: field.description,
119+
validate,
120+
});
121+
122+
/** Function to build a drop down select box. */
123+
export const buildDropDownList = (field, validate) => {
124+
let options = [];
125+
let placeholder = __('<Choose>');
126+
let start;
127+
128+
field.values.forEach((value) => {
129+
if (value[0] === null) {
130+
value[0] = null;
131+
// eslint-disable-next-line prefer-destructuring
132+
placeholder = value[1];
133+
}
134+
options.push({ value: value[0] !== null ? String(value[0]) : null, label: value[1] });
135+
});
136+
137+
if (options[0].value === null) {
138+
start = options.shift();
139+
}
140+
options = options.sort((option1, option2) => {
141+
if (field.options.sort_by === 'description') {
142+
if (field.options.sort_order === 'ascending') {
143+
return option1.label.localeCompare(option2.label);
144+
}
145+
return option2.label.localeCompare(option1.label);
146+
}
147+
if (field.options.sort_order === 'ascending') {
148+
return option1.value.localeCompare(option2.value);
149+
}
150+
return option2.value.localeCompare(option1.value);
151+
});
152+
if (start) {
153+
options.unshift(start);
154+
}
155+
156+
let isMulti = false;
157+
if (field.options && field.options.force_multi_value) {
158+
isMulti = true;
159+
}
160+
generateDynamicFields(field);
161+
return {
162+
component: componentTypes.SELECT,
163+
id: field.id,
164+
name: field.name,
165+
labelText: field.label,
166+
hideField: !field.visible,
167+
isRequired: field.required,
168+
isDisabled: field.read_only,
169+
initialValue: field.default_value,
170+
description: field.description,
171+
validate,
172+
resolveProps: (props, { meta, input }, formOptions) => {
173+
dynamicFields[input.name] = input.value;
174+
},
175+
options,
176+
placeholder,
177+
isSearchable: true,
178+
simpleValue: true,
179+
isMulti,
180+
};
181+
};
182+
183+
/** Function to build a tag control field. */
184+
export const buildTagControl = (field, validate) => {
185+
const options = [];
186+
field.values.forEach((value) => {
187+
if (!value.id) {
188+
value.id = '-1';
189+
}
190+
options.push({ value: value.id, label: value.description });
191+
});
192+
return {
193+
component: componentTypes.SELECT,
194+
id: field.id,
195+
name: field.name,
196+
label: field.label,
197+
hideField: !field.visible,
198+
isRequired: field.required,
199+
isDisabled: field.read_only,
200+
initialValue: field.default_value,
201+
description: field.description,
202+
validate,
203+
options,
204+
};
205+
};
206+
207+
/** Function to build a date control field */
208+
export const buildDateControl = (field, validate) => ({
209+
component: componentTypes.DATE_PICKER,
210+
id: field.id,
211+
name: field.name,
212+
label: field.label,
213+
isRequired: field.required,
214+
isDisabled: field.read_only,
215+
initialValue: field.default_value,
216+
description: field.description,
217+
validate,
218+
variant: 'date-time',
219+
});
220+
221+
/** Function to build a time control field */
222+
export const buildTimeControl = (field, validate, dateTime) => ([{
223+
component: componentTypes.DATE_PICKER,
224+
id: field.id,
225+
name: field.name,
226+
label: field.label,
227+
isRequired: field.required,
228+
isDisabled: field.read_only,
229+
initialValue: dateTime.toISOString(),
230+
description: field.description,
231+
validate,
232+
variant: 'date-time',
233+
},
234+
{
235+
component: componentTypes.TIME_PICKER,
236+
id: `${field.id}-time`,
237+
name: `${field.name}-time`,
238+
isRequired: field.required,
239+
isDisabled: field.read_only,
240+
initialValue: dateTime,
241+
validate,
242+
twelveHoursFormat: true,
243+
pattern: '(0?[1-9]|1[0-2]):[0-5][0-9]',
244+
}]);
245+
246+
/** Function to build radio buttons fields */
247+
export const buildRadioButtons = (field, validate) => {
248+
const options = [];
249+
field.values.forEach((value) => {
250+
options.push({ value: value[0], label: value[1] });
251+
});
252+
return {
253+
component: componentTypes.RADIO,
254+
id: field.id,
255+
name: field.name,
256+
label: field.label,
257+
isRequired: field.required,
258+
isDisabled: field.read_only,
259+
initialValue: field.default_value,
260+
description: field.description,
261+
validate,
262+
options,
263+
};
264+
};
265+
266+
/** Function to show/hide loaders near to the fields. */
267+
const fieldSpinner = (fieldName, show) => {
268+
const activeSpinner = document.getElementById(`refreshSpinner_${fieldName}`);
269+
activeSpinner.style.display = show ? 'block' : 'none';
270+
};
271+
272+
/** Function to update the response and build the fileds again after field refresh. */
273+
const updateResponseFields = (response, fieldPosition, fieldName, result) => {
274+
response.content[0].dialog_tabs.map((tab, tabIndex) => {
275+
if (tabIndex === fieldPosition.tabIndex) {
276+
tab.dialog_groups.map((group, groupIndex) => {
277+
if (groupIndex === fieldPosition.groupIndex) {
278+
const field = group.dialog_fields.find((item) => item.name === fieldName);
279+
const data = result[fieldName];
280+
field.data_type = data.data_type;
281+
field.options = data.options;
282+
field.read_only = data.read_only;
283+
field.required = data.required;
284+
field.visible = data.visible;
285+
field.values = [['001', 'one'], ['002', 'two']]; // data.values;
286+
field.default_value = data.default_value;
287+
field.validator_rule = data.validator_rule;
288+
field.validator_type = data.validator_type;
289+
}
290+
return group;
291+
});
292+
}
293+
return tab;
294+
});
295+
return response;
296+
};
297+
298+
/** Function to fetch the field information and update the field value.
299+
* If another field is linked, the same function is called again to update the linked field.
300+
*/
301+
const refreshFields = (response, params, fieldName, initialData, resource, data, setData, fieldPosition) => {
302+
fieldSpinner(fieldName, true);
303+
API.post(`/api/service_dialogs/${response.id}`, params).then(({ result }) => {
304+
const responders = result[fieldName].dialog_field_responders;
305+
const newResponse = updateResponseFields(response, fieldPosition, fieldName, result);
306+
buildFields(newResponse, data, setData, initialData);
307+
responders.forEach((responderName) => {
308+
const newParams = {
309+
...params,
310+
resource: { ...resource, fields: [responderName] },
311+
};
312+
fieldSpinner(fieldName, false);
313+
refreshFields(response, newParams, responderName, initialData, resource, data, setData, fieldPosition);
314+
});
315+
});
316+
};
317+
318+
/** Function to handle the the refresh button click event. */
319+
const onRefreshField = (response, field, initialData, data, setData, fieldPosition) => {
320+
const resource = {
321+
dialog_fields: dynamicFields,
322+
fields: [field.name],
323+
resource_action_id: initialData.resourceActionId,
324+
target_id: initialData.targetId,
325+
target_type: initialData.targetType,
326+
real_target_type: initialData.realTargetType,
327+
};
328+
const params = {
329+
action: 'refresh_dialog_fields',
330+
resource,
331+
};
332+
333+
refreshFields(response, params, field.name, initialData, resource, data, setData, fieldPosition);
334+
};
335+
336+
/** Function to build a refresh button near to drop down. */
337+
export const buildRefreshButton = (response, field, initialData, data, setData, fieldPosition) => ({
338+
component: 'refresh-button',
339+
id: `refresh_${field.id}`,
340+
name: `refresh_${field.name}`,
341+
label: 'Refresh',
342+
hideField: !field.visible,
343+
className: 'refresh-button',
344+
showRefreshButton: field.show_refresh_button,
345+
fieldName: field.name,
346+
onRefresh: () => onRefreshField(response, field, initialData, data, setData, fieldPosition),
347+
});

0 commit comments

Comments
 (0)