foreman_remote_execution 15.0.2 → 16.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/app/controllers/api/v2/job_templates_controller.rb +3 -0
- data/app/views/api/v2/job_invocations/main.json.rabl +1 -1
- data/lib/foreman_remote_execution/engine.rb +1 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/foreman_remote_execution.pot +138 -135
- data/package.json +8 -7
- data/webpack/JobInvocationDetail/JobAdditionInfo.js +4 -4
- data/webpack/JobInvocationDetail/JobInvocationDetail.scss +5 -5
- data/webpack/JobInvocationDetail/JobInvocationHostTable.js +7 -4
- data/webpack/JobInvocationDetail/JobInvocationHostTableToolbar.js +8 -3
- data/webpack/JobInvocationDetail/JobInvocationToolbarButtons.js +3 -5
- data/webpack/JobInvocationDetail/TemplateInvocationComponents/OutputToggleGroup.js +1 -1
- data/webpack/JobInvocationDetail/TemplateInvocationComponents/PreviewTemplate.js +3 -10
- data/webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js +5 -5
- data/webpack/JobInvocationDetail/TemplateInvocationComponents/index.scss +1 -1
- data/webpack/JobInvocationDetail/__tests__/MainInformation.test.js +6 -6
- data/webpack/JobInvocationDetail/__tests__/TemplateInvocation.test.js +1 -1
- data/webpack/JobInvocationDetail/__tests__/fixtures.js +1 -0
- data/webpack/JobInvocationDetail/index.js +14 -13
- data/webpack/JobWizard/Footer.js +2 -4
- data/webpack/JobWizard/JobWizard.js +1 -1
- data/webpack/JobWizard/JobWizard.scss +19 -19
- data/webpack/JobWizard/JobWizardPageRerun.js +22 -16
- data/webpack/JobWizard/PermissionDenied.js +15 -11
- data/webpack/JobWizard/__tests__/integration.test.js +10 -8
- data/webpack/JobWizard/steps/AdvancedFields/DescriptionField.js +26 -14
- data/webpack/JobWizard/steps/AdvancedFields/Fields.js +5 -5
- data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +14 -12
- data/webpack/JobWizard/steps/HostsAndInputs/SelectAPI.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/SelectGQL.js +1 -1
- data/webpack/JobWizard/steps/HostsAndInputs/__tests__/HostsAndInputs.test.js +5 -5
- data/webpack/JobWizard/steps/HostsAndInputs/index.js +41 -36
- data/webpack/JobWizard/steps/ReviewDetails/ReviewDetails.test.js +3 -3
- data/webpack/JobWizard/steps/ReviewDetails/index.js +1 -1
- data/webpack/JobWizard/steps/Schedule/PurposeField.js +1 -1
- data/webpack/JobWizard/steps/Schedule/RepeatCron.js +1 -1
- data/webpack/JobWizard/steps/Schedule/RepeatDaily.js +1 -1
- data/webpack/JobWizard/steps/Schedule/RepeatHour.js +6 -4
- data/webpack/JobWizard/steps/Schedule/RepeatMonth.js +1 -1
- data/webpack/JobWizard/steps/Schedule/RepeatWeek.js +1 -1
- data/webpack/JobWizard/steps/Schedule/ScheduleFuture.js +10 -3
- data/webpack/JobWizard/steps/Schedule/ScheduleRecurring.js +29 -19
- data/webpack/JobWizard/steps/form/DateTimePicker.js +1 -1
- data/webpack/JobWizard/steps/form/FormHelpers.js +7 -4
- data/webpack/JobWizard/steps/form/Formatter.js +3 -1
- data/webpack/JobWizard/steps/form/GroupedSelectField.js +3 -3
- data/webpack/JobWizard/steps/form/NumberInput.js +17 -7
- data/webpack/JobWizard/steps/form/ResourceSelect.js +8 -4
- data/webpack/JobWizard/steps/form/SearchSelect.js +6 -2
- data/webpack/JobWizard/steps/form/SelectField.js +3 -2
- data/webpack/react_app/components/FeaturesDropdown/index.js +1 -1
- data/webpack/react_app/components/FeaturesDropdown/index.scss +2 -2
- data/webpack/react_app/components/HostKebab/KebabItems.js +1 -1
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +2 -1
- data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +3 -3
- data/webpack/react_app/components/RecentJobsCard/styles.scss +3 -3
- data/webpack/react_app/components/RegistrationExtension/RexInterface.js +5 -3
- data/webpack/react_app/components/RegistrationExtension/RexPull.js +1 -1
- data/webpack/react_app/components/RegistrationExtension/__tests__/__snapshots__/RexInterface.test.js.snap +6 -6
- metadata +2 -2
@@ -59,26 +59,28 @@ describe('Job wizard fill', () => {
|
|
59
59
|
<JobWizard />
|
60
60
|
</Provider>
|
61
61
|
);
|
62
|
-
expect(
|
63
|
-
|
64
|
-
);
|
62
|
+
expect(
|
63
|
+
wrapper.find('.pf-v5-c-wizard__nav-link.pf-m-disabled')
|
64
|
+
).toHaveLength(5);
|
65
65
|
selectors.selectJobCategoriesStatus.mockImplementation(() => 'RESOLVED');
|
66
66
|
expect(store.getActions()).toMatchSnapshot('initial');
|
67
67
|
selectors.selectJobTemplate.mockRestore();
|
68
68
|
jest.spyOn(selectors, 'selectJobTemplate');
|
69
69
|
selectors.selectJobTemplate.mockImplementation(() => jobTemplate);
|
70
|
-
wrapper
|
70
|
+
wrapper
|
71
|
+
.find('.pf-v5-c-button.pf-v5-c-select__toggle-button')
|
72
|
+
.simulate('click');
|
71
73
|
await act(async () => {
|
72
74
|
await wrapper
|
73
|
-
.find('.pf-c-select__menu-item')
|
75
|
+
.find('.pf-v5-c-select__menu-item')
|
74
76
|
.first()
|
75
77
|
.simulate('click');
|
76
78
|
});
|
77
79
|
expect(store.getActions().slice(-1)).toMatchSnapshot('select template');
|
78
80
|
wrapper.update();
|
79
|
-
expect(
|
80
|
-
|
81
|
-
);
|
81
|
+
expect(
|
82
|
+
wrapper.find('.pf-v5-c-wizard__nav-link.pf-m-disabled')
|
83
|
+
).toHaveLength(0);
|
82
84
|
});
|
83
85
|
|
84
86
|
it('have all steps', async () => {
|
@@ -1,7 +1,15 @@
|
|
1
1
|
import React, { useState, useEffect, useCallback } from 'react';
|
2
2
|
import { useSelector } from 'react-redux';
|
3
3
|
import PropTypes from 'prop-types';
|
4
|
-
import {
|
4
|
+
import {
|
5
|
+
FormGroup,
|
6
|
+
TextInput,
|
7
|
+
Tooltip,
|
8
|
+
Button,
|
9
|
+
FormHelperText,
|
10
|
+
HelperText,
|
11
|
+
HelperTextItem,
|
12
|
+
} from '@patternfly/react-core';
|
5
13
|
import { translate as __ } from 'foremanReact/common/I18n';
|
6
14
|
import {
|
7
15
|
selectTemplateInputs,
|
@@ -55,18 +63,6 @@ export const DescriptionField = ({
|
|
55
63
|
<ResetDefault setValue={setValue} defaultValue={defaultValue} />
|
56
64
|
}
|
57
65
|
fieldId="description"
|
58
|
-
helperText={
|
59
|
-
<Button
|
60
|
-
ouiaId="description-preview-button"
|
61
|
-
variant="link"
|
62
|
-
isInline
|
63
|
-
onClick={togglePreview}
|
64
|
-
>
|
65
|
-
{isPreview
|
66
|
-
? __('Edit job description template')
|
67
|
-
: __('Preview job description')}
|
68
|
-
</Button>
|
69
|
-
}
|
70
66
|
>
|
71
67
|
{isPreview ? (
|
72
68
|
<Tooltip content={generatedDesc}>
|
@@ -89,9 +85,25 @@ export const DescriptionField = ({
|
|
89
85
|
autoComplete="description"
|
90
86
|
id="description"
|
91
87
|
value={value}
|
92
|
-
onChange={newValue => setValue(newValue)}
|
88
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
93
89
|
/>
|
94
90
|
)}
|
91
|
+
<FormHelperText>
|
92
|
+
<HelperText>
|
93
|
+
<HelperTextItem>
|
94
|
+
<Button
|
95
|
+
ouiaId="description-preview-button"
|
96
|
+
variant="link"
|
97
|
+
isInline
|
98
|
+
onClick={togglePreview}
|
99
|
+
>
|
100
|
+
{isPreview
|
101
|
+
? __('Edit job description template')
|
102
|
+
: __('Preview job description')}
|
103
|
+
</Button>
|
104
|
+
</HelperTextItem>
|
105
|
+
</HelperText>
|
106
|
+
</FormHelperText>
|
95
107
|
</FormGroup>
|
96
108
|
);
|
97
109
|
};
|
@@ -25,7 +25,7 @@ export const EffectiveUserField = ({ value, setValue, defaultValue }) => (
|
|
25
25
|
id="effective-user"
|
26
26
|
type="text"
|
27
27
|
value={value}
|
28
|
-
onChange={newValue => setValue(newValue)}
|
28
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
29
29
|
/>
|
30
30
|
</FormGroup>
|
31
31
|
);
|
@@ -94,7 +94,7 @@ export const PasswordField = ({ value, setValue }) => (
|
|
94
94
|
type="password"
|
95
95
|
placeholder="*****"
|
96
96
|
value={value}
|
97
|
-
onChange={newValue => setValue(newValue)}
|
97
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
98
98
|
/>
|
99
99
|
</FormGroup>
|
100
100
|
);
|
@@ -118,7 +118,7 @@ export const KeyPassphraseField = ({ value, setValue }) => (
|
|
118
118
|
type="password"
|
119
119
|
placeholder="*****"
|
120
120
|
value={value}
|
121
|
-
onChange={newValue => setValue(newValue)}
|
121
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
122
122
|
/>
|
123
123
|
</FormGroup>
|
124
124
|
);
|
@@ -142,7 +142,7 @@ export const EffectiveUserPasswordField = ({ value, setValue }) => (
|
|
142
142
|
type="password"
|
143
143
|
placeholder="*****"
|
144
144
|
value={value}
|
145
|
-
onChange={newValue => setValue(newValue)}
|
145
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
146
146
|
/>
|
147
147
|
</FormGroup>
|
148
148
|
);
|
@@ -228,7 +228,7 @@ export const SSHUserField = ({ value, setValue, defaultValue }) => (
|
|
228
228
|
id="ssh-user"
|
229
229
|
type="text"
|
230
230
|
value={value}
|
231
|
-
onChange={newValue => setValue(newValue)}
|
231
|
+
onChange={(_event, newValue) => setValue(newValue)}
|
232
232
|
/>
|
233
233
|
</FormGroup>
|
234
234
|
);
|
@@ -44,18 +44,20 @@ describe('AdvancedFields', () => {
|
|
44
44
|
</MockedProvider>
|
45
45
|
);
|
46
46
|
// setup
|
47
|
-
wrapper.find('.pf-c-button.pf-c-select__toggle-button').simulate('click');
|
48
47
|
wrapper
|
49
|
-
.find('.pf-c-
|
48
|
+
.find('.pf-v5-c-button.pf-v5-c-select__toggle-button')
|
49
|
+
.simulate('click');
|
50
|
+
wrapper
|
51
|
+
.find('.pf-v5-c-select__menu-item')
|
50
52
|
.first()
|
51
53
|
.simulate('click');
|
52
54
|
|
53
55
|
// test
|
54
|
-
expect(
|
55
|
-
|
56
|
-
);
|
56
|
+
expect(
|
57
|
+
wrapper.find('.pf-v5-c-wizard__nav-link.pf-m-disabled')
|
58
|
+
).toHaveLength(0);
|
57
59
|
wrapper
|
58
|
-
.find('.pf-c-wizard__nav-link')
|
60
|
+
.find('.pf-v5-c-wizard__nav-link')
|
59
61
|
.at(2)
|
60
62
|
.simulate('click'); // Advanced step
|
61
63
|
|
@@ -64,7 +66,7 @@ describe('AdvancedFields', () => {
|
|
64
66
|
});
|
65
67
|
const effectiveUserInput = () => wrapper.find('input#effective-user');
|
66
68
|
const advancedTemplateInput = () =>
|
67
|
-
wrapper.find('.pf-c-form__group-control textarea');
|
69
|
+
wrapper.find('.pf-v5-c-form__group-control textarea');
|
68
70
|
const effectiveUesrValue = 'effective user new value';
|
69
71
|
const advancedTemplateInputValue = 'advanced input new value';
|
70
72
|
effectiveUserInput().getDOMNode().value = effectiveUesrValue;
|
@@ -79,15 +81,15 @@ describe('AdvancedFields', () => {
|
|
79
81
|
);
|
80
82
|
|
81
83
|
wrapper
|
82
|
-
.find('.pf-c-wizard__nav-link')
|
84
|
+
.find('.pf-v5-c-wizard__nav-link')
|
83
85
|
.at(1)
|
84
86
|
.simulate('click');
|
85
87
|
|
86
|
-
expect(
|
87
|
-
'
|
88
|
-
);
|
88
|
+
expect(
|
89
|
+
wrapper.find('.pf-v5-c-wizard__nav-link.pf-m-current').text()
|
90
|
+
).toEqual('Target hosts and inputs');
|
89
91
|
wrapper
|
90
|
-
.find('.pf-c-wizard__nav-link')
|
92
|
+
.find('.pf-v5-c-wizard__nav-link')
|
91
93
|
.at(2)
|
92
94
|
.simulate('click'); // Advanced step
|
93
95
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { useSelector, useDispatch } from 'react-redux';
|
3
3
|
import URI from 'urijs';
|
4
|
-
import { SelectVariant } from '@patternfly/react-core';
|
4
|
+
import { SelectVariant } from '@patternfly/react-core/deprecated';
|
5
5
|
import { get } from 'foremanReact/redux/API';
|
6
6
|
import { selectResponse, selectIsLoading } from '../../JobWizardSelectors';
|
7
7
|
import { SearchSelect } from '../form/SearchSelect';
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React, { useState } from 'react';
|
2
2
|
import { useQuery } from '@apollo/client';
|
3
|
-
import { SelectVariant } from '@patternfly/react-core';
|
3
|
+
import { SelectVariant } from '@patternfly/react-core/deprecated';
|
4
4
|
import {
|
5
5
|
useForemanOrganization,
|
6
6
|
useForemanLocation,
|
@@ -43,7 +43,7 @@ describe('Hosts', () => {
|
|
43
43
|
await act(async () => {
|
44
44
|
fireEvent.click(
|
45
45
|
screen.getByText('host1', {
|
46
|
-
selector: '.pf-c-select__menu-item',
|
46
|
+
selector: '.pf-v5-c-select__menu-item',
|
47
47
|
})
|
48
48
|
);
|
49
49
|
fireEvent.blur(select('hosts'));
|
@@ -56,7 +56,7 @@ describe('Hosts', () => {
|
|
56
56
|
fireEvent.click(screen.getByText('host2'));
|
57
57
|
});
|
58
58
|
fireEvent.click(
|
59
|
-
screen.getByText('Hosts', { selector: '.pf-c-select__toggle-text' })
|
59
|
+
screen.getByText('Hosts', { selector: '.pf-v5-c-select__toggle-text' })
|
60
60
|
);
|
61
61
|
await act(async () => {
|
62
62
|
fireEvent.click(screen.getByText('Host groups'));
|
@@ -71,7 +71,7 @@ describe('Hosts', () => {
|
|
71
71
|
await act(async () => {
|
72
72
|
fireEvent.click(
|
73
73
|
screen.getByText('Host groups', {
|
74
|
-
selector: '.pf-c-select__toggle-text',
|
74
|
+
selector: '.pf-v5-c-select__toggle-text',
|
75
75
|
})
|
76
76
|
);
|
77
77
|
});
|
@@ -128,7 +128,7 @@ describe('Hosts', () => {
|
|
128
128
|
expect(screen.queryAllByText('Hosts')).toHaveLength(1);
|
129
129
|
await act(async () => {
|
130
130
|
fireEvent.click(
|
131
|
-
screen.getByText('Hosts', { selector: '.pf-c-select__toggle-text' })
|
131
|
+
screen.getByText('Hosts', { selector: '.pf-v5-c-select__toggle-text' })
|
132
132
|
);
|
133
133
|
});
|
134
134
|
expect(screen.queryAllByText('Host groups')).toHaveLength(1);
|
@@ -138,7 +138,7 @@ describe('Hosts', () => {
|
|
138
138
|
await act(async () => {
|
139
139
|
fireEvent.click(
|
140
140
|
// Close the select
|
141
|
-
screen.getByText('Hosts', { selector: '.pf-c-select__toggle-text' })
|
141
|
+
screen.getByText('Hosts', { selector: '.pf-v5-c-select__toggle-text' })
|
142
142
|
);
|
143
143
|
});
|
144
144
|
});
|
@@ -8,6 +8,9 @@ import {
|
|
8
8
|
InputGroup,
|
9
9
|
Text,
|
10
10
|
Spinner,
|
11
|
+
InputGroupItem,
|
12
|
+
FormHelperText,
|
13
|
+
HelperText,
|
11
14
|
} from '@patternfly/react-core';
|
12
15
|
import PropTypes from 'prop-types';
|
13
16
|
import { useSelector, useDispatch } from 'react-redux';
|
@@ -145,43 +148,40 @@ const HostsAndInputs = ({
|
|
145
148
|
/>
|
146
149
|
)}
|
147
150
|
<Form>
|
148
|
-
<FormGroup
|
149
|
-
fieldId="host_selection"
|
150
|
-
id="host-selection"
|
151
|
-
helperTextInvalid={errorText}
|
152
|
-
validated={isError ? 'error' : 'default'}
|
153
|
-
>
|
151
|
+
<FormGroup fieldId="host_selection" id="host-selection">
|
154
152
|
<InputGroup onBlur={() => setWasFocus(true)}>
|
155
|
-
<
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
153
|
+
<InputGroupItem>
|
154
|
+
<SelectField
|
155
|
+
isRequired
|
156
|
+
className="target-method-select"
|
157
|
+
toggleIcon={<FilterIcon />}
|
158
|
+
fieldId="host_methods"
|
159
|
+
options={Object.values(hostMethods).filter(method => {
|
160
|
+
if (method === hostMethods.hostCollections && !withKatello) {
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
return true;
|
164
|
+
})}
|
165
|
+
setValue={val => {
|
166
|
+
setHostMethod(val);
|
167
|
+
if (val === hostMethods.searchQuery) {
|
168
|
+
setErrorText(__('Please enter a search query'));
|
169
|
+
}
|
170
|
+
if (val === hostMethods.hosts) {
|
171
|
+
setErrorText(__('Please select at least one host'));
|
172
|
+
}
|
173
|
+
if (val === hostMethods.hostCollections) {
|
174
|
+
setErrorText(
|
175
|
+
__('Please select at least one host collection')
|
176
|
+
);
|
177
|
+
}
|
178
|
+
if (val === hostMethods.hostGroups) {
|
179
|
+
setErrorText(__('Please select at least one host group'));
|
180
|
+
}
|
181
|
+
}}
|
182
|
+
value={hostMethod}
|
183
|
+
/>
|
184
|
+
</InputGroupItem>
|
185
185
|
{hostMethod === hostMethods.searchQuery && (
|
186
186
|
<HostSearch
|
187
187
|
setValue={setHostsSearchQuery}
|
@@ -220,6 +220,11 @@ const HostsAndInputs = ({
|
|
220
220
|
/>
|
221
221
|
)}
|
222
222
|
</InputGroup>
|
223
|
+
{isError && (
|
224
|
+
<FormHelperText>
|
225
|
+
<HelperText>{errorText}</HelperText>
|
226
|
+
</FormHelperText>
|
227
|
+
)}
|
223
228
|
</FormGroup>
|
224
229
|
<SelectedChips
|
225
230
|
selectedHosts={selectedHosts}
|
@@ -76,7 +76,7 @@ describe('ReviewDetails', () => {
|
|
76
76
|
expect(screen.getAllByText('Review details')).toHaveLength(3);
|
77
77
|
fireEvent.click(
|
78
78
|
screen.getByText('Job template', {
|
79
|
-
selector: '.pf-c-button',
|
79
|
+
selector: '.pf-v5-c-button',
|
80
80
|
})
|
81
81
|
);
|
82
82
|
expect(screen.getAllByText('Category and template')).toHaveLength(3);
|
@@ -88,7 +88,7 @@ describe('ReviewDetails', () => {
|
|
88
88
|
act(() => {
|
89
89
|
fireEvent.click(
|
90
90
|
screen.getByText('Target hosts', {
|
91
|
-
selector: '.pf-c-button',
|
91
|
+
selector: '.pf-v5-c-button',
|
92
92
|
})
|
93
93
|
);
|
94
94
|
jest.advanceTimersByTime(1000); // to handle pf4 date picker popover useTimer
|
@@ -100,7 +100,7 @@ describe('ReviewDetails', () => {
|
|
100
100
|
act(() => {
|
101
101
|
fireEvent.click(
|
102
102
|
screen.getByText('Advanced fields', {
|
103
|
-
selector: '.pf-c-button',
|
103
|
+
selector: '.pf-v5-c-button',
|
104
104
|
})
|
105
105
|
);
|
106
106
|
jest.advanceTimersByTime(1000);
|
@@ -6,8 +6,8 @@ import {
|
|
6
6
|
DescriptionListTerm,
|
7
7
|
DescriptionListGroup,
|
8
8
|
DescriptionListDescription,
|
9
|
-
WizardContextConsumer,
|
10
9
|
} from '@patternfly/react-core';
|
10
|
+
import { WizardContextConsumer } from '@patternfly/react-core/deprecated';
|
11
11
|
import PropTypes from 'prop-types';
|
12
12
|
import { useDispatch, useSelector } from 'react-redux';
|
13
13
|
import { get } from 'foremanReact/redux/API';
|
@@ -20,7 +20,7 @@ export const RepeatDaily = ({ repeatData, setRepeatData, setValid }) => {
|
|
20
20
|
className="time-picker"
|
21
21
|
time={repeatData.at}
|
22
22
|
placeholder="hh:mm"
|
23
|
-
onChange={newTime => {
|
23
|
+
onChange={(e, newTime) => {
|
24
24
|
setRepeatData({ ...repeatData, at: newTime });
|
25
25
|
}}
|
26
26
|
is24Hour
|
@@ -2,13 +2,15 @@ import React, { useState, useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import {
|
4
4
|
FormGroup,
|
5
|
-
Select,
|
6
|
-
SelectOption,
|
7
|
-
SelectVariant,
|
8
5
|
Alert,
|
9
6
|
AlertActionCloseButton,
|
10
7
|
ValidatedOptions,
|
11
8
|
} from '@patternfly/react-core';
|
9
|
+
import {
|
10
|
+
Select,
|
11
|
+
SelectOption,
|
12
|
+
SelectVariant,
|
13
|
+
} from '@patternfly/react-core/deprecated';
|
12
14
|
import { translate as __ } from 'foremanReact/common/I18n';
|
13
15
|
import { helpLabel } from '../form/FormHelpers';
|
14
16
|
|
@@ -43,7 +45,7 @@ export const RepeatHour = ({ repeatData, setRepeatData }) => {
|
|
43
45
|
setMinuteOpen(false);
|
44
46
|
}}
|
45
47
|
selections={`${minute}` || ''}
|
46
|
-
onToggle={toggle => {
|
48
|
+
onToggle={(_event, toggle) => {
|
47
49
|
setMinuteOpen(toggle);
|
48
50
|
}}
|
49
51
|
isOpen={minuteOpen}
|
@@ -26,7 +26,7 @@ export const RepeatMonth = ({ repeatData, setRepeatData, setValid }) => {
|
|
26
26
|
placeholder="1,2..."
|
27
27
|
type="text"
|
28
28
|
value={repeatData.days || ''}
|
29
|
-
onChange={newTime => {
|
29
|
+
onChange={(_event, newTime) => {
|
30
30
|
setRepeatData({ ...repeatData, days: newTime });
|
31
31
|
}}
|
32
32
|
/>
|
@@ -32,7 +32,7 @@ export const RepeatWeek = ({ repeatData, setRepeatData, setValid }) => {
|
|
32
32
|
return () => setValid(true);
|
33
33
|
}, [setValid, daysOfWeek, at]);
|
34
34
|
const days = getWeekDays();
|
35
|
-
const handleChangeDays = (
|
35
|
+
const handleChangeDays = ({ target: { name } }, checked) => {
|
36
36
|
setRepeatData({
|
37
37
|
...repeatData,
|
38
38
|
daysOfWeek: { ...repeatData.daysOfWeek, [name]: checked },
|
@@ -4,7 +4,9 @@ import {
|
|
4
4
|
FormGroup,
|
5
5
|
Form,
|
6
6
|
Button,
|
7
|
-
|
7
|
+
FormHelperText,
|
8
|
+
HelperText,
|
9
|
+
HelperTextItem,
|
8
10
|
} from '@patternfly/react-core';
|
9
11
|
import { translate as __ } from 'foremanReact/common/I18n';
|
10
12
|
import { DateTimePicker } from '../form/DateTimePicker';
|
@@ -85,8 +87,6 @@ export const ScheduleFuture = ({
|
|
85
87
|
),
|
86
88
|
'start-before-date'
|
87
89
|
)}
|
88
|
-
validated={error ? ValidatedOptions.error : ValidatedOptions.noval}
|
89
|
-
helperTextInvalid={error}
|
90
90
|
>
|
91
91
|
<DateTimePicker
|
92
92
|
ariaLabel="starts before"
|
@@ -112,6 +112,13 @@ export const ScheduleFuture = ({
|
|
112
112
|
>
|
113
113
|
{__('Clear input')}
|
114
114
|
</Button>
|
115
|
+
{error && (
|
116
|
+
<FormHelperText>
|
117
|
+
<HelperText>
|
118
|
+
<HelperTextItem variant="error">{error}</HelperTextItem>
|
119
|
+
</HelperText>
|
120
|
+
</FormHelperText>
|
121
|
+
)}
|
115
122
|
</FormGroup>
|
116
123
|
</Form>
|
117
124
|
</>
|
@@ -5,8 +5,10 @@ import {
|
|
5
5
|
FormGroup,
|
6
6
|
Radio,
|
7
7
|
TextInput,
|
8
|
-
ValidatedOptions,
|
9
8
|
Divider,
|
9
|
+
FormHelperText,
|
10
|
+
HelperText,
|
11
|
+
HelperTextItem,
|
10
12
|
} from '@patternfly/react-core';
|
11
13
|
import { ExclamationCircleIcon } from '@patternfly/react-icons';
|
12
14
|
import { translate as __ } from 'foremanReact/common/I18n';
|
@@ -86,7 +88,7 @@ export const ScheduleRecurring = ({
|
|
86
88
|
<WizardTitle title={SCHEDULE_TYPES.RECURRING} />
|
87
89
|
<Form className="schedule-tab">
|
88
90
|
<FormGroup label={__('Starts')} fieldId="schedule-starts">
|
89
|
-
<div className="pf-
|
91
|
+
<div className="pf-v5-cform">
|
90
92
|
<FormGroup fieldId="schedule-starts-now">
|
91
93
|
<Radio
|
92
94
|
ouiaId="schedule-start-now"
|
@@ -162,7 +164,7 @@ export const ScheduleRecurring = ({
|
|
162
164
|
/>
|
163
165
|
<Divider component="div" />
|
164
166
|
<FormGroup label={__('Ends')} fieldId="schedule-ends">
|
165
|
-
<div className="pf-
|
167
|
+
<div className="pf-v5-cform">
|
166
168
|
<FormGroup fieldId="schedule-ends-never">
|
167
169
|
<Radio
|
168
170
|
ouiaId="schedule-never-ends"
|
@@ -180,14 +182,7 @@ export const ScheduleRecurring = ({
|
|
180
182
|
label={__('Never')}
|
181
183
|
/>
|
182
184
|
</FormGroup>
|
183
|
-
<FormGroup
|
184
|
-
fieldId="ends-on-date"
|
185
|
-
validated={
|
186
|
-
validEnd ? ValidatedOptions.noval : ValidatedOptions.error
|
187
|
-
}
|
188
|
-
helperTextInvalid={__('End time needs to be after start time')}
|
189
|
-
helperTextInvalidIcon={<ExclamationCircleIcon />}
|
190
|
-
>
|
185
|
+
<FormGroup fieldId="ends-on-date">
|
191
186
|
<Radio
|
192
187
|
ouiaId="schedule-ends-on-date"
|
193
188
|
isChecked={!!ends}
|
@@ -219,6 +214,18 @@ export const ScheduleRecurring = ({
|
|
219
214
|
</div>
|
220
215
|
}
|
221
216
|
/>
|
217
|
+
{!validEnd && (
|
218
|
+
<FormHelperText>
|
219
|
+
<HelperText>
|
220
|
+
<HelperTextItem
|
221
|
+
icon={<ExclamationCircleIcon />}
|
222
|
+
variant="error"
|
223
|
+
>
|
224
|
+
{__('End time needs to be after start time')}
|
225
|
+
</HelperTextItem>
|
226
|
+
</HelperText>
|
227
|
+
</FormHelperText>
|
228
|
+
)}
|
222
229
|
</FormGroup>
|
223
230
|
<FormGroup fieldId="ends-after">
|
224
231
|
<Radio
|
@@ -238,21 +245,24 @@ export const ScheduleRecurring = ({
|
|
238
245
|
label={
|
239
246
|
<div className="schedule-radio-wrapper">
|
240
247
|
<div className="schedule-radio-title">{__('After')}</div>
|
241
|
-
<FormGroup
|
242
|
-
helperTextInvalid={__(
|
243
|
-
'Repeat amount can only be a positive number'
|
244
|
-
)}
|
245
|
-
validated={repeatValidated}
|
246
|
-
className="schedule-radio-repeat-text"
|
247
|
-
>
|
248
|
+
<FormGroup className="schedule-radio-repeat-text">
|
248
249
|
<TextInput
|
249
250
|
ouiaId="repeat-amount"
|
250
251
|
id="repeat-amount"
|
251
252
|
value={repeatAmount || ''}
|
252
253
|
type="number"
|
253
|
-
onChange={
|
254
|
+
onChange={(_event, newValue) =>
|
255
|
+
handleRepeatInputChange(newValue)
|
256
|
+
}
|
254
257
|
isDisabled={!(repeatAmount === 0 || !!repeatAmount)}
|
255
258
|
/>
|
259
|
+
{repeatValidated === 'error' && (
|
260
|
+
<HelperText>
|
261
|
+
<HelperTextItem variant="error">
|
262
|
+
{__('Repeat amount can only be a positive number')}
|
263
|
+
</HelperTextItem>
|
264
|
+
</HelperText>
|
265
|
+
)}
|
256
266
|
</FormGroup>
|
257
267
|
<div className="schedule-radio-occurences">
|
258
268
|
{__('occurences')}
|
@@ -75,7 +75,7 @@ export const DateTimePicker = ({
|
|
75
75
|
}
|
76
76
|
};
|
77
77
|
|
78
|
-
const onTimeChange = newTime => {
|
78
|
+
const onTimeChange = (e, newTime) => {
|
79
79
|
if (!newTime.length && allowEmpty) {
|
80
80
|
const parsedNewTime = new Date(`${formattedDate} 00:00`);
|
81
81
|
setDateTime(formatDateTime(parsedNewTime));
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
-
import { Popover, Button } from '@patternfly/react-core';
|
3
|
+
import { Popover, Button, Icon } from '@patternfly/react-core';
|
4
4
|
import { HelpIcon } from '@patternfly/react-icons';
|
5
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
6
|
+
import styles from '@patternfly/react-styles/css/components/Form/form';
|
6
7
|
|
7
8
|
export const helpLabel = (text, id) => {
|
8
9
|
if (!text) return null;
|
@@ -12,9 +13,11 @@ export const helpLabel = (text, id) => {
|
|
12
13
|
type="button"
|
13
14
|
aria-label={__('open-help-tooltip-button')}
|
14
15
|
onClick={e => e.preventDefault()}
|
15
|
-
className=
|
16
|
+
className={styles.formGroupLabelHelp}
|
16
17
|
>
|
17
|
-
<
|
18
|
+
<Icon isInline>
|
19
|
+
<HelpIcon />
|
20
|
+
</Icon>
|
18
21
|
</button>
|
19
22
|
</Popover>
|
20
23
|
);
|
@@ -31,7 +34,7 @@ export const ResetDefault = ({ setValue, defaultValue }) =>
|
|
31
34
|
className="reset-default"
|
32
35
|
component="a"
|
33
36
|
variant="link"
|
34
|
-
|
37
|
+
size="sm"
|
35
38
|
onClick={() => setValue(defaultValue)}
|
36
39
|
>
|
37
40
|
{__('Reset to default')}
|