foreman_remote_execution 8.2.1 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_ci.yml +3 -1
  3. data/app/controllers/api/v2/job_invocations_controller.rb +0 -1
  4. data/app/controllers/ui_job_wizard_controller.rb +1 -6
  5. data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
  6. data/app/views/job_invocations/show.html.erb +1 -1
  7. data/app/views/job_invocations/welcome.html.erb +1 -1
  8. data/db/migrate/20210816100932_rex_setting_category_to_dsl.rb +1 -1
  9. data/lib/foreman_remote_execution/engine.rb +1 -1
  10. data/lib/foreman_remote_execution/version.rb +1 -1
  11. data/locale/action_names.rb +2 -2
  12. data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  13. data/locale/de/foreman_remote_execution.po +154 -266
  14. data/locale/en/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  15. data/locale/en/foreman_remote_execution.po +24 -132
  16. data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  17. data/locale/en_GB/foreman_remote_execution.po +41 -149
  18. data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  19. data/locale/es/foreman_remote_execution.po +210 -320
  20. data/locale/foreman_remote_execution.pot +211 -394
  21. data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  22. data/locale/fr/foreman_remote_execution.po +241 -353
  23. data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  24. data/locale/ja/foreman_remote_execution.po +261 -368
  25. data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  26. data/locale/ko/foreman_remote_execution.po +53 -161
  27. data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  28. data/locale/pt_BR/foreman_remote_execution.po +225 -335
  29. data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  30. data/locale/ru/foreman_remote_execution.po +53 -161
  31. data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  32. data/locale/zh_CN/foreman_remote_execution.po +359 -465
  33. data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  34. data/locale/zh_TW/foreman_remote_execution.po +54 -162
  35. data/webpack/JobWizard/JobWizard.js +10 -52
  36. data/webpack/JobWizard/JobWizard.scss +1 -5
  37. data/webpack/JobWizard/__tests__/__snapshots__/integration.test.js.snap +0 -8
  38. data/webpack/JobWizard/__tests__/fixtures.js +0 -5
  39. data/webpack/JobWizard/__tests__/integration.test.js +0 -15
  40. data/webpack/JobWizard/__tests__/validation.test.js +0 -27
  41. data/webpack/JobWizard/autofill.js +0 -1
  42. data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +0 -19
  43. data/webpack/JobWizard/steps/AdvancedFields/__tests__/__snapshots__/AdvancedFields.test.js.snap +1 -9
  44. data/webpack/JobWizard/steps/HostsAndInputs/HostPreviewModal.js +0 -3
  45. data/webpack/JobWizard/steps/HostsAndInputs/HostSearch.js +4 -28
  46. data/webpack/JobWizard/steps/HostsAndInputs/__tests__/HostsAndInputs.test.js +1 -31
  47. data/webpack/JobWizard/steps/HostsAndInputs/buildHostQuery.js +10 -16
  48. data/webpack/JobWizard/steps/HostsAndInputs/index.js +3 -55
  49. data/webpack/JobWizard/steps/Schedule/__tests__/Schedule.test.js +1 -21
  50. data/webpack/JobWizard/steps/form/Formatter.js +8 -30
  51. data/webpack/JobWizard/submit.js +2 -13
  52. metadata +3 -3
