foreman_remote_execution 11.1.3 → 12.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +0 -8
- data/.tx/config +2 -2
- data/app/assets/javascripts/foreman_remote_execution/locale/de/foreman_remote_execution.js +27 -21
- data/app/assets/javascripts/foreman_remote_execution/locale/en/foreman_remote_execution.js +24 -15
- data/app/assets/javascripts/foreman_remote_execution/locale/en_GB/foreman_remote_execution.js +27 -9
- data/app/assets/javascripts/foreman_remote_execution/locale/es/foreman_remote_execution.js +27 -24
- data/app/assets/javascripts/foreman_remote_execution/locale/fr/foreman_remote_execution.js +27 -24
- data/app/assets/javascripts/foreman_remote_execution/locale/ja/foreman_remote_execution.js +27 -24
- data/app/assets/javascripts/foreman_remote_execution/locale/ka/foreman_remote_execution.js +1587 -0
- data/app/assets/javascripts/foreman_remote_execution/locale/ko/foreman_remote_execution.js +27 -15
- data/app/assets/javascripts/foreman_remote_execution/locale/pt_BR/foreman_remote_execution.js +27 -24
- data/app/assets/javascripts/foreman_remote_execution/locale/ru/foreman_remote_execution.js +27 -15
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_CN/foreman_remote_execution.js +27 -24
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_TW/foreman_remote_execution.js +27 -15
- data/app/controllers/ui_job_wizard_controller.rb +1 -4
- data/app/helpers/remote_execution_helper.rb +10 -4
- data/app/lib/actions/remote_execution/event_helpers.rb +42 -0
- data/app/lib/actions/remote_execution/run_host_job.rb +3 -16
- data/app/lib/actions/remote_execution/run_hosts_job.rb +7 -5
- data/app/models/concerns/api/v2/hosts_controller_extensions.rb +12 -0
- data/app/models/job_invocation_composer.rb +0 -1
- data/app/views/api/v2/job_invocations/base.json.rabl +14 -0
- data/app/views/templates/script/convert2rhel_analyze.erb +0 -3
- data/config/routes.rb +2 -0
- data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +1 -1
- data/db/migrate/20151217092555_migrate_to_task_groups.rb +1 -1
- data/db/migrate/20160113162007_expand_all_template_invocations.rb +2 -2
- data/db/migrate/20160114125628_rename_job_name_to_job_category.rb +2 -2
- data/db/migrate/20200623073022_rename_sudo_password_to_effective_user_password.rb +2 -2
- data/db/migrate/20220321101835_rename_ssh_provider_to_script.rb +1 -1
- data/extra/cockpit/foreman-cockpit-session +1 -1
- data/foreman_remote_execution.gemspec +3 -1
- data/lib/foreman_remote_execution/engine.rb +14 -9
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/Makefile +3 -4
- data/locale/action_names.rb +0 -5
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +24 -15
- data/locale/en/foreman_remote_execution.po +24 -15
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +24 -15
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +24 -15
- data/locale/foreman_remote_execution.pot +82 -69
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +24 -15
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +24 -15
- data/locale/ka/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ka/foreman_remote_execution.po +1576 -0
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +24 -15
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +24 -15
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +24 -15
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +24 -15
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +24 -15
- data/test/unit/actions/run_hosts_job_test.rb +1 -1
- data/test/unit/api_params_test.rb +2 -10
- data/webpack/JobInvocationDetail/JobInvocationActions.js +22 -0
- data/webpack/JobInvocationDetail/JobInvocationConstants.js +7 -0
- data/webpack/JobInvocationDetail/JobInvocationOverview.js +104 -0
- data/webpack/JobInvocationDetail/JobInvocationSelectors.js +5 -0
- data/webpack/JobInvocationDetail/index.js +77 -0
- data/webpack/JobWizard/JobWizardPageRerun.js +10 -25
- data/webpack/JobWizard/index.js +9 -18
- data/webpack/Routes/routes.js +6 -0
- data/webpack/react_app/components/FeaturesDropdown/actions.js +4 -2
- data/webpack/react_app/components/FeaturesDropdown/constants.js +5 -0
- data/webpack/react_app/components/FeaturesDropdown/index.js +53 -14
- data/webpack/react_app/components/FeaturesDropdown/index.scss +11 -0
- data/webpack/react_app/extend/Fills.js +6 -0
- metadata +24 -10
- data/webpack/react_app/components/FeaturesDropdown/constant.js +0 -3
- /data/test/graphql/mutations/job_invocations/{create.rb → create_test.rb} +0 -0
- /data/test/unit/{renderer_scope_input.rb → renderer_scope_input_test.rb} +0 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import {
|
4
|
+
Button,
|
5
|
+
DescriptionList,
|
6
|
+
DescriptionListTerm,
|
7
|
+
DescriptionListGroup,
|
8
|
+
DescriptionListDescription,
|
9
|
+
} from '@patternfly/react-core';
|
10
|
+
import DefaultLoaderEmptyState from 'foremanReact/components/HostDetails/DetailsCard/DefaultLoaderEmptyState';
|
11
|
+
import { translate as __, documentLocale } from 'foremanReact/common/I18n';
|
12
|
+
|
13
|
+
const JobInvocationOverview = ({ data }) => {
|
14
|
+
const {
|
15
|
+
start_at: startAt,
|
16
|
+
ssh_user: sshUser,
|
17
|
+
template_id: templateId,
|
18
|
+
template_name: templateName,
|
19
|
+
effective_user: effectiveUser,
|
20
|
+
permissions,
|
21
|
+
} = data;
|
22
|
+
const canEditJobTemplates = permissions
|
23
|
+
? permissions.edit_job_templates
|
24
|
+
: false;
|
25
|
+
const dateOptions = {
|
26
|
+
day: 'numeric',
|
27
|
+
month: 'short',
|
28
|
+
year: 'numeric',
|
29
|
+
hour: '2-digit',
|
30
|
+
minute: '2-digit',
|
31
|
+
hour12: false,
|
32
|
+
timeZoneName: 'short',
|
33
|
+
};
|
34
|
+
let formattedStartDate = __('Not yet');
|
35
|
+
|
36
|
+
if (startAt) {
|
37
|
+
// Ensures date string compatibility across browsers
|
38
|
+
const convertedDate = new Date(startAt.replace(/[-.]/g, '/'));
|
39
|
+
if (convertedDate.getTime() <= new Date().getTime()) {
|
40
|
+
formattedStartDate = convertedDate.toLocaleString(
|
41
|
+
documentLocale(),
|
42
|
+
dateOptions
|
43
|
+
);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
return (
|
48
|
+
<DescriptionList
|
49
|
+
columnModifier={{
|
50
|
+
default: '2Col',
|
51
|
+
}}
|
52
|
+
isHorizontal
|
53
|
+
isCompact
|
54
|
+
isFluid
|
55
|
+
isAutoColumnWidths
|
56
|
+
>
|
57
|
+
<DescriptionListGroup>
|
58
|
+
<DescriptionListTerm>{__('Effective user:')}</DescriptionListTerm>
|
59
|
+
<DescriptionListDescription>
|
60
|
+
{effectiveUser || <DefaultLoaderEmptyState />}
|
61
|
+
</DescriptionListDescription>
|
62
|
+
</DescriptionListGroup>
|
63
|
+
<DescriptionListGroup>
|
64
|
+
<DescriptionListTerm>{__('Started at:')}</DescriptionListTerm>
|
65
|
+
<DescriptionListDescription>
|
66
|
+
{formattedStartDate}
|
67
|
+
</DescriptionListDescription>
|
68
|
+
</DescriptionListGroup>
|
69
|
+
<DescriptionListGroup>
|
70
|
+
<DescriptionListTerm>{__('SSH user:')}</DescriptionListTerm>
|
71
|
+
<DescriptionListDescription>
|
72
|
+
{sshUser || <DefaultLoaderEmptyState />}
|
73
|
+
</DescriptionListDescription>
|
74
|
+
</DescriptionListGroup>
|
75
|
+
<DescriptionListGroup>
|
76
|
+
<DescriptionListTerm>{__('Template:')}</DescriptionListTerm>
|
77
|
+
<DescriptionListDescription>
|
78
|
+
{templateName ? (
|
79
|
+
<Button
|
80
|
+
ouiaId="template-link"
|
81
|
+
variant="link"
|
82
|
+
component="a"
|
83
|
+
isInline
|
84
|
+
isDisabled={!canEditJobTemplates}
|
85
|
+
href={
|
86
|
+
templateId ? `/job_templates/${templateId}/edit` : undefined
|
87
|
+
}
|
88
|
+
>
|
89
|
+
{templateName}
|
90
|
+
</Button>
|
91
|
+
) : (
|
92
|
+
<DefaultLoaderEmptyState />
|
93
|
+
)}
|
94
|
+
</DescriptionListDescription>
|
95
|
+
</DescriptionListGroup>
|
96
|
+
</DescriptionList>
|
97
|
+
);
|
98
|
+
};
|
99
|
+
|
100
|
+
JobInvocationOverview.propTypes = {
|
101
|
+
data: PropTypes.object.isRequired,
|
102
|
+
};
|
103
|
+
|
104
|
+
export default JobInvocationOverview;
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import React, { useEffect } from 'react';
|
2
|
+
import { useSelector, useDispatch } from 'react-redux';
|
3
|
+
import PropTypes from 'prop-types';
|
4
|
+
import { Divider, PageSection, Flex, FlexItem } from '@patternfly/react-core';
|
5
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
6
|
+
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
7
|
+
import { stopInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
|
8
|
+
import { getData } from './JobInvocationActions';
|
9
|
+
import { selectItems } from './JobInvocationSelectors';
|
10
|
+
import JobInvocationOverview from './JobInvocationOverview';
|
11
|
+
import { JOB_INVOCATION_KEY, STATUS } from './JobInvocationConstants';
|
12
|
+
|
13
|
+
const JobInvocationDetailPage = ({
|
14
|
+
match: {
|
15
|
+
params: { id },
|
16
|
+
},
|
17
|
+
}) => {
|
18
|
+
const dispatch = useDispatch();
|
19
|
+
const items = useSelector(selectItems);
|
20
|
+
const { description, status_label: statusLabel, task } = items;
|
21
|
+
const finished =
|
22
|
+
statusLabel === STATUS.FAILED || statusLabel === STATUS.SUCCEEDED;
|
23
|
+
const autoRefresh = task?.state === STATUS.PENDING || false;
|
24
|
+
|
25
|
+
useEffect(() => {
|
26
|
+
dispatch(getData(`/api/job_invocations/${id}`));
|
27
|
+
if (finished && !autoRefresh) {
|
28
|
+
dispatch(stopInterval(JOB_INVOCATION_KEY));
|
29
|
+
}
|
30
|
+
return () => {
|
31
|
+
dispatch(stopInterval(JOB_INVOCATION_KEY));
|
32
|
+
};
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
34
|
+
}, [dispatch, id, finished, autoRefresh]);
|
35
|
+
|
36
|
+
const breadcrumbOptions = {
|
37
|
+
breadcrumbItems: [
|
38
|
+
{ caption: __('Jobs'), url: `/job_invocations` },
|
39
|
+
{ caption: description },
|
40
|
+
],
|
41
|
+
isPf4: true,
|
42
|
+
};
|
43
|
+
|
44
|
+
return (
|
45
|
+
<PageLayout
|
46
|
+
header={description}
|
47
|
+
breadcrumbOptions={breadcrumbOptions}
|
48
|
+
searchable={false}
|
49
|
+
>
|
50
|
+
<React.Fragment>
|
51
|
+
<PageSection isFilled variant="light">
|
52
|
+
<Flex>
|
53
|
+
<FlexItem> </FlexItem>
|
54
|
+
<Divider
|
55
|
+
orientation={{
|
56
|
+
default: 'vertical',
|
57
|
+
}}
|
58
|
+
/>
|
59
|
+
<FlexItem>
|
60
|
+
<JobInvocationOverview data={items} />
|
61
|
+
</FlexItem>
|
62
|
+
</Flex>
|
63
|
+
</PageSection>
|
64
|
+
</React.Fragment>
|
65
|
+
</PageLayout>
|
66
|
+
);
|
67
|
+
};
|
68
|
+
|
69
|
+
JobInvocationDetailPage.propTypes = {
|
70
|
+
match: PropTypes.shape({
|
71
|
+
params: PropTypes.shape({
|
72
|
+
id: PropTypes.string.isRequired,
|
73
|
+
}),
|
74
|
+
}).isRequired,
|
75
|
+
};
|
76
|
+
|
77
|
+
export default JobInvocationDetailPage;
|
@@ -1,15 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import URI from 'urijs';
|
4
|
-
import {
|
5
|
-
Alert,
|
6
|
-
Title,
|
7
|
-
Divider,
|
8
|
-
Skeleton,
|
9
|
-
Flex,
|
10
|
-
FlexItem,
|
11
|
-
Button,
|
12
|
-
} from '@patternfly/react-core';
|
4
|
+
import { Alert, Divider, Skeleton, Button } from '@patternfly/react-core';
|
13
5
|
import { sprintf, translate as __ } from 'foremanReact/common/I18n';
|
14
6
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
15
7
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
@@ -54,25 +46,18 @@ const JobWizardPageRerun = ({
|
|
54
46
|
header={title}
|
55
47
|
breadcrumbOptions={breadcrumbOptions}
|
56
48
|
searchable={false}
|
49
|
+
toolbarButtons={
|
50
|
+
<Button
|
51
|
+
variant="link"
|
52
|
+
component="a"
|
53
|
+
href={`/old/job_invocations/${id}/rerun${search}`}
|
54
|
+
>
|
55
|
+
{__('Use old form')}
|
56
|
+
</Button>
|
57
|
+
}
|
57
58
|
>
|
58
59
|
<React.Fragment>
|
59
60
|
<React.Fragment>
|
60
|
-
<Flex>
|
61
|
-
<FlexItem>
|
62
|
-
<Title headingLevel="h2" size="2xl">
|
63
|
-
{title}
|
64
|
-
</Title>
|
65
|
-
</FlexItem>
|
66
|
-
<FlexItem align={{ default: 'alignRight' }}>
|
67
|
-
<Button
|
68
|
-
variant="link"
|
69
|
-
component="a"
|
70
|
-
href={`/old/job_invocations/${id}/rerun${search}`}
|
71
|
-
>
|
72
|
-
{__('Use old form')}
|
73
|
-
</Button>
|
74
|
-
</FlexItem>
|
75
|
-
</Flex>
|
76
61
|
<Divider component="div" />
|
77
62
|
</React.Fragment>
|
78
63
|
{!status || status === STATUS.PENDING ? (
|
data/webpack/JobWizard/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
-
import {
|
3
|
+
import { Button } from '@patternfly/react-core';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
5
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
6
6
|
import { JobWizard } from './JobWizard';
|
@@ -18,23 +18,14 @@ const JobWizardPage = ({ location: { search } }) => {
|
|
18
18
|
header={title}
|
19
19
|
breadcrumbOptions={breadcrumbOptions}
|
20
20
|
searchable={false}
|
21
|
-
|
22
|
-
<
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
<Button
|
30
|
-
variant="link"
|
31
|
-
component="a"
|
32
|
-
href={`/old/job_invocations/new${search}`}
|
33
|
-
>
|
34
|
-
{__('Use legacy form')}
|
35
|
-
</Button>
|
36
|
-
</FlexItem>
|
37
|
-
</Flex>
|
21
|
+
toolbarButtons={
|
22
|
+
<Button
|
23
|
+
variant="link"
|
24
|
+
component="a"
|
25
|
+
href={`/old/job_invocations/new${search}`}
|
26
|
+
>
|
27
|
+
{__('Use legacy form')}
|
28
|
+
</Button>
|
38
29
|
}
|
39
30
|
pageSectionType="wizard"
|
40
31
|
>
|
data/webpack/Routes/routes.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import JobWizardPage from '../JobWizard';
|
3
3
|
import JobWizardPageRerun from '../JobWizard/JobWizardPageRerun';
|
4
|
+
import JobInvocationDetailPage from '../JobInvocationDetail';
|
4
5
|
|
5
6
|
const ForemanREXRoutes = [
|
6
7
|
{
|
@@ -13,6 +14,11 @@ const ForemanREXRoutes = [
|
|
13
14
|
exact: true,
|
14
15
|
render: props => <JobWizardPageRerun {...props} />,
|
15
16
|
},
|
17
|
+
{
|
18
|
+
path: '/experimental/job_invocations_detail/:id',
|
19
|
+
exact: true,
|
20
|
+
render: props => <JobInvocationDetailPage {...props} />,
|
21
|
+
},
|
16
22
|
];
|
17
23
|
|
18
24
|
export default ForemanREXRoutes;
|
@@ -2,9 +2,11 @@ import { foremanUrl } from 'foremanReact/common/helpers';
|
|
2
2
|
import { sprintf, translate as __ } from 'foremanReact/common/I18n';
|
3
3
|
import { post } from 'foremanReact/redux/API';
|
4
4
|
|
5
|
-
export const runFeature = (hostId, feature, label) => dispatch => {
|
5
|
+
export const runFeature = (hostId, feature, label, hostSearch) => dispatch => {
|
6
6
|
const url = foremanUrl(
|
7
|
-
|
7
|
+
hostId
|
8
|
+
? `/job_invocations?feature=${feature}&host_ids%5B%5D=${hostId}`
|
9
|
+
: `/job_invocations?feature=${feature}&search=${hostSearch}`
|
8
10
|
);
|
9
11
|
const redirectUrl = 'job_invocations/new';
|
10
12
|
|
@@ -0,0 +1,5 @@
|
|
1
|
+
export const REX_FEATURES_HOST_URL = host =>
|
2
|
+
`/api/v2/hosts/${host}/available_remote_execution_features`;
|
3
|
+
export const ALL_REX_FEATURES_URL = '/api/v2/remote_execution_features';
|
4
|
+
export const NEW_JOB_PAGE = '/job_invocations/new?host_ids%5B%5D';
|
5
|
+
export const ALL_HOSTS_NEW_JOB_PAGE = '/job_invocations/new?search';
|
@@ -11,58 +11,83 @@ import { push } from 'connected-react-router';
|
|
11
11
|
|
12
12
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
13
13
|
import { translate as __ } from 'foremanReact/common/I18n';
|
14
|
-
import { foremanUrl } from 'foremanReact/common/helpers';
|
14
|
+
import { foremanUrl, propsToCamelCase } from 'foremanReact/common/helpers';
|
15
15
|
import { STATUS } from 'foremanReact/constants';
|
16
16
|
|
17
|
-
import {
|
17
|
+
import {
|
18
|
+
REX_FEATURES_HOST_URL,
|
19
|
+
ALL_REX_FEATURES_URL,
|
20
|
+
NEW_JOB_PAGE,
|
21
|
+
ALL_HOSTS_NEW_JOB_PAGE,
|
22
|
+
} from './constants';
|
18
23
|
import { runFeature } from './actions';
|
24
|
+
import './index.scss';
|
19
25
|
|
20
|
-
const FeaturesDropdown = ({
|
26
|
+
const FeaturesDropdown = ({
|
27
|
+
hostId,
|
28
|
+
hostSearch,
|
29
|
+
hostResponse,
|
30
|
+
selectedCount,
|
31
|
+
}) => {
|
21
32
|
const [isOpen, setIsOpen] = useState(false);
|
22
|
-
const
|
23
|
-
|
24
|
-
|
25
|
-
|
33
|
+
const isSingleHost = !!hostId; // identifies whether we're on the host details or host overview page
|
34
|
+
const rexFeaturesUrl = isSingleHost
|
35
|
+
? REX_FEATURES_HOST_URL(hostId)
|
36
|
+
: ALL_REX_FEATURES_URL;
|
37
|
+
const { response, status } = useAPI('get', foremanUrl(rexFeaturesUrl));
|
26
38
|
const dispatch = useDispatch();
|
27
|
-
|
28
|
-
|
39
|
+
const permissions = propsToCamelCase(
|
40
|
+
(isSingleHost ? response?.permissions : hostResponse?.response) || {}
|
41
|
+
);
|
42
|
+
const canRunJob = isSingleHost
|
43
|
+
? permissions.canRunJob
|
44
|
+
: permissions.canCreateJobInvocations;
|
29
45
|
if (!canRunJob) {
|
30
46
|
return null;
|
31
47
|
}
|
32
|
-
|
33
|
-
const features =
|
48
|
+
|
49
|
+
const features = isSingleHost
|
50
|
+
? response?.remote_execution_features // eslint-disable-line camelcase
|
51
|
+
: response?.results;
|
34
52
|
const dropdownItems = features
|
35
53
|
?.filter(feature => feature.host_action_button)
|
36
54
|
?.map(({ name, label, id, description }) => (
|
37
55
|
<DropdownItem
|
38
|
-
onClick={() => dispatch(runFeature(hostId, label, name))}
|
56
|
+
onClick={() => dispatch(runFeature(hostId, label, name, hostSearch))}
|
39
57
|
key={id}
|
40
58
|
description={description}
|
41
59
|
>
|
42
60
|
{name}
|
43
61
|
</DropdownItem>
|
44
62
|
));
|
63
|
+
const newJobPageUrl = hostId
|
64
|
+
? `${NEW_JOB_PAGE}=${hostId}`
|
65
|
+
: `${ALL_HOSTS_NEW_JOB_PAGE}=${hostSearch}`;
|
45
66
|
const scheduleJob = [
|
46
67
|
<DropdownToggleAction
|
47
|
-
onClick={() => dispatch(push(
|
68
|
+
onClick={() => dispatch(push(newJobPageUrl))}
|
48
69
|
key="schedule-job-action"
|
49
70
|
>
|
50
71
|
{__('Schedule a job')}
|
51
72
|
</DropdownToggleAction>,
|
52
73
|
];
|
53
74
|
|
75
|
+
const disableDropdown = !isSingleHost && selectedCount === 0;
|
76
|
+
|
54
77
|
return (
|
55
78
|
<Dropdown
|
56
79
|
ouiaId="schedule-a-job-dropdown"
|
80
|
+
id="schedule-a-job-dropdown"
|
57
81
|
alignments={{ default: 'right' }}
|
58
82
|
onSelect={() => setIsOpen(false)}
|
59
83
|
toggle={
|
60
84
|
<DropdownToggle
|
61
85
|
ouiaId="schedule-a-job-dropdown-toggle"
|
86
|
+
id="schedule-a-job-dropdown-toggle"
|
62
87
|
splitButtonItems={scheduleJob}
|
63
88
|
toggleVariant="secondary"
|
64
89
|
onToggle={() => setIsOpen(prev => !prev)}
|
65
|
-
isDisabled={status === STATUS.PENDING}
|
90
|
+
isDisabled={status === STATUS.PENDING || disableDropdown}
|
66
91
|
splitButtonVariant="action"
|
67
92
|
/>
|
68
93
|
}
|
@@ -74,9 +99,23 @@ const FeaturesDropdown = ({ hostId }) => {
|
|
74
99
|
|
75
100
|
FeaturesDropdown.propTypes = {
|
76
101
|
hostId: PropTypes.number,
|
102
|
+
hostSearch: PropTypes.string,
|
103
|
+
selectedCount: PropTypes.number,
|
104
|
+
hostResponse: PropTypes.shape({
|
105
|
+
response: PropTypes.shape({
|
106
|
+
results: PropTypes.arrayOf(
|
107
|
+
PropTypes.shape({
|
108
|
+
can_create_job_invocations: PropTypes.bool,
|
109
|
+
})
|
110
|
+
),
|
111
|
+
}),
|
112
|
+
}),
|
77
113
|
};
|
78
114
|
FeaturesDropdown.defaultProps = {
|
79
115
|
hostId: undefined,
|
116
|
+
hostSearch: undefined,
|
117
|
+
selectedCount: 0,
|
118
|
+
hostResponse: undefined,
|
80
119
|
};
|
81
120
|
|
82
121
|
export default FeaturesDropdown;
|
@@ -38,6 +38,12 @@ const fills = [
|
|
38
38
|
component: props => <FeaturesDropdown {...props} />,
|
39
39
|
weight: 1000,
|
40
40
|
},
|
41
|
+
{
|
42
|
+
slot: '_all-hosts-schedule-a-job',
|
43
|
+
name: '_all-hosts-schedule-a-job',
|
44
|
+
component: props => <FeaturesDropdown {...props} />,
|
45
|
+
weight: 1000,
|
46
|
+
},
|
41
47
|
];
|
42
48
|
|
43
49
|
const registerFills = () => {
|
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: 12.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: 2023-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 8.
|
53
|
+
version: 8.3.0
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 8.
|
60
|
+
version: 8.3.0
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: factory_bot_rails
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- app/assets/javascripts/foreman_remote_execution/locale/es/foreman_remote_execution.js
|
121
121
|
- app/assets/javascripts/foreman_remote_execution/locale/fr/foreman_remote_execution.js
|
122
122
|
- app/assets/javascripts/foreman_remote_execution/locale/ja/foreman_remote_execution.js
|
123
|
+
- app/assets/javascripts/foreman_remote_execution/locale/ka/foreman_remote_execution.js
|
123
124
|
- app/assets/javascripts/foreman_remote_execution/locale/ko/foreman_remote_execution.js
|
124
125
|
- app/assets/javascripts/foreman_remote_execution/locale/pt_BR/foreman_remote_execution.js
|
125
126
|
- app/assets/javascripts/foreman_remote_execution/locale/ru/foreman_remote_execution.js
|
@@ -162,6 +163,7 @@ files:
|
|
162
163
|
- app/helpers/job_invocations_helper.rb
|
163
164
|
- app/helpers/remote_execution_helper.rb
|
164
165
|
- app/lib/actions/middleware/bind_job_invocation.rb
|
166
|
+
- app/lib/actions/remote_execution/event_helpers.rb
|
165
167
|
- app/lib/actions/remote_execution/proxy_action.rb
|
166
168
|
- app/lib/actions/remote_execution/run_host_job.rb
|
167
169
|
- app/lib/actions/remote_execution/run_hosts_job.rb
|
@@ -171,6 +173,7 @@ files:
|
|
171
173
|
- app/lib/proxy_api/remote_execution_ssh.rb
|
172
174
|
- app/mailers/.gitkeep
|
173
175
|
- app/mailers/rex_job_mailer.rb
|
176
|
+
- app/models/concerns/api/v2/hosts_controller_extensions.rb
|
174
177
|
- app/models/concerns/api/v2/interfaces_controller_extensions.rb
|
175
178
|
- app/models/concerns/foreman_remote_execution/bookmark_extensions.rb
|
176
179
|
- app/models/concerns/foreman_remote_execution/errors_flattener.rb
|
@@ -381,6 +384,8 @@ files:
|
|
381
384
|
- locale/gemspec.rb
|
382
385
|
- locale/ja/LC_MESSAGES/foreman_remote_execution.mo
|
383
386
|
- locale/ja/foreman_remote_execution.po
|
387
|
+
- locale/ka/LC_MESSAGES/foreman_remote_execution.mo
|
388
|
+
- locale/ka/foreman_remote_execution.po
|
384
389
|
- locale/ko/LC_MESSAGES/foreman_remote_execution.mo
|
385
390
|
- locale/ko/foreman_remote_execution.po
|
386
391
|
- locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo
|
@@ -405,7 +410,7 @@ files:
|
|
405
410
|
- test/functional/job_invocations_controller_test.rb
|
406
411
|
- test/functional/job_templates_controller_test.rb
|
407
412
|
- test/functional/ui_job_wizard_controller_test.rb
|
408
|
-
- test/graphql/mutations/job_invocations/
|
413
|
+
- test/graphql/mutations/job_invocations/create_test.rb
|
409
414
|
- test/graphql/queries/job_invocation_query_test.rb
|
410
415
|
- test/graphql/queries/job_invocations_query_test.rb
|
411
416
|
- test/helpers/remote_execution_helper_test.rb
|
@@ -426,9 +431,14 @@ files:
|
|
426
431
|
- test/unit/job_template_test.rb
|
427
432
|
- test/unit/remote_execution_feature_test.rb
|
428
433
|
- test/unit/remote_execution_provider_test.rb
|
429
|
-
- test/unit/
|
434
|
+
- test/unit/renderer_scope_input_test.rb
|
430
435
|
- test/unit/targeting_test.rb
|
431
436
|
- test/unit/template_invocation_input_value_test.rb
|
437
|
+
- webpack/JobInvocationDetail/JobInvocationActions.js
|
438
|
+
- webpack/JobInvocationDetail/JobInvocationConstants.js
|
439
|
+
- webpack/JobInvocationDetail/JobInvocationOverview.js
|
440
|
+
- webpack/JobInvocationDetail/JobInvocationSelectors.js
|
441
|
+
- webpack/JobInvocationDetail/index.js
|
432
442
|
- webpack/JobWizard/Footer.js
|
433
443
|
- webpack/JobWizard/JobWizard.js
|
434
444
|
- webpack/JobWizard/JobWizard.scss
|
@@ -513,8 +523,9 @@ files:
|
|
513
523
|
- webpack/helpers.js
|
514
524
|
- webpack/index.js
|
515
525
|
- webpack/react_app/components/FeaturesDropdown/actions.js
|
516
|
-
- webpack/react_app/components/FeaturesDropdown/
|
526
|
+
- webpack/react_app/components/FeaturesDropdown/constants.js
|
517
527
|
- webpack/react_app/components/FeaturesDropdown/index.js
|
528
|
+
- webpack/react_app/components/FeaturesDropdown/index.scss
|
518
529
|
- webpack/react_app/components/HostKebab/KebabItems.js
|
519
530
|
- webpack/react_app/components/RecentJobsCard/JobStatusIcon.js
|
520
531
|
- webpack/react_app/components/RecentJobsCard/RecentJobsCard.js
|
@@ -572,7 +583,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
572
583
|
requirements:
|
573
584
|
- - ">="
|
574
585
|
- !ruby/object:Gem::Version
|
575
|
-
version: '
|
586
|
+
version: '2.7'
|
587
|
+
- - "<"
|
588
|
+
- !ruby/object:Gem::Version
|
589
|
+
version: '4'
|
576
590
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
577
591
|
requirements:
|
578
592
|
- - ">="
|
@@ -598,7 +612,7 @@ test_files:
|
|
598
612
|
- test/functional/job_invocations_controller_test.rb
|
599
613
|
- test/functional/job_templates_controller_test.rb
|
600
614
|
- test/functional/ui_job_wizard_controller_test.rb
|
601
|
-
- test/graphql/mutations/job_invocations/
|
615
|
+
- test/graphql/mutations/job_invocations/create_test.rb
|
602
616
|
- test/graphql/queries/job_invocation_query_test.rb
|
603
617
|
- test/graphql/queries/job_invocations_query_test.rb
|
604
618
|
- test/helpers/remote_execution_helper_test.rb
|
@@ -619,6 +633,6 @@ test_files:
|
|
619
633
|
- test/unit/job_template_test.rb
|
620
634
|
- test/unit/remote_execution_feature_test.rb
|
621
635
|
- test/unit/remote_execution_provider_test.rb
|
622
|
-
- test/unit/
|
636
|
+
- test/unit/renderer_scope_input_test.rb
|
623
637
|
- test/unit/targeting_test.rb
|
624
638
|
- test/unit/template_invocation_input_value_test.rb
|
File without changes
|
File without changes
|