foreman_remote_execution 5.1.0 → 6.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.
- checksums.yaml +4 -4
- data/README.md +7 -0
- data/app/controllers/ui_job_wizard_controller.rb +12 -1
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +20 -9
- data/app/helpers/remote_execution_helper.rb +1 -1
- data/app/mailers/rex_job_mailer.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +4 -0
- data/app/models/targeting.rb +1 -1
- data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
- data/app/views/template_invocations/show.html.erb +1 -1
- data/lib/foreman_remote_execution/engine.rb +6 -2
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +3 -4
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +356 -20
- data/locale/en/foreman_remote_execution.po +356 -20
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +356 -20
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +357 -21
- data/locale/foreman_remote_execution.pot +808 -296
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +357 -21
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +357 -21
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +356 -20
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +357 -21
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +356 -20
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +357 -21
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +356 -20
- data/webpack/JobWizard/JobWizard.js +22 -5
- data/webpack/JobWizard/JobWizard.scss +5 -0
- data/webpack/JobWizard/JobWizardConstants.js +2 -1
- data/webpack/JobWizard/__tests__/fixtures.js +13 -2
- data/webpack/JobWizard/__tests__/integration.test.js +6 -1
- data/webpack/JobWizard/autofill.js +34 -9
- data/webpack/JobWizard/index.js +0 -7
- data/webpack/JobWizard/steps/CategoryAndTemplate/index.js +25 -7
- data/webpack/JobWizard/steps/HostsAndInputs/HostSearch.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/__tests__/HostsAndInputs.test.js +28 -0
- data/webpack/JobWizard/steps/Schedule/RepeatOn.js +1 -1
- data/webpack/JobWizard/steps/form/Formatter.js +18 -3
- data/webpack/__mocks__/foremanReact/components/Pagination.js +2 -0
- data/webpack/__mocks__/foremanReact/constants.js +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsHelpers.js +1 -1
- data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +1 -6
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +1 -9
- data/webpack/react_app/components/TargetingHosts/index.js +2 -3
- metadata +3 -4
- data/app/views/templates/README.md +0 -6
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
@@ -20,6 +20,7 @@ import {
|
|
20
20
|
selectTemplateError,
|
21
21
|
selectJobTemplate,
|
22
22
|
selectIsSubmitting,
|
23
|
+
selectRouterSearch,
|
23
24
|
} from './JobWizardSelectors';
|
24
25
|
import Schedule from './steps/Schedule/';
|
25
26
|
import HostsAndInputs from './steps/HostsAndInputs/';
|
@@ -41,6 +42,7 @@ export const JobWizard = () => {
|
|
41
42
|
hostGroups: [],
|
42
43
|
});
|
43
44
|
const [hostsSearchQuery, setHostsSearchQuery] = useState('');
|
45
|
+
const [fills, setFills] = useState(useSelector(selectRouterSearch));
|
44
46
|
const dispatch = useDispatch();
|
45
47
|
|
46
48
|
const setDefaults = useCallback(
|
@@ -49,17 +51,26 @@ export const JobWizard = () => {
|
|
49
51
|
template_inputs,
|
50
52
|
advanced_template_inputs,
|
51
53
|
effective_user,
|
52
|
-
job_template: {
|
54
|
+
job_template: {
|
55
|
+
name,
|
56
|
+
execution_timeout_interval,
|
57
|
+
description_format,
|
58
|
+
job_category,
|
59
|
+
},
|
53
60
|
},
|
54
61
|
}) => {
|
62
|
+
if (!category.length) {
|
63
|
+
setCategory(current => (current.length ? current : job_category));
|
64
|
+
}
|
55
65
|
const advancedTemplateValues = {};
|
56
66
|
const defaultTemplateValues = {};
|
57
67
|
const inputs = template_inputs;
|
58
68
|
const advancedInputs = advanced_template_inputs;
|
59
69
|
if (inputs) {
|
60
|
-
setTemplateValues(
|
70
|
+
setTemplateValues(prev => {
|
61
71
|
inputs.forEach(input => {
|
62
|
-
defaultTemplateValues[input.name] =
|
72
|
+
defaultTemplateValues[input.name] =
|
73
|
+
prev[input.name] || input?.default || '';
|
63
74
|
});
|
64
75
|
return defaultTemplateValues;
|
65
76
|
});
|
@@ -67,7 +78,8 @@ export const JobWizard = () => {
|
|
67
78
|
setAdvancedValues(currentAdvancedValues => {
|
68
79
|
if (advancedInputs) {
|
69
80
|
advancedInputs.forEach(input => {
|
70
|
-
advancedTemplateValues[input.name] =
|
81
|
+
advancedTemplateValues[input.name] =
|
82
|
+
currentAdvancedValues[input.name] || input?.default || '';
|
71
83
|
});
|
72
84
|
}
|
73
85
|
const generateDefaultDescription = () => {
|
@@ -89,7 +101,7 @@ export const JobWizard = () => {
|
|
89
101
|
};
|
90
102
|
});
|
91
103
|
},
|
92
|
-
[]
|
104
|
+
[category.length]
|
93
105
|
);
|
94
106
|
useEffect(() => {
|
95
107
|
if (jobTemplateID) {
|
@@ -108,8 +120,12 @@ export const JobWizard = () => {
|
|
108
120
|
templateValues,
|
109
121
|
});
|
110
122
|
useAutoFill({
|
123
|
+
fills,
|
124
|
+
setFills,
|
111
125
|
setSelectedTargets,
|
112
126
|
setHostsSearchQuery,
|
127
|
+
setJobTemplateID,
|
128
|
+
setTemplateValues,
|
113
129
|
});
|
114
130
|
const templateError = !!useSelector(selectTemplateError);
|
115
131
|
const templateResponse = useSelector(selectJobTemplate);
|
@@ -126,6 +142,7 @@ export const JobWizard = () => {
|
|
126
142
|
setJobTemplate={setJobTemplateID}
|
127
143
|
category={category}
|
128
144
|
setCategory={setCategory}
|
145
|
+
isFeature={!!fills.feature}
|
129
146
|
/>
|
130
147
|
),
|
131
148
|
enableNext: isTemplate,
|
@@ -47,7 +47,7 @@ export const hostMethods = {
|
|
47
47
|
searchQuery: __('Search query'),
|
48
48
|
};
|
49
49
|
|
50
|
-
export const hostQuerySearchID = '
|
50
|
+
export const hostQuerySearchID = 'mainHostQuery';
|
51
51
|
export const hostsController = 'hosts';
|
52
52
|
|
53
53
|
export const dataName = {
|
@@ -58,3 +58,4 @@ export const HOSTS_TO_PREVIEW_AMOUNT = 20;
|
|
58
58
|
|
59
59
|
export const DEBOUNCE_HOST_COUNT = 700;
|
60
60
|
export const HOST_IDS = 'HOST_IDS';
|
61
|
+
export const REX_FEATURE = 'REX_FEATURE';
|
@@ -69,6 +69,7 @@ export const jobTemplateResponse = {
|
|
69
69
|
default: '',
|
70
70
|
hidden_value: false,
|
71
71
|
url: 'foreman_tasks/tasks',
|
72
|
+
resource_type_tableize: 'hosts',
|
72
73
|
},
|
73
74
|
{
|
74
75
|
name: 'adv date',
|
@@ -96,7 +97,7 @@ export const jobTemplateResponse = {
|
|
96
97
|
],
|
97
98
|
};
|
98
99
|
|
99
|
-
export const jobCategories = ['Ansible Commands', 'Puppet'
|
100
|
+
export const jobCategories = ['Services', 'Ansible Commands', 'Puppet'];
|
100
101
|
|
101
102
|
export const testSetup = (selectors, api) => {
|
102
103
|
jest.spyOn(api, 'get');
|
@@ -149,7 +150,12 @@ export const mockApi = api => {
|
|
149
150
|
api.get.mockImplementation(({ handleSuccess, ...action }) => {
|
150
151
|
if (action.key === 'JOB_CATEGORIES') {
|
151
152
|
handleSuccess &&
|
152
|
-
handleSuccess({
|
153
|
+
handleSuccess({
|
154
|
+
data: {
|
155
|
+
job_categories: jobCategories,
|
156
|
+
default_category: 'Ansible Commands',
|
157
|
+
},
|
158
|
+
});
|
153
159
|
} else if (action.key === 'JOB_TEMPLATE') {
|
154
160
|
handleSuccess &&
|
155
161
|
handleSuccess({
|
@@ -165,6 +171,11 @@ export const mockApi = api => {
|
|
165
171
|
handleSuccess({
|
166
172
|
data: { results: [{ name: 'host1' }, { name: 'host3' }] },
|
167
173
|
});
|
174
|
+
} else if (action.key === 'REX_FEATURE') {
|
175
|
+
handleSuccess &&
|
176
|
+
handleSuccess({
|
177
|
+
data: { job_template_id: 178 },
|
178
|
+
});
|
168
179
|
}
|
169
180
|
return { type: 'get', ...action };
|
170
181
|
});
|
@@ -22,7 +22,12 @@ describe('Job wizard fill', () => {
|
|
22
22
|
api.get.mockImplementation(({ handleSuccess, ...action }) => {
|
23
23
|
if (action.key === 'JOB_CATEGORIES') {
|
24
24
|
handleSuccess &&
|
25
|
-
handleSuccess({
|
25
|
+
handleSuccess({
|
26
|
+
data: {
|
27
|
+
job_categories: jobCategories,
|
28
|
+
default_category: 'Ansible Commands',
|
29
|
+
},
|
30
|
+
});
|
26
31
|
} else if (action.key === 'JOB_TEMPLATE') {
|
27
32
|
handleSuccess &&
|
28
33
|
handleSuccess({
|
@@ -1,22 +1,29 @@
|
|
1
1
|
import { useEffect } from 'react';
|
2
|
-
import { useDispatch
|
2
|
+
import { useDispatch } from 'react-redux';
|
3
3
|
import { get } from 'foremanReact/redux/API';
|
4
|
-
import { HOST_IDS } from './JobWizardConstants';
|
5
|
-
import { selectRouterSearch } from './JobWizardSelectors';
|
4
|
+
import { HOST_IDS, REX_FEATURE } from './JobWizardConstants';
|
6
5
|
import './JobWizard.scss';
|
7
6
|
|
8
|
-
export const useAutoFill = ({
|
9
|
-
|
7
|
+
export const useAutoFill = ({
|
8
|
+
fills,
|
9
|
+
setFills,
|
10
|
+
setSelectedTargets,
|
11
|
+
setHostsSearchQuery,
|
12
|
+
setJobTemplateID,
|
13
|
+
setTemplateValues,
|
14
|
+
}) => {
|
10
15
|
const dispatch = useDispatch();
|
11
16
|
|
12
17
|
useEffect(() => {
|
13
18
|
if (Object.keys(fills).length) {
|
14
|
-
|
19
|
+
const { 'host_ids[]': hostIds, search, feature, ...rest } = { ...fills };
|
20
|
+
setFills({});
|
21
|
+
if (hostIds) {
|
15
22
|
dispatch(
|
16
23
|
get({
|
17
24
|
key: HOST_IDS,
|
18
25
|
url: '/api/hosts',
|
19
|
-
params: { search: `id = ${
|
26
|
+
params: { search: `id = ${hostIds.join(' or id = ')}` },
|
20
27
|
handleSuccess: ({ data }) => {
|
21
28
|
setSelectedTargets(currentTargets => ({
|
22
29
|
...currentTargets,
|
@@ -29,8 +36,26 @@ export const useAutoFill = ({ setSelectedTargets, setHostsSearchQuery }) => {
|
|
29
36
|
})
|
30
37
|
);
|
31
38
|
}
|
32
|
-
if (
|
33
|
-
setHostsSearchQuery(
|
39
|
+
if (search) {
|
40
|
+
setHostsSearchQuery(search);
|
41
|
+
}
|
42
|
+
if (feature) {
|
43
|
+
dispatch(
|
44
|
+
get({
|
45
|
+
key: REX_FEATURE,
|
46
|
+
url: `/api/remote_execution_features/${feature}`,
|
47
|
+
handleSuccess: ({ data }) => {
|
48
|
+
setJobTemplateID(data.job_template_id);
|
49
|
+
},
|
50
|
+
})
|
51
|
+
);
|
52
|
+
Object.keys(rest).forEach(key => {
|
53
|
+
const re = /inputs\[(?<input>.*)\]/g;
|
54
|
+
const input = re.exec(key)?.groups?.input;
|
55
|
+
if (input) {
|
56
|
+
setTemplateValues(prev => ({ ...prev, [input]: rest[key] }));
|
57
|
+
}
|
58
|
+
});
|
34
59
|
}
|
35
60
|
}
|
36
61
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
data/webpack/JobWizard/index.js
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
2
|
import { Title, Divider } from '@patternfly/react-core';
|
4
3
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
4
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
@@ -30,10 +29,4 @@ const JobWizardPage = () => {
|
|
30
29
|
);
|
31
30
|
};
|
32
31
|
|
33
|
-
JobWizardPage.propTypes = {
|
34
|
-
location: PropTypes.shape({
|
35
|
-
search: PropTypes.string,
|
36
|
-
}).isRequired,
|
37
|
-
};
|
38
|
-
|
39
32
|
export default JobWizardPage;
|
@@ -25,6 +25,7 @@ const ConnectedCategoryAndTemplate = ({
|
|
25
25
|
setJobTemplate,
|
26
26
|
category,
|
27
27
|
setCategory,
|
28
|
+
isFeature,
|
28
29
|
}) => {
|
29
30
|
const dispatch = useDispatch();
|
30
31
|
|
@@ -36,12 +37,23 @@ const ConnectedCategoryAndTemplate = ({
|
|
36
37
|
get({
|
37
38
|
key: JOB_CATEGORIES,
|
38
39
|
url: '/ui_job_wizard/categories',
|
39
|
-
handleSuccess:
|
40
|
-
|
40
|
+
handleSuccess: ({
|
41
|
+
data: {
|
42
|
+
default_category: defaultCategory,
|
43
|
+
job_categories: jobCategories,
|
44
|
+
default_template: defaultTemplate,
|
45
|
+
},
|
46
|
+
}) => {
|
47
|
+
if (!isFeature) {
|
48
|
+
setCategory(defaultCategory || jobCategories[0] || '');
|
49
|
+
if (defaultTemplate) setJobTemplate(defaultTemplate);
|
50
|
+
}
|
51
|
+
},
|
41
52
|
})
|
42
53
|
);
|
43
54
|
}
|
44
|
-
|
55
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
56
|
+
}, [jobCategoriesStatus]);
|
45
57
|
|
46
58
|
const jobCategories = useSelector(selectJobCategories);
|
47
59
|
useEffect(() => {
|
@@ -55,14 +67,19 @@ const ConnectedCategoryAndTemplate = ({
|
|
55
67
|
per_page: 'all',
|
56
68
|
}),
|
57
69
|
handleSuccess: response => {
|
58
|
-
|
59
|
-
|
60
|
-
|
70
|
+
if (!jobTemplate)
|
71
|
+
setJobTemplate(
|
72
|
+
current =>
|
73
|
+
current ||
|
74
|
+
Number(filterJobTemplates(response?.data?.results)[0]?.id) ||
|
75
|
+
null
|
76
|
+
);
|
61
77
|
},
|
62
78
|
})
|
63
79
|
);
|
64
80
|
}
|
65
|
-
|
81
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
82
|
+
}, [category, dispatch]);
|
66
83
|
|
67
84
|
const jobTemplates = useSelector(selectJobTemplates);
|
68
85
|
|
@@ -89,6 +106,7 @@ ConnectedCategoryAndTemplate.propTypes = {
|
|
89
106
|
setJobTemplate: PropTypes.func.isRequired,
|
90
107
|
category: PropTypes.string.isRequired,
|
91
108
|
setCategory: PropTypes.func.isRequired,
|
109
|
+
isFeature: PropTypes.bool.isRequired,
|
92
110
|
};
|
93
111
|
ConnectedCategoryAndTemplate.defaultProps = { jobTemplate: null };
|
94
112
|
|
@@ -10,7 +10,7 @@ import { noop } from '../../../helpers';
|
|
10
10
|
|
11
11
|
export const HostSearch = ({ value, setValue }) => {
|
12
12
|
const searchQuery = useSelector(
|
13
|
-
state => state.autocomplete?.
|
13
|
+
state => state.autocomplete?.[hostQuerySearchID]?.searchQuery
|
14
14
|
);
|
15
15
|
useEffect(() => {
|
16
16
|
setValue(searchQuery || '');
|
@@ -148,4 +148,32 @@ describe('Hosts', () => {
|
|
148
148
|
});
|
149
149
|
expect(screen.queryAllByText('os=gnome')).toHaveLength(1);
|
150
150
|
});
|
151
|
+
|
152
|
+
it('input fill from url', async () => {
|
153
|
+
const inputText = 'test text';
|
154
|
+
routerSelectors.selectRouterLocation.mockImplementation(() => ({
|
155
|
+
search: `feature=test_feature&inputs[plain hidden]=${inputText}`,
|
156
|
+
}));
|
157
|
+
render(
|
158
|
+
<MockedProvider mocks={gqlMock} addTypename={false}>
|
159
|
+
<Provider store={store}>
|
160
|
+
<JobWizard />
|
161
|
+
</Provider>
|
162
|
+
</MockedProvider>
|
163
|
+
);
|
164
|
+
api.get.mock.calls.forEach(call => {
|
165
|
+
if (call[0].key === 'REX_FEATURE') {
|
166
|
+
expect(call[0].url).toEqual(
|
167
|
+
'/api/remote_execution_features/test_feature'
|
168
|
+
);
|
169
|
+
}
|
170
|
+
});
|
171
|
+
await act(async () => {
|
172
|
+
fireEvent.click(screen.getByText('Target hosts and inputs'));
|
173
|
+
});
|
174
|
+
const textField = screen.getByLabelText('plain hidden', {
|
175
|
+
selector: 'textarea',
|
176
|
+
});
|
177
|
+
expect(textField.value).toBe(inputText);
|
178
|
+
});
|
151
179
|
});
|
@@ -21,7 +21,7 @@ export const RepeatOn = ({
|
|
21
21
|
}) => {
|
22
22
|
const [repeatValidated, setRepeatValidated] = useState('default');
|
23
23
|
const handleRepeatInputChange = newValue => {
|
24
|
-
setRepeatValidated(newValue >= 1 ? 'default' : 'error');
|
24
|
+
setRepeatValidated(!newValue || newValue >= 1 ? 'default' : 'error');
|
25
25
|
setRepeatAmount(newValue);
|
26
26
|
};
|
27
27
|
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import React, { useEffect } from 'react';
|
2
|
-
import { useSelector } from 'react-redux';
|
2
|
+
import { useSelector, useDispatch } from 'react-redux';
|
3
3
|
import { FormGroup, TextInput, TextArea } from '@patternfly/react-core';
|
4
4
|
import PropTypes from 'prop-types';
|
5
5
|
import SearchBar from 'foremanReact/components/SearchBar';
|
6
6
|
import { getControllerSearchProps } from 'foremanReact/constants';
|
7
|
+
import { TRIGGERS } from 'foremanReact/components/AutoComplete/AutoCompleteConstants';
|
8
|
+
import { getResults } from 'foremanReact/components/AutoComplete/AutoCompleteActions';
|
7
9
|
import { helpLabel } from './FormHelpers';
|
8
10
|
import { SelectField } from './SelectField';
|
9
11
|
import { ResourceSelectAPI } from './ResourceSelect';
|
@@ -22,12 +24,25 @@ const TemplateSearchField = ({
|
|
22
24
|
const searchQuery = useSelector(
|
23
25
|
state => state.autocomplete?.[name]?.searchQuery
|
24
26
|
);
|
27
|
+
const dispatch = useDispatch();
|
25
28
|
useEffect(() => {
|
26
29
|
setValue({ ...values, [name]: searchQuery });
|
27
30
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
28
31
|
}, [searchQuery]);
|
29
32
|
const id = name.replace(/ /g, '-');
|
30
33
|
const props = getControllerSearchProps(controller.replace('/', '_'), name);
|
34
|
+
|
35
|
+
const setSearch = newSearchQuery => {
|
36
|
+
dispatch(
|
37
|
+
getResults({
|
38
|
+
url,
|
39
|
+
searchQuery: newSearchQuery,
|
40
|
+
controller,
|
41
|
+
trigger: TRIGGERS.INPUT_CHANGE,
|
42
|
+
id: name,
|
43
|
+
})
|
44
|
+
);
|
45
|
+
};
|
31
46
|
return (
|
32
47
|
<FormGroup
|
33
48
|
label={name}
|
@@ -45,9 +60,9 @@ const TemplateSearchField = ({
|
|
45
60
|
url,
|
46
61
|
useKeyShortcuts: true,
|
47
62
|
},
|
48
|
-
bookmarks: null,
|
49
63
|
}}
|
50
64
|
onSearch={noop}
|
65
|
+
onBookmarkClick={search => setSearch(search)}
|
51
66
|
/>
|
52
67
|
</FormGroup>
|
53
68
|
);
|
@@ -152,7 +167,7 @@ export const formatter = (input, values, setValue) => {
|
|
152
167
|
key={id}
|
153
168
|
name={name}
|
154
169
|
defaultValue={value}
|
155
|
-
controller={
|
170
|
+
controller={controller}
|
156
171
|
url={`/${controller}/auto_complete_search`}
|
157
172
|
labelText={labelText}
|
158
173
|
required={required}
|
@@ -4,7 +4,7 @@ export const getApiUrl = (searchQuery, pagination) => {
|
|
4
4
|
const baseUrl = getURI()
|
5
5
|
.search('')
|
6
6
|
.addQuery('page', pagination.page)
|
7
|
-
.addQuery('per_page', pagination.
|
7
|
+
.addQuery('per_page', pagination.per_page);
|
8
8
|
|
9
9
|
return searchQuery ? baseUrl.addQuery('search', searchQuery) : baseUrl;
|
10
10
|
};
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { Grid } from 'patternfly-react';
|
4
4
|
|
5
5
|
import SearchBar from 'foremanReact/components/SearchBar';
|
6
|
-
import Pagination from 'foremanReact/components/Pagination
|
6
|
+
import Pagination from 'foremanReact/components/Pagination';
|
7
7
|
import { getControllerSearchProps } from 'foremanReact/constants';
|
8
8
|
|
9
9
|
import TargetingHosts from './TargetingHosts';
|
@@ -15,7 +15,6 @@ const TargetingHostsPage = ({
|
|
15
15
|
apiStatus,
|
16
16
|
items,
|
17
17
|
totalHosts,
|
18
|
-
pagination,
|
19
18
|
handlePagination,
|
20
19
|
}) => (
|
21
20
|
<div id="targeting_hosts">
|
@@ -39,11 +38,8 @@ const TargetingHostsPage = ({
|
|
39
38
|
<br />
|
40
39
|
<TargetingHosts apiStatus={apiStatus} items={items} />
|
41
40
|
<Pagination
|
42
|
-
viewType="table"
|
43
41
|
itemCount={totalHosts}
|
44
|
-
pagination={pagination}
|
45
42
|
onChange={args => handlePagination(args)}
|
46
|
-
dropdownButtonId="targeting-hosts-pagination-dropdown"
|
47
43
|
className="targeting-hosts-pagination"
|
48
44
|
/>
|
49
45
|
</div>
|
@@ -55,7 +51,6 @@ TargetingHostsPage.propTypes = {
|
|
55
51
|
apiStatus: PropTypes.string,
|
56
52
|
items: PropTypes.array.isRequired,
|
57
53
|
totalHosts: PropTypes.number.isRequired,
|
58
|
-
pagination: PropTypes.object.isRequired,
|
59
54
|
handlePagination: PropTypes.func.isRequired,
|
60
55
|
};
|
61
56
|
|
@@ -52,18 +52,10 @@ exports[`TargetingHostsPage renders 1`] = `
|
|
52
52
|
]
|
53
53
|
}
|
54
54
|
/>
|
55
|
-
<
|
55
|
+
<Pagination
|
56
56
|
className="targeting-hosts-pagination"
|
57
|
-
dropdownButtonId="targeting-hosts-pagination-dropdown"
|
58
57
|
itemCount={1}
|
59
58
|
onChange={[Function]}
|
60
|
-
pagination={
|
61
|
-
Object {
|
62
|
-
"page": 1,
|
63
|
-
"perPage": 20,
|
64
|
-
}
|
65
|
-
}
|
66
|
-
viewType="table"
|
67
59
|
/>
|
68
60
|
</div>
|
69
61
|
`;
|
@@ -30,14 +30,14 @@ const WrappedTargetingHosts = () => {
|
|
30
30
|
const [searchQuery, setSearchQuery] = useState('');
|
31
31
|
const [pagination, setPagination] = useState({
|
32
32
|
page: 1,
|
33
|
-
perPage,
|
33
|
+
per_page: perPage,
|
34
34
|
perPageOptions,
|
35
35
|
});
|
36
36
|
const [apiUrl, setApiUrl] = useState(getApiUrl(searchQuery, pagination));
|
37
37
|
const intervalExists = useSelector(selectIntervalExists);
|
38
38
|
|
39
39
|
const handleSearch = query => {
|
40
|
-
const defaultPagination = { page: 1,
|
40
|
+
const defaultPagination = { page: 1, per_page: pagination.per_page };
|
41
41
|
stopApiInterval();
|
42
42
|
|
43
43
|
setApiUrl(getApiUrl(query, defaultPagination));
|
@@ -88,7 +88,6 @@ const WrappedTargetingHosts = () => {
|
|
88
88
|
apiStatus={apiStatus}
|
89
89
|
items={items}
|
90
90
|
totalHosts={totalHosts}
|
91
|
-
pagination={pagination}
|
92
91
|
handlePagination={handlePagination}
|
93
92
|
/>
|
94
93
|
);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -263,7 +263,6 @@ files:
|
|
263
263
|
- app/views/template_invocations/_refresh.js.erb
|
264
264
|
- app/views/template_invocations/show.html.erb
|
265
265
|
- app/views/template_invocations/show.js.erb
|
266
|
-
- app/views/templates/README.md
|
267
266
|
- app/views/templates/ssh/check_update.erb
|
268
267
|
- app/views/templates/ssh/module_action.erb
|
269
268
|
- app/views/templates/ssh/package_action.erb
|
@@ -463,7 +462,7 @@ files:
|
|
463
462
|
- webpack/__mocks__/foremanReact/common/helpers.js
|
464
463
|
- webpack/__mocks__/foremanReact/components/AutoComplete/AutoCompleteActions.js
|
465
464
|
- webpack/__mocks__/foremanReact/components/AutoComplete/AutoCompleteConstants.js
|
466
|
-
- webpack/__mocks__/foremanReact/components/Pagination
|
465
|
+
- webpack/__mocks__/foremanReact/components/Pagination.js
|
467
466
|
- webpack/__mocks__/foremanReact/components/SearchBar.js
|
468
467
|
- webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js
|
469
468
|
- webpack/__mocks__/foremanReact/constants.js
|