foreman_acd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +87 -0
  4. data/Rakefile +49 -0
  5. data/app/assets/javascripts/foreman_acd/acd_dummy.js +3 -0
  6. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +55 -0
  7. data/app/controllers/foreman_acd/api/v2/base_controller.rb +16 -0
  8. data/app/controllers/foreman_acd/app_definitions_controller.rb +53 -0
  9. data/app/controllers/foreman_acd/app_instances_controller.rb +158 -0
  10. data/app/controllers/foreman_acd/application_controller.rb +10 -0
  11. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +23 -0
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +23 -0
  13. data/app/controllers/ui_acd_controller.rb +30 -0
  14. data/app/models/foreman_acd/app_definition.rb +23 -0
  15. data/app/models/foreman_acd/app_instance.rb +21 -0
  16. data/app/views/foreman_acd/app_definitions/_form.html.erb +40 -0
  17. data/app/views/foreman_acd/app_definitions/edit.html.erb +11 -0
  18. data/app/views/foreman_acd/app_definitions/index.html.erb +27 -0
  19. data/app/views/foreman_acd/app_definitions/new.html.erb +10 -0
  20. data/app/views/foreman_acd/app_instances/_form.html.erb +46 -0
  21. data/app/views/foreman_acd/app_instances/edit.html.erb +11 -0
  22. data/app/views/foreman_acd/app_instances/index.html.erb +30 -0
  23. data/app/views/foreman_acd/app_instances/new.html.erb +11 -0
  24. data/app/views/ui_acd/app.json.rabl +9 -0
  25. data/app/views/ui_acd/app_definition.json.rabl +5 -0
  26. data/app/views/ui_acd/computeprofile.json.rabl +4 -0
  27. data/app/views/ui_acd/domain.json.rabl +4 -0
  28. data/app/views/ui_acd/environment.json.rabl +4 -0
  29. data/app/views/ui_acd/fdata.json.rabl +24 -0
  30. data/app/views/ui_acd/lifecycle_environment.json.rabl +4 -0
  31. data/app/views/ui_acd/ptable.json.rabl +4 -0
  32. data/config/routes.rb +24 -0
  33. data/db/migrate/20190610202252_create_app_definitions.rb +19 -0
  34. data/db/migrate/20190625140305_create_app_instances.rb +19 -0
  35. data/lib/foreman_acd/engine.rb +43 -0
  36. data/lib/foreman_acd/plugin.rb +80 -0
  37. data/lib/foreman_acd/version.rb +5 -0
  38. data/lib/foreman_acd.rb +7 -0
  39. data/lib/tasks/foreman_acd_tasks.rake +47 -0
  40. data/locale/Makefile +60 -0
  41. data/locale/en/foreman_acd.po +19 -0
  42. data/locale/foreman_acd.pot +19 -0
  43. data/locale/gemspec.rb +2 -0
  44. data/package.json +121 -0
  45. data/test/controllers/app_definitions_controller_test.rb +24 -0
  46. data/test/controllers/app_instances_controller_test.rb +24 -0
  47. data/test/controllers/ui_acd_controller_test.rb +26 -0
  48. data/test/factories/foreman_acd_factories.rb +17 -0
  49. data/test/models/app_definition_test.rb +11 -0
  50. data/test/models/app_instance_test.rb +8 -0
  51. data/test/test_plugin_helper.rb +8 -0
  52. data/webpack/__mocks__/foremanReact/components/common/forms/Select.js +2 -0
  53. data/webpack/components/ParameterSelection/ParameterSelection.js +468 -0
  54. data/webpack/components/ParameterSelection/ParameterSelection.scss +3 -0
  55. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +294 -0
  56. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +31 -0
  57. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +52 -0
  58. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +175 -0
  59. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +15 -0
  60. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +162 -0
  61. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +194 -0
  62. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +127 -0
  63. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +48 -0
  64. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +150 -0
  65. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +47 -0
  66. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +454 -0
  67. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +2265 -0
  68. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +209 -0
  69. data/webpack/components/ParameterSelection/index.js +39 -0
  70. data/webpack/index.js +8 -0
  71. data/webpack/reducer.js +7 -0
  72. data/webpack/test_setup.js +11 -0
  73. metadata +206 -0