@@ -209,11 +209,6 @@ export const JobWizard = ({ rerunData }) => {
209
209
  !templateError &&
210
210
  !!jobTemplateID &&
211
211
  templateResponse.job_template;
212
- const areHostsSelected =
213
- selectedTargets.hosts.length > 0 ||
214
- selectedTargets.hostCollections.length > 0 ||
215
- selectedTargets.hostGroups.length > 0 ||
216
- hostsSearchQuery.length > 0;
217
212
  const steps = [
218
213
  {
219
214
  name: WIZARD_TITLES.categoryAndTemplate,
@@ -243,7 +238,7 @@ export const JobWizard = ({ rerunData }) => {
243
238
  />
244
239
  ),
245
240
  canJumpTo: isTemplate,
246
- enableNext: isTemplate && valid.hostsAndInputs && areHostsSelected,
241
+ enableNext: isTemplate && valid.hostsAndInputs,
247
242
  },
248
243
  {
249
244
  name: WIZARD_TITLES.advanced,
@@ -259,26 +254,14 @@ export const JobWizard = ({ rerunData }) => {
259
254
  templateValues={templateValues}
260
255
  />
261
256
  ),
262
- canJumpTo: isTemplate && valid.hostsAndInputs && areHostsSelected,
263
- enableNext:
264
- isTemplate &&
265
- valid.hostsAndInputs &&
266
- areHostsSelected &&
267
- valid.advanced,
257
+ canJumpTo: isTemplate && valid.hostsAndInputs,
258
+ enableNext: isTemplate && valid.hostsAndInputs && valid.advanced,
268
259
  },
269
260
  {
270
261
  name: WIZARD_TITLES.schedule,
271
- canJumpTo:
272
- isTemplate &&
273
- valid.hostsAndInputs &&
274
- areHostsSelected &&
275
- valid.advanced,
262
+ canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced,
276
263
  enableNext:
277
- isTemplate &&
278
- valid.hostsAndInputs &&
279
- areHostsSelected &&
280
- valid.advanced &&
281
- valid.schedule,
264
+ isTemplate && valid.hostsAndInputs && valid.advanced && valid.schedule,
282
265
  steps: [
283
266
  {
284
267
  name: WIZARD_TITLES.typeOfExecution,
@@ -295,17 +278,9 @@ export const JobWizard = ({ rerunData }) => {
295
278
  }}
296
279
  />
297
280
  ),
298
- canJumpTo:
299
- isTemplate &&
300
- valid.hostsAndInputs &&
301
- areHostsSelected &&
302
- valid.advanced,
281
+ canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced,
303
282
 
304
- enableNext:
305
- isTemplate &&
306
- valid.hostsAndInputs &&
307
- areHostsSelected &&
308
- valid.advanced,
283
+ enableNext: isTemplate && valid.hostsAndInputs && valid.advanced,
309
284
  },
310
285
  ...(scheduleValue.scheduleType === SCHEDULE_TYPES.FUTURE
311
286
  ? [
@@ -323,15 +298,10 @@ export const JobWizard = ({ rerunData }) => {
323
298
  }}
324
299
  />
325
300
  ),
326
- canJumpTo:
327
- isTemplate &&
328
- valid.hostsAndInputs &&
329
- areHostsSelected &&
330
- valid.advanced,
301
+ canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced,
331
302
  enableNext:
332
303
  isTemplate &&
333
304
  valid.hostsAndInputs &&
334
- areHostsSelected &&
335
305
  valid.advanced &&
336
306
  valid.schedule,
337
307
  },
@@ -353,15 +323,10 @@ export const JobWizard = ({ rerunData }) => {
353
323
  }}
354
324
  />
355
325
  ),
356
- canJumpTo:
357
- isTemplate &&
358
- valid.hostsAndInputs &&
359
- areHostsSelected &&
360
- valid.advanced,
326
+ canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced,
361
327
  enableNext:
362
328
  isTemplate &&
363
329
  valid.hostsAndInputs &&
364
- areHostsSelected &&
365
330
  valid.advanced &&
366
331
  valid.schedule,
367
332
  },
@@ -384,15 +349,10 @@ export const JobWizard = ({ rerunData }) => {
384
349
  ),
385
350
  nextButtonText: 'Run',
386
351
  canJumpTo:
387
- isTemplate &&
388
- valid.advanced &&
389
- valid.hostsAndInputs &&
390
- areHostsSelected &&
391
- valid.schedule,
352
+ isTemplate && valid.hostsAndInputs && valid.advanced && valid.schedule,
392
353
  enableNext:
393
354
  isTemplate &&
394
355
  valid.hostsAndInputs &&
395
- areHostsSelected &&
396
356
  valid.advanced &&
397
357
  valid.schedule &&
