Skip to content

Commit

Permalink
Fixes #38059 - job wizard limit starts at to future only
Browse files Browse the repository at this point in the history
  • Loading branch information
MariaAga committed Dec 3, 2024
1 parent ca7cca1 commit c665348
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 19 deletions.
46 changes: 33 additions & 13 deletions webpack/JobWizard/JobWizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ import { useValidation } from './validation';
import { useAutoFill } from './autofill';
import { submit } from './submit';
import { generateDefaultDescription } from './JobWizardHelpers';
import { StartsBeforeErrorAlert } from './StartsBeforeErrorAlert';
import {
StartsBeforeErrorAlert,
StartsAtErrorAlert,
} from './StartsBeforeErrorAlert';
import { Footer } from './Footer';
import './JobWizard.scss';

Expand Down Expand Up @@ -203,22 +206,37 @@ export const JobWizard = ({ rerunData }) => {
}, [rerunData, jobTemplateID, dispatch]);

const [isStartsBeforeError, setIsStartsBeforeError] = useState(false);
const [isStartsAtError, setIsStartsAtError] = useState(false);
useEffect(() => {
const updateStartsBeforeError = () => {
setIsStartsBeforeError(
scheduleValue.scheduleType === SCHEDULE_TYPES.FUTURE &&
new Date().getTime() >= new Date(scheduleValue.startsBefore).getTime()
);
const updateStartsError = () => {
if (scheduleValue.scheduleType === SCHEDULE_TYPES.FUTURE) {
setIsStartsAtError(
!!scheduleValue?.startsAt?.length &&
new Date().getTime() >= new Date(scheduleValue.startsAt).getTime()
);
setIsStartsBeforeError(
!!scheduleValue?.startsBefore?.length &&
new Date().getTime() >=
new Date(scheduleValue.startsBefore).getTime()
);
} else if (scheduleValue.scheduleType === SCHEDULE_TYPES.RECURRING) {
setIsStartsAtError(
!!scheduleValue?.startsAt?.length &&
new Date().getTime() >= new Date(scheduleValue.startsAt).getTime()
);
setIsStartsBeforeError(false);
} else {
setIsStartsAtError(false);
setIsStartsBeforeError(false);
}
};
let interval;
if (scheduleValue.scheduleType === SCHEDULE_TYPES.FUTURE) {
updateStartsBeforeError();
interval = setInterval(updateStartsBeforeError, 5000);
}
updateStartsError();
const interval = setInterval(updateStartsError, 5000);

return () => {
interval && clearInterval(interval);
};
}, [scheduleValue.scheduleType, scheduleValue.startsBefore]);
}, [scheduleValue]);