@@ -0,0 +1,294 @@
1
+ import React from 'react';
2
+ import * as sort from 'sortabular';
3
+
4
+ import {
5
+ actionHeaderCellFormatter,
6
+ sortableHeaderCellFormatter,
7
+ tableCellFormatter,
8
+ TABLE_SORT_DIRECTION
9
+ } from 'patternfly-react';
10
+
11
+ import api from 'foremanReact/API';
12
+
13
+ import {
14
+ propsToSnakeCase,
15
+ propsToCamelCase,
16
+ } from 'foremanReact/common/helpers';
17
+
18
+ import {
19
+ isNewDefinition,
20
+ isEditDefinition,
21
+ isDefinition,
22
+ isNewInstance,
23
+ isEditInstance,
24
+ isInstance,
25
+ filterUsedParameterTypes,
26
+ } from './ParameterSelectionHelper';
27
+
28
+ import {
29
+ INIT_PARAMETER_SELECTION,
30
+ PARAMETER_TYPES,
31
+ PARAMETER_DELETE,
32
+ PARAMETER_ADD,
33
+ PARAMETER_EDIT_ACTIVATE,
34
+ PARAMETER_EDIT_CONFIRM,
35
+ PARAMETER_EDIT_CHANGE,
36
+ PARAMETER_EDIT_CANCEL,
37
+ PARAMETER_SORT,
38
+ LOAD_PARAMETER_SELECTION_REQUEST,
39
+ LOAD_PARAMETER_SELECTION_SUCCESS,
40
+ LOAD_PARAMETER_SELECTION_FAILURE,
41
+ LOAD_FOREMAN_DATA_REQUEST,
42
+ LOAD_FOREMAN_DATA_SUCCESS,
43
+ LOAD_FOREMAN_DATA_FAILURE,
44
+ } from './ParameterSelectionConstants';
45
+
46
+ export const initParameterSelection = (
47
+ mode,
48
+ appDefinition,
49
+ parameters,
50
+ sortingFormatter,
51
+ sortableTransform,
52
+ inlineEditFormatter,
53
+ inlineEditButtonsFormatter,
54
+ ) => dispatch => {
55
+ const initialState = {};
56
+
57
+ initialState.sortingColumns = {
58
+ name: {
59
+ direction: TABLE_SORT_DIRECTION.ASC,
60
+ position: 0
61
+ }
62
+ };
63
+ initialState.appDefinition = appDefinition;
64
+
65
+ var valueLabel = 'Value';
66
+ if (isDefinition(mode)) {
67
+ valueLabel = 'Default value';
68
+ }
69
+
70
+ initialState.columns = [
71
+ {
72
+ property: 'name',
73
+ header: {
74
+ label: 'Name',
75
+ props: {
76
+ index: 0,
77
+ sort: true,
78
+ style: {
79
+ width: '20%'
80
+ }
81
+ },
82
+ transforms: [sortableTransform],
83
+ formatters: [sortingFormatter],
84
+ customFormatters: [sortableHeaderCellFormatter]
85
+ },
86
+ cell: {
87
+ formatters: [isDefinition(mode) ? inlineEditFormatter : tableCellFormatter]
88
+ }
89
+ },
90
+ {
91
+ property: 'description',
92
+ header: {
93
+ label: 'Description',
94
+ props: {
95
+ index: 1,
96
+ sort: true,
97
+ style: {
98
+ width: '25%'
99
+ }
100
+ },
101
+ transforms: [sortableTransform],
102
+ formatters: [sortingFormatter],
103
+ customFormatters: [sortableHeaderCellFormatter]
104
+ },
105
+ cell: {
106
+ props: {
107
+ index: 1
108
+ },
109
+ formatters: [isDefinition(mode) ? inlineEditFormatter : tableCellFormatter]
110
+ }
111
+ },
112
+ {
113
+ property: 'type',
114
+ header: {
115
+ label: 'Type',
116
+ props: {
117
+ index: 2,
118
+ sort: true,
119
+ style: {
120
+ width: '20%'
121
+ }
122
+ },
123
+ transforms: [sortableTransform],
124
+ formatters: [sortingFormatter],
125
+ customFormatters: [sortableHeaderCellFormatter]
126
+ },
127
+ cell: {
128
+ props: {
129
+ index: 2
130
+ },
131
+ // we are always using the inlineEditFormatter so that
132
+ // the well formatted type name is shown
133
+ formatters: [inlineEditFormatter]
134
+ }
135
+ },
136
+ {
137
+ property: 'value',
138
+ header: {
139
+ label: valueLabel,
140
+ props: {
141
+ index: 3,
142
+ sort: true,
143
+ style: {
144
+ width: '25%'
145
+ }
146
+ },
147
+ transforms: [sortableTransform],
148
+ formatters: [sortingFormatter],
149
+ customFormatters: [sortableHeaderCellFormatter]
150
+ },
151
+ cell: {
152
+ props: {
153
+ index: 3
154
+ },
155
+ formatters: [inlineEditFormatter]
156
+ }
157
+ },
158
+ {
159
+ property: 'actions',
160
+ header: {
161
+ label: 'Actions',
162
+ props: {
163
+ index: 4
164
+ },
165
+ formatters: [actionHeaderCellFormatter]
166
+ },
167
+ cell: {
168
+ props: {
169
+ index: 4
170
+ },
171
+ formatters: [inlineEditButtonsFormatter]
172
+ }
173
+ }
174
+ ];
175
+
176
+ if ((isNewDefinition(mode)) || (isNewInstance(mode))) {
177
+ initialState.rows = [];
178
+ } else if ((isEditDefinition(mode)) || (isEditInstance(mode))) {
179
+ initialState.rows = parameters;
180
+ initialState.hostgroupId = appDefinition.hostgroup_id;
181
+ } else {
182
+ // FIXME: should never ever happen
183
+ }
184
+
185
+ if (isNewDefinition(mode) || isNewInstance(mode)) {
186
+ initialState.parameterTypes = PARAMETER_TYPES;
187
+ } else {
188
+ initialState.parameterTypes = filterUsedParameterTypes(PARAMETER_TYPES, parameters);
189
+ }
190
+
191
+ dispatch({
192
+ type: INIT_PARAMETER_SELECTION,
193
+ payload: initialState,
194
+ });
195
+ }
196
+
197
+ const errorHandler = (msg, err) => {
198
+ const error = {
199
+ errorMsg: 'Failed to fetch data from server.',
200
+ statusText: err,
201
+ };
202
+ return { type: msg, payload: { error } };
203
+ };
204
+
205
+ export const addParameter = (additionalData) => ({
206
+ type: PARAMETER_ADD,
207
+ payload: {
208
+ ...additionalData,
209
+ },
210
+ });
211
+
212
+ export const deleteParameter = (additionalData) => ({
213
+ type: PARAMETER_DELETE,
214
+ payload: {
215
+ ...additionalData,
216
+ },
217
+ });
218
+
219
+ export const activateEditParameter = (additionalData) => ({
220
+ type: PARAMETER_EDIT_ACTIVATE,
221
+ payload: {
222
+ ...additionalData,
223
+ },
224
+ });
225
+
226
+ export const confirmEditParameter = (rowData) => ({
227
+ type: PARAMETER_EDIT_CONFIRM,
228
+ payload: {
229
+ ...rowData,
230
+ },
231
+ });
232
+
233
+ export const cancelEditParameter = (rowData) => ({
234
+ type: PARAMETER_EDIT_CANCEL,
235
+ payload: {
236
+ ...rowData,
237
+ },
238
+ });
239
+
240
+ export const changeEditParameter = (value, additionalData) => ({
241
+ type: PARAMETER_EDIT_CHANGE,
242
+ payload: {
243
+ value,
244
+ ...additionalData,
245
+ },
246
+ });
247
+
248
+ export const sortParameter = (selectedColumn, defaultSortingOrder) => ({
249
+ type: PARAMETER_SORT,
250
+ payload: {
251
+ selectedColumn,
252
+ defaultSortingOrder,
253
+ },
254
+ });
255
+
256
+ export const loadParameterSelection = (
257
+ url,
258
+ applicationDefinitionId
259
+ ) => dispatch => {
260
+ dispatch({ type: LOAD_PARAMETER_SELECTION_REQUEST });
261
+
262
+ var realUrl = url.replace("__id__", applicationDefinitionId);
263
+
264
+ return api
265
+ .get(realUrl, {}, {})
266
+ .then(({ data }) =>
267
+ dispatch({
268
+ type: LOAD_PARAMETER_SELECTION_SUCCESS,
269
+ payload: data,
270
+ })
271
+ )
272
+ .catch(error => dispatch(errorHandler(LOAD_PARAMETER_SELECTION_FAILURE, error)));
273
+ };
274
+
275
+ export const loadForemanData = (
276
+ url,
277
+ hostgroupId,
278
+ clearRows = false,
279
+ ) => dispatch => {
280
+ dispatch({ type: LOAD_FOREMAN_DATA_REQUEST, payload: { clearRows: clearRows } });
281
+
282
+ var realUrl = url.replace("__id__", hostgroupId);
283
+
284
+ return api
285
+ .get(realUrl, {}, {})
286
+ .then(({ data }) =>
287
+ dispatch({
288
+ type: LOAD_FOREMAN_DATA_SUCCESS,
289
+ payload: data,
290
+ })
291
+ )
292
+ .catch(error => dispatch(errorHandler(LOAD_FOREMAN_DATA_FAILURE, error)));
293
+ };
294
+
@@ -0,0 +1,31 @@
1
+ export const INIT_PARAMETER_SELECTION = 'INIT_PARAMETER_SELECTION';
2
+
3
+ export const PARAMETER_DELETE = 'PARAMETER_DELETE';
4
+ export const PARAMETER_ADD = 'PARAMETER_ADD';
5
+ export const PARAMETER_EDIT_ACTIVATE = 'PARAMETER_EDIT_ACTIVATE';
6
+ export const PARAMETER_EDIT_CONFIRM = 'PARAMETER_EDIT_CONFIRM';
7
+ export const PARAMETER_EDIT_CHANGE = 'PARAMETER_EDIT_CHANGE';
8
+ export const PARAMETER_EDIT_CANCEL = 'PARAMETER_EDIT_CANCEL';
9
+ export const PARAMETER_SORT = 'PARAMETER_SORT';
10
+
11
+ export const LOAD_PARAMETER_SELECTION_REQUEST = 'LOAD_PARAMETER_SELECTION_REQUEST';
12
+ export const LOAD_PARAMETER_SELECTION_SUCCESS = 'LOAD_PARAMETER_SELECTION_SUCCESS';
13
+ export const LOAD_PARAMETER_SELECTION_FAILURE = 'LOAD_PARAMETER_SELECTION_FAILURE';
14
+
15
+ export const LOAD_FOREMAN_DATA_REQUEST = 'LOAD_FOREMAN_DATA_REQUEST';
16
+ export const LOAD_FOREMAN_DATA_SUCCESS = 'LOAD_FOREMAN_DATA_SUCCESS';
17
+ export const LOAD_FOREMAN_DATA_FAILURE = 'LOAD_FOREMAN_DATA_FAILURE';
18
+
19
+ // Make sure the object is sorted by value
20
+ // (Compute Profile -> Partition table -> Root password)
21
+ export const PARAMETER_TYPES = {
22
+ computeprofile: 'Compute profile',
23
+ domain: 'Domain',
24
+ hostname: 'Hostname',
25
+ hostparam: 'Host parameter',
26
+ ip: 'IP',
27
+ lifecycleenv: 'Lifecycle environment',
28
+ ptable: 'Partition table',
29
+ puppetenv: 'Puppet environment',
30
+ password: 'Root password',
31
+ };
@@ -0,0 +1,52 @@
1
+ import {
2
+ cloneDeep,
3
+ } from 'lodash';
4
+
5
+ export const isNewDefinition = (mode) => {
6
+ if (mode == "newDefinition")
7
+ return true;
8
+ return false;
9
+ }
10
+
11
+ export const isEditDefinition = (mode) => {
12
+ if (mode == "editDefinition")
13
+ return true;
14
+ return false;
15
+ }
16
+
17
+ export const isDefinition = (mode) => {
18
+ return (isNewDefinition(mode) || isEditDefinition(mode))
19
+ }
20
+
21
+ export const isNewInstance = (mode) => {
22
+ if (mode == "newInstance")
23
+ return true;
24
+ return false;
25
+ }
26
+
27
+ export const isEditInstance = (mode) => {
28
+ if (mode == "editInstance")
29
+ return true;
30
+ return false;
31
+ }
32
+
33
+ export const isInstance = (mode) => {
34
+ return (isNewInstance(mode) || isEditInstance(mode))
35
+ }
36
+
37
+ export const transformForemanData = (fdata) => {
38
+ if (fdata === undefined) {
39
+ return "";
40
+ }
41
+ var result = {};
42
+ fdata.map(item => result[item.id] = item.name)
43
+ return (result);
44
+ }
45
+
46
+ export const filterUsedParameterTypes = (options, parameters) => {
47
+ var newOptions = cloneDeep(options);
48
+ // hostparam can be used multiple times
49
+ var alreadyUsed = parameters.map(item => item["type"]).filter(item => item != 'hostparam');
50
+ alreadyUsed.forEach(item => delete newOptions[item])
51
+ return newOptions;
52
+ }
@@ -0,0 +1,175 @@
1
+ import Immutable from 'seamless-immutable';
2
+
3
+ import {
4
+ cloneDeep,
5
+ findIndex,
6
+ findLastIndex,
7
+ } from 'lodash';
8
+
9
+ import {
10
+ filterUsedParameterTypes,
11
+ } from './ParameterSelectionHelper';
12
+
13
+ import * as sort from 'sortabular';
14
+
15
+ import {
16
+ INIT_PARAMETER_SELECTION,
17
+ PARAMETER_TYPES,
18
+ PARAMETER_DELETE,
19
+ PARAMETER_ADD,
20
+ PARAMETER_EDIT_ACTIVATE,
21
+ PARAMETER_EDIT_CONFIRM,
22
+ PARAMETER_EDIT_CHANGE,
23
+ PARAMETER_EDIT_CANCEL,
24
+ PARAMETER_SORT,
25
+ LOAD_PARAMETER_SELECTION_REQUEST,
26
+ LOAD_PARAMETER_SELECTION_SUCCESS,
27
+ LOAD_PARAMETER_SELECTION_FAILURE,
28
+ LOAD_FOREMAN_DATA_REQUEST,
29
+ LOAD_FOREMAN_DATA_SUCCESS,
30
+ LOAD_FOREMAN_DATA_FAILURE,
31
+ } from './ParameterSelectionConstants';
32
+
33
+ export const initialState = Immutable({
34
+ editMode: false,
35
+ error: { errorMsg: '', status: '', statusText: '' },
36
+ });
37
+
38
+ const parameterSelectionParameters = (state = initialState, action) => {
39
+ const { payload } = action;
40
+
41
+ switch (action.type) {
42
+ case INIT_PARAMETER_SELECTION: {
43
+ return state.merge(payload);
44
+ }
45
+ case PARAMETER_ADD: {
46
+ var rows = [];
47
+ var index = 0;
48
+
49
+ if ('rows' in state && state.rows !== undefined && state.rows.length > 0) {
50
+ rows = cloneDeep(state.rows);
51
+ index = Math.max(...rows.map(e => e.id)) + 1;
52
+ }
53
+
54
+ const newRow = {id: index, name: "", description: '', type: '', value: '', newEntry: true };
55
+ newRow.backup = cloneDeep(newRow)
56
+ rows.push(newRow);
57
+
58
+ return state.merge({
59
+ editMode: true,
60
+ rows: rows
61
+ });
62
+ }
63
+ case PARAMETER_DELETE: {
64
+ var rows = state.rows.filter(v => v.id !== payload.rowData.id);
65
+ return state.merge({
66
+ rows: rows,
67
+ parameterTypes: filterUsedParameterTypes(PARAMETER_TYPES, rows),
68
+ })
69
+ }
70
+ case PARAMETER_EDIT_ACTIVATE: {
71
+ const rows = cloneDeep(state.rows);
72
+ const index = findIndex(rows, { id: payload.rowData.id });
73
+
74
+ rows[index].backup = cloneDeep(rows[index]);
75
+
76
+ return state.merge({
77
+ editMode: true,
78
+ rows: rows
79
+ });
80
+ }
81
+ case PARAMETER_EDIT_CONFIRM: {
82
+ const rows = cloneDeep(state.rows);
83
+ const index = findIndex(rows, { id: payload.rowData.id });
84
+
85
+ delete rows[index].backup;
86
+ delete rows[index].newEntry;
87
+
88
+ return state.merge({
89
+ editMode: false,
90
+ parameterTypes: filterUsedParameterTypes(PARAMETER_TYPES, rows),
91
+ rows: rows
92
+ });
93
+ }
94
+ case PARAMETER_EDIT_CHANGE: {
95
+ const rows = cloneDeep(state.rows);
96
+ const index = findIndex(rows, { id: payload.rowData.id });
97
+
98
+ rows[index][payload.property] = payload.value;
99
+
100
+ return state.set('rows', rows);
101
+ }
102
+ case PARAMETER_EDIT_CANCEL: {
103
+ const rows = cloneDeep(state.rows);
104
+ const index = findIndex(rows, { id: payload.rowData.id });
105
+
106
+ rows[index] = cloneDeep(rows[index].backup);
107
+ delete rows[index].backup;
108
+
109
+ if (rows[index].newEntry === true) {
110
+ rows.splice(index, 1);
111
+ }
112
+
113
+ return state.merge({
114
+ editMode: false,
115
+ rows: rows
116
+ });
117
+ }
118
+ case PARAMETER_SORT: {
119
+ const selectedColumn = payload.selectedColumn;
120
+ return state.set(
121
+ 'sortingColumns',
122
+ sort.byColumn({
123
+ sortingColumns: state.sortingColumns,
124
+ sortingOrder: payload.defaultSortingOrder,
125
+ selectedColumn
126
+ })
127
+ );
128
+ }
129
+ case LOAD_PARAMETER_SELECTION_FAILURE: {
130
+ return state.merge({ error: payload.error, loading: false });
131
+ }
132
+ case LOAD_PARAMETER_SELECTION_REQUEST: {
133
+ return state.set('loading', true);
134
+ }
135
+ case LOAD_PARAMETER_SELECTION_SUCCESS: {
136
+ return state.merge({
137
+ appDefinition: payload.app_definition,
138
+ loading: false,
139
+ rows: JSON.parse(payload.app_definition.parameters),
140
+ hostgroupId: payload.app_definition.hostgroup_id,
141
+ foremanData: payload.fdata,
142
+ });
143
+ }
144
+ case LOAD_FOREMAN_DATA_FAILURE: {
145
+ return state.merge({
146
+ error: payload.error,
147
+ loading: false
148
+ });
149
+ }
150
+ case LOAD_FOREMAN_DATA_REQUEST: {
151
+ var newState = {
152
+ foremanData: {},
153
+ hostgroupId: -1,
154
+ loading: true
155
+ };
156
+
157
+ if (payload.clearRows === true) {
158
+ Object.assign(newState, { rows: [] });
159
+ }
160
+
161
+ return state.merge(newState);
162
+ }
163
+ case LOAD_FOREMAN_DATA_SUCCESS: {
164
+ return state.merge({
165
+ loading: false,
166
+ foremanData: payload,
167
+ hostgroupId: payload.hostgroup_id,
168
+ });
169
+ }
170
+ default:
171
+ return state;
172
+ }
173
+ };
174
+
175
+ export default parameterSelectionParameters;
@@ -0,0 +1,15 @@
1
+ import { differenceBy, slice, includes, uniq } from 'lodash';
2
+ import Immutable from 'seamless-immutable';
3
+ import { createSelector } from 'reselect';
4
+
5
+ const parameterState = state => state.foremanAcd.parameterSelectionParameters;
6
+
7
+ export const selectLoading = state => parameterState(state).loading;
8
+ export const selectEditMode = state => parameterState(state).editMode;
9
+ export const selectForemanData = state => parameterState(state).foremanData;
10
+ export const selectParameterTypes = state => parameterState(state).parameterTypes;
11
+ export const selectRows = state => parameterState(state).rows;
12
+ export const selectSortingColumns = state => parameterState(state).sortingColumns;
13
+ export const selectColumns = state => parameterState(state).columns;
14
+ export const selectAppDefinition = state => parameterState(state).appDefinition;
15
+ export const selectHostgroupId = state => parameterState(state).hostgroupId;