398
358
  !isSubmitting,
@@ -419,8 +379,6 @@ export const JobWizard = ({ rerunData }) => {
419
379
  location,
420
380
  organization,
421
381
  feature: routerSearch?.feature,
422
- provider: templateResponse.provider_name,
423
- advancedInputs: templateResponse.advanced_template_inputs,
424
382
  });
425
383
  }}
426
384
  />
@@ -1,4 +1,5 @@
1
1
  .job-wizard {
2
+ font-size: var(--pf-global--FontSize--md);
2
3
  .wizard-title {
3
4
  margin-bottom: 25px;
4
5
  }
@@ -134,11 +135,6 @@
134
135
  margin-left: 10px;
135
136
  }
136
137
  }
137
- .foreman-search-field {
138
- .autocomplete-search-btn {
139
- display: none;
140
- }
141
- }
142
138
  .pf-c-radio__body {
143
139
  font-size: var(--pf-c-radio__label--FontSize);
144
140
  }
@@ -7,14 +7,6 @@ Array [
7
7
  "type": "get",
8
8
  "url": "/ui_job_wizard/categories",
9
9
  },
10
- Object {
11
- "key": "HOST_IDS",
12
- "params": Object {
13
- "search": "id = 105 or id = 37",
14
- },
15
- "type": "get",
16
- "url": "/api/hosts",
17
- },
18
10
  Object {
19
11
  "key": "JOB_TEMPLATES",
20
12
  "type": "get",
@@ -161,11 +161,6 @@ export const testSetup = (selectors, api) => {
161
161
  ],
162
162
  },
163
163
  },
164
- HOSTS_API: {
165
- response: {
166
- subtotal: 3,
167
- },
168
- },
169
164
  });
170
165
  return store;
171
166
  };
@@ -18,15 +18,6 @@ import {
18
18
  const store = testSetup(selectors, api);
19
19
 
20
20
  describe('Job wizard fill', () => {
21
- beforeEach(() => {
22
- jest.spyOn(selectors, 'selectRouterSearch');
23
- selectors.selectRouterSearch.mockImplementation(() => ({
24
- 'host_ids[]': ['105', '37'],
25
- }));
26
- });
27
- afterEach(() => {
28
- selectors.selectRouterSearch.mockRestore();
29
- });
30
21
  it('should select template', async () => {
31
22
  api.get.mockImplementation(({ handleSuccess, ...action }) => {
32
23
  if (action.key === 'JOB_CATEGORIES') {
@@ -42,13 +33,7 @@ describe('Job wizard fill', () => {
42
33
  handleSuccess({
43
34
  data: jobTemplate,
44
35
  });
45
- } else if (action.key === 'HOST_IDS') {
46
- handleSuccess &&
47
- handleSuccess({
48
- data: { results: [{ name: 'host1' }, { name: 'host3' }] },
49
- });
50
36
  }
51
-
52
37
  return { type: 'get', ...action };
53
38
  });
54
39
  selectors.selectJobTemplate.mockRestore();
@@ -41,26 +41,11 @@ describe('Job wizard validation', () => {
41
41
  expect(screen.getByText(WIZARD_TITLES.review)).toBeDisabled();
42
42
  await act(async () => {
43
43
  fireEvent.click(screen.getByText(WIZARD_TITLES.hostsAndInputs));
44
- await new Promise(resolve => setTimeout(resolve, 0)); // to resolve gql
45
44
  });
46
- const select = name =>
47
- screen.getByRole('button', { name: `${name} toggle` });
48
- fireEvent.click(select('hosts'));
49
- await act(async () => {
50
- fireEvent.click(screen.getByText('host1'));
51
- });
52
-
53
- expect(screen.getByText(WIZARD_TITLES.advanced)).toBeDisabled();
54
- expect(screen.getByText(WIZARD_TITLES.schedule)).toBeDisabled();
55
- expect(screen.getByText(WIZARD_TITLES.review)).toBeDisabled();
56
45
  const textField = screen.getByLabelText('plain hidden', {
57
46
  selector: 'textarea',
58
47
  });
59
48
  await act(async () => {
60
- fireEvent.click(
61
- // Close the select
62
- select('hosts')
63
- );
64
49
  await fireEvent.change(textField, {
65
50
  target: { value: 'text' },
66
51
  });
@@ -100,20 +85,8 @@ describe('Job wizard validation', () => {
100
85
  // setup
101
86
  await act(async () => {
102
87
  fireEvent.click(screen.getByText(WIZARD_TITLES.hostsAndInputs));
103
- await new Promise(resolve => setTimeout(resolve, 0)); // to resolve gql
104
88
  });
105
-
106
- const select = name =>
107
- screen.getByRole('button', { name: `${name} toggle` });
108
- fireEvent.click(select('hosts'));
109
89
  await act(async () => {
110
- fireEvent.click(screen.getByText('host1'));
111
- });
112
- await act(async () => {
113
- fireEvent.click(
114
- // Close the host select
115
- select('hosts')
116
- );
117
90
  await fireEvent.change(
118
91
  screen.getByLabelText('plain hidden', {
119
92
  selector: 'textarea',
@@ -72,7 +72,6 @@ export const useAutoFill = ({
72
72
  if (input) {
73
73
  if (typeof rest[key] === 'string') {
74
74
  setTemplateValues(prev => ({ ...prev, [input]: rest[key] }));
75
- setAdvancedValues(prev => ({ ...prev, [input]: rest[key] }));
76
75
  } else {
77
76
  const { value, advanced } = rest[key];
78
77
  if (advanced) {
@@ -26,15 +26,6 @@ mockApi(api);
26
26
  jest.useFakeTimers();
27
27
 
28
28
  describe('AdvancedFields', () => {
29
- beforeEach(() => {
30
- jest.spyOn(selectors, 'selectRouterSearch');
31
- selectors.selectRouterSearch.mockImplementation(() => ({
32
- 'host_ids[]': ['105', '37'],
33
- }));
34
- });
35
- afterEach(() => {
36
- selectors.selectRouterSearch.mockRestore();
37
- });
38
29
  it('should save data between steps for advanced fields', async () => {
39
30
  const wrapper = mount(
40
31
  <MockedProvider mocks={gqlMock} addTypename={false}>
@@ -279,11 +270,6 @@ describe('AdvancedFields', () => {
279
270
  handleSuccess({
280
271
  data: { results: [jobTemplate] },
281
272
  });
282
- } else if (action.key === 'HOST_IDS') {
283
- handleSuccess &&
284
- handleSuccess({
285
- data: { results: [{ name: 'host1' }, { name: 'host3' }] },
286
- });
287
273
  }
288
274
  return { type: 'get', ...action };
289
275
  });
@@ -353,11 +339,6 @@ describe('AdvancedFields', () => {
353
339
  handleSuccess({
354
340
  data: { results: [jobTemplate] },
355
341
  });
356
- } else if (action.key === 'HOST_IDS') {
357
- handleSuccess &&
358
- handleSuccess({
359
- data: { results: [{ name: 'host1' }, { name: 'host3' }] },
360
- });
361
342
  }
362
343
  return { type: 'get', ...action };
363
344
  });
@@ -7,14 +7,6 @@ Array [
7
7
  "type": "get",
8
8
  "url": "/ui_job_wizard/categories",
9
9
  },
10
- Object {
11
- "key": "HOST_IDS",
12
- "params": Object {
13
- "search": "id = 105 or id = 37",
14
- },
15
- "type": "get",
16
- "url": "/api/hosts",
17
- },
18
10
  Object {
19
11
  "key": "JOB_TEMPLATES",
20
12
  "type": "get",
@@ -57,7 +49,7 @@ Array [
57
49
  "port": null,
58
50
  "preventInvalidHostname": false,
59
51
  "protocol": null,
60
- "query": "resource=ForemanTasks%3A%3ATask",
52
+ "query": "resource=ForemanTasks%3A%3ATask&name=some+search",
61
53
  "urn": null,
62
54
  "username": null,
63
55
  },
@@ -60,6 +60,3 @@ HostPreviewModal.propTypes = {
60
60
  setIsOpen: PropTypes.func.isRequired,
61
61
  searchQuery: PropTypes.string.isRequired,
62
62
  };
63
- HostPreviewModal.defaultPropTypes = {
64
- searchQuery: '',
65
- };
@@ -1,33 +1,10 @@
1
- import React, { useEffect } from 'react';
2
- import { useSelector, useDispatch } from 'react-redux';
1
+ import React from 'react';
3
2
  import PropTypes from 'prop-types';
4
3
  import SearchBar from 'foremanReact/components/SearchBar';
5
4
  import { getControllerSearchProps } from 'foremanReact/constants';
6
- import { getResults } from 'foremanReact/components/AutoComplete/AutoCompleteActions';
7
- import { TRIGGERS } from 'foremanReact/components/AutoComplete/AutoCompleteConstants';
8
5
  import { hostsController, hostQuerySearchID } from '../../JobWizardConstants';
9
- import { noop } from '../../../helpers';
10
6
 
11
7
  export const HostSearch = ({ value, setValue }) => {
12
- const searchQuery = useSelector(
13
- state => state.autocomplete?.[hostQuerySearchID]?.searchQuery
14
- );
15
- useEffect(() => {
16
- setValue(searchQuery || '');
17
- }, [setValue, searchQuery]);
18
- const dispatch = useDispatch();
19
- const setSearch = newSearchQuery => {
20
- dispatch(
21
- getResults({
22
- url: '/hosts/auto_complete_search',
23
- searchQuery: newSearchQuery,
24
- controller: 'hostsController',
25
- trigger: TRIGGERS.INPUT_CHANGE,
26
- id: hostQuerySearchID,
27
- })
28
- );
29
- };
30
-
31
8
  const props = getControllerSearchProps(hostsController, hostQuerySearchID);
32
9
  return (
33
10
  <div className="foreman-search-field">
@@ -37,12 +14,11 @@ export const HostSearch = ({ value, setValue }) => {
37
14
  autocomplete: {
38
15
  id: hostQuerySearchID,
39
16
  url: '/hosts/auto_complete_search',
40
- useKeyShortcuts: true,
17
+ searchQuery: value,
41
18
  },
42
19
  }}
43
- onSearch={noop}
44
- initialQuery={value}
45
- onBookmarkClick={search => setSearch(search)}
20
+ onSearch={null}
21
+ onSearchChange={search => setValue(search)}
46
22
  />
47
23
  </div>
48
24
  );
@@ -30,27 +30,6 @@ describe('Hosts', () => {
30
30
  const select = name =>
31
31
  screen.getByRole('button', { name: `${name} toggle` });
32
32
  fireEvent.click(select('hosts'));
33
- await act(async () => {
34
- fireEvent.click(screen.getByText('host1'));
35
- fireEvent.click(select('hosts'));
36
- });
37
- expect(
38
- screen.queryAllByText('Please select at least one host')
39
- ).toHaveLength(0);
40
- await act(async () => {
41
- fireEvent.click(select('hosts'));
42
- });
43
- await act(async () => {
44
- fireEvent.click(
45
- screen.getByText('host1', {
46
- selector: '.pf-c-select__menu-item',
47
- })
48
- );
49
- fireEvent.blur(select('hosts'));
50
- });
51
- expect(
52
- screen.queryAllByText('Please select at least one host')
53
- ).toHaveLength(1);
54
33
  await act(async () => {
55
34
  fireEvent.click(screen.getByText('host1'));
56
35
  fireEvent.click(screen.getByText('host2'));
@@ -172,9 +151,8 @@ describe('Hosts', () => {
172
151
 
173
152
  it('input fill from url', async () => {
174
153
  const inputText = 'test text';
175
- const advancedInputText = 'test adv text';
176
154
  routerSelectors.selectRouterLocation.mockImplementation(() => ({
177
- search: `host_ids%5B%5D=host1&host_ids%5B%5D=host3&feature=test_feature&inputs[plain hidden]=${inputText}&inputs[adv plain hidden]=${advancedInputText}`,
155
+ search: `feature=test_feature&inputs[plain hidden]=${inputText}`,
178
156
  }));
179
157
  render(
180
158
  <MockedProvider mocks={gqlMock} addTypename={false}>
@@ -197,13 +175,5 @@ describe('Hosts', () => {
197
175
  selector: 'textarea',
198
176
  });
199
177
  expect(textField.value).toBe(inputText);
200
-
201
- await act(async () => {
202
- fireEvent.click(screen.getByText('Advanced fields'));
203
- });
204
- const advancedTextField = screen.getByLabelText('adv plain hidden', {
205
- selector: 'textarea',
206
- });
207
- expect(advancedTextField.value).toBe(advancedInputText);
208
178
  });
209
179
  });
@@ -1,24 +1,18 @@
1
1
  export const buildHostQuery = (selected, search) => {
2
2
  const { hosts, hostCollections, hostGroups } = selected;
3
- const hostsSearch = `id ^ (${hosts.map(({ id }) => id).join(',')})`;
4
- const hostCollectionsSearch = `host_collection_id ^ (${hostCollections
3
+ const hostsSearch = `(id ^ (${hosts.map(({ id }) => id).join(',')}))`;
4
+ const hostCollectionsSearch = `(host_collection_id ^ (${hostCollections
5
5
  .map(({ id }) => id)
6
- .join(',')})`;
7
- const hostGroupsSearch = `hostgroup_id ^ (${hostGroups
6
+ .join(',')}))`;
7
+ const hostGroupsSearch = `(hostgroup_id ^ (${hostGroups
8
8
  .map(({ id }) => id)
9
- .join(',')})`;
10
- const queryParts = [
9
+ .join(',')}))`;
10
+ return [
11
11
  hosts.length ? hostsSearch : false,
12
12
  hostCollections.length ? hostCollectionsSearch : false,
13
13
  hostGroups.length ? hostGroupsSearch : false,
14
- search.length ? search : false,
15
- ].filter(Boolean);
16
-
17
- if (queryParts.length === 0) {
18
- return 'name=a AND name=b';
19
- }
20
- if (queryParts.length === 1) {
21
- return queryParts[0] || 'name=a AND name=b';
22
- }
23
- return queryParts.map(p => `(${p})`).join(' or ') || 'name=a AND name=b';
14
+ search.length ? `(${search})` : false,
15
+ ]
16
+ .filter(Boolean)
17
+ .join(' or ');
24
18
  };
@@ -13,7 +13,6 @@ import { FilterIcon } from '@patternfly/react-icons';
13
13
  import { debounce } from 'lodash';
14
14
  import { get } from 'foremanReact/redux/API';
15
15
  import { translate as __ } from 'foremanReact/common/I18n';
16
- import { resetData } from 'foremanReact/components/AutoComplete/AutoCompleteActions';
17
16
  import {
18
17
  selectTemplateInputs,
19
18
  selectWithKatello,
@@ -31,8 +30,6 @@ import {
31
30
  HOST_COLLECTIONS,
32
31
  HOST_GROUPS,
33
32
  hostMethods,
34
- hostsController,
35
- hostQuerySearchID,
36
33
  HOSTS_API,
37
34
  HOSTS_TO_PREVIEW_AMOUNT,
38
35
  DEBOUNCE_API,
@@ -54,30 +51,6 @@ const HostsAndInputs = ({
54
51
  const isLoading = useSelector(selectIsLoadingHosts);
55
52
  const templateInputs = useSelector(selectTemplateInputs);
56
53
  const [hostPreviewOpen, setHostPreviewOpen] = useState(false);
57
- const [wasFocus, setWasFocus] = useState(false);
58
- const [isError, setIsError] = useState(false);
59
- useEffect(() => {
60
- if (wasFocus) {
61
- if (
62
- selected.hosts.length === 0 &&
63
- selected.hostCollections.length === 0 &&
64
- selected.hostGroups.length === 0 &&
65
- hostsSearchQuery.length === 0
66
- ) {
67
- setIsError(true);
68
- } else {
69
- setIsError(false);
70
- }
71
- }
72
- }, [
73
- hostMethod,
74
- hostsSearchQuery.length,
75
- selected,
76
- selected.hostCollections.length,
77
- selected.hostGroups.length,
78
- selected.hosts.length,
79
- wasFocus,
80
- ]);
81
54
  useEffect(() => {
82
55
  debounce(() => {
83
56
  dispatch(
@@ -124,12 +97,8 @@ const HostsAndInputs = ({
124
97
  };
125
98
 
126
99
  const clearSearch = () => {
127
- dispatch(resetData(hostsController, hostQuerySearchID));
128
100
  setHostsSearchQuery('');
129
101
  };
130
- const [errorText, setErrorText] = useState(
131
- __('Please select at least one host')
132
- );
133
102
  return (
134
103
  <div className="target-hosts-and-inputs">
135
104
  <WizardTitle title={WIZARD_TITLES.hostsAndInputs} />
@@ -141,13 +110,8 @@ const HostsAndInputs = ({
141
110
  />
142
111
  )}
143
112
  <Form>
144
- <FormGroup
145
- fieldId="host_selection"
146
- id="host-selection"
147
- helperTextInvalid={errorText}
148
- validated={isError ? 'error' : 'default'}
149
- >
150
- <InputGroup onBlur={() => setWasFocus(true)}>
113
+ <FormGroup fieldId="host_selection" id="host-selection">
114
+ <InputGroup>
151
115
  <SelectField
152
116
  isRequired
153
117
  className="target-method-select"
@@ -159,23 +123,7 @@ const HostsAndInputs = ({
159
123
  }
160
124
  return true;
161
125
  })}
162
- setValue={val => {
163
- setHostMethod(val);
164
- if (val === hostMethods.searchQuery) {
165
- setErrorText(__('Please enter a search query'));
166
- }
167
- if (val === hostMethods.hosts) {
168
- setErrorText(__('Please select at least one host'));
169
- }
170
- if (val === hostMethods.hostCollections) {
171
- setErrorText(
172
- __('Please select at least one host collection')
173
- );
174
- }
175
- if (val === hostMethods.hostGroups) {
176
- setErrorText(__('Please select at least one host group'));
177
- }
178
- }}
126
+ setValue={setHostMethod}
179
127
  value={hostMethod}
180
128
  />
181
129
  {hostMethod === hostMethods.searchQuery && (
@@ -39,35 +39,15 @@ api.get.mockImplementation(({ handleSuccess, ...action }) => {
39
39
  handleSuccess({
40
40
  data: { results: [jobTemplateResponse.job_template] },
41
41
  });
42
- } else if (action.key === 'HOST_IDS') {
43
- handleSuccess &&
44
- handleSuccess({
45
- data: { results: [{ name: 'host1' }, { name: 'host3' }] },
46
- });
47
42
  }
48
43
  return { type: 'get', ...action };
49
44
  });
50
45
 
51
46
  const mockStore = configureMockStore([]);
52
- const store = mockStore({
53
- HOSTS_API: {
54
- response: {
55
- subtotal: 3,
56
- },
57
- },
58
- });
47
+ const store = mockStore({});
59
48
  jest.useFakeTimers();
60
49
 
61
50
  describe('Schedule', () => {
62
- beforeEach(() => {
63
- jest.spyOn(selectors, 'selectRouterSearch');
64
- selectors.selectRouterSearch.mockImplementation(() => ({
65
- 'host_ids[]': ['105', '37'],
66
- }));
67
- });
68
- afterEach(() => {
69
- selectors.selectRouterSearch.mockRestore();
70
- });
71
51
  it('sub steps appear', () => {
72
52
  render(
73
53
  <Provider store={store}>