const [valid, setValid] = useValidation({
advancedValues,
Expand Down Expand Up @@ -432,7 +450,8 @@ export const JobWizard = ({ rerunData }) => {
valid.advanced &&
valid.schedule &&
!isSubmitting &&
!isStartsBeforeError,
!isStartsBeforeError &&
!isStartsAtError,
},
];
const location = useForemanLocation();
Expand All @@ -456,6 +475,7 @@ export const JobWizard = ({ rerunData }) => {
return (
<>
{isStartsBeforeError && <StartsBeforeErrorAlert />}
{isStartsAtError && <StartsAtErrorAlert />}
<Wizard
onClose={() => history.goBack()}
navAriaLabel="Run Job steps"
Expand Down
15 changes: 15 additions & 0 deletions webpack/JobWizard/StartsBeforeErrorAlert.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@ export const StartsBeforeErrorAlert = () => (
<Divider component="div" />
</>
);

export const StartsAtErrorAlert = () => (
<>
<Alert
ouiaId="starts-at-error-alert"
variant="danger"
title={__("'Starts at' date must in the future")}
>
{__(
'Please go back to "Schedule" - "Future execution" or "Recurring execution" step to fix the error'
)}
</Alert>
<Divider component="div" />
</>
);
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ describe('AdvancedFields', () => {
target: { value: 'some search' },
});

jest.runAllTimers();
jest.advanceTimersByTime(10000);
});
expect(newStore.getActions()).toMatchSnapshot('resource search');
});
Expand Down
8 changes: 5 additions & 3 deletions webpack/JobWizard/steps/Schedule/ScheduleRecurring.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ScheduleRecurring = ({
if (isNeverEnds) setValidEnd(true);
else if (!ends) setValidEnd(true);
else if (
!startsAt.length &&
!startsAt?.length &&
new Date().getTime() <= new Date(ends).getTime()
)
setValidEnd(true);
Expand All @@ -63,7 +63,7 @@ export const ScheduleRecurring = ({

if (!validEnd || !repeatValid) {
wrappedSetValid(false);
} else if (isFuture && startsAt.length) {
} else if (isFuture && startsAt?.length) {
wrappedSetValid(true);
} else if (!isFuture) {
wrappedSetValid(true);
Expand Down Expand Up @@ -111,7 +111,9 @@ export const ScheduleRecurring = ({
onChange={() =>
setScheduleValue(current => ({
...current,
startsAt: new Date().toISOString(),
startsAt: new Date(
new Date().getTime() + 60000
).toISOString(), // 1 minute in the future
isFuture: true,
}))
}
Expand Down
2 changes: 1 addition & 1 deletion webpack/JobWizard/steps/Schedule/ScheduleType.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const ScheduleType = ({
onChange={() => {
setScheduleValue(current => ({
...current,
startsAt: new Date().toISOString(),
startsAt: new Date(new Date().getTime() + 60000).toISOString(), // 1 minute in the future
scheduleType: SCHEDULE_TYPES.FUTURE,
repeatType: repeatTypes.noRepeat,
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ describe('Schedule', () => {
fireEvent.click(
screen.getByRole('button', { name: 'Recurring execution' })
);
jest.runAllTimers();
jest.advanceTimersByTime(1000);
});
expect(screen.queryAllByText('Recurring execution')).toHaveLength(3);

Expand Down
13 changes: 13 additions & 0 deletions webpack/JobWizard/steps/form/DateTimePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const DateTimePicker = ({
ariaLabel,
allowEmpty,
includeSeconds,
isFutureOnly,
}) => {
const [validated, setValidated] = useState();
const dateFormat = date =>
Expand Down Expand Up @@ -87,6 +88,15 @@ export const DateTimePicker = ({
setValidated(ValidatedOptions.error);
}
};
const validateFuture = date => {
if (
isFutureOnly &&
date.setHours(1, 0, 0, 0) < new Date().setHours(0, 0, 0, 0)
) {
return __('Date must be in the future');
}
return '';
};
return (
<>
<DatePicker
Expand All @@ -105,6 +115,7 @@ export const DateTimePicker = ({
validated === ValidatedOptions.error ? __('Invalid date') : ''
}
inputProps={{ validated }}
validators={[validateFuture]}
/>
<TimePicker
aria-label={`${ariaLabel} timepicker`}
Expand Down Expand Up @@ -132,11 +143,13 @@ DateTimePicker.propTypes = {
ariaLabel: PropTypes.string,
allowEmpty: PropTypes.bool,
includeSeconds: PropTypes.bool,
isFutureOnly: PropTypes.bool,
};
DateTimePicker.defaultProps = {
dateTime: null,
isDisabled: false,
ariaLabel: '',
allowEmpty: true,
includeSeconds: false,
isFutureOnly: true,
};
1 change: 1 addition & 0 deletions webpack/JobWizard/steps/form/Formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export const formatter = (input, values, setValue) => {
isRequired={required}
>
<DateTimePicker
isFutureOnly={false}
ariaLabel={name}
className={hidden ? 'masked-input' : null}
id={id}
Expand Down

0 comments on commit c665348

Please sign in to comment.