Skip to content

Commit

Permalink
add schedule form validation to ensure at least one occurrence
Browse files Browse the repository at this point in the history
  • Loading branch information
keithjgrant committed Sep 7, 2022
1 parent 0005d24 commit 3e86206
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 33 deletions.
21 changes: 21 additions & 0 deletions awx/ui/src/components/Schedule/shared/ScheduleForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import ScheduleFormFields from './ScheduleFormFields';
import UnsupportedScheduleForm from './UnsupportedScheduleForm';
import parseRuleObj, { UnsupportedRRuleError } from './parseRuleObj';
import buildRuleObj from './buildRuleObj';
import buildRuleSet from './buildRuleSet';

const NUM_DAYS_PER_FREQUENCY = {
week: 7,
Expand Down Expand Up @@ -411,6 +412,26 @@ function ScheduleForm({
}
});

if (values.exceptionFrequency.length > 0) {
let rangeToCheck = 1;
values.frequency.forEach((freq) => {
if (NUM_DAYS_PER_FREQUENCY[freq] > rangeToCheck) {
rangeToCheck = NUM_DAYS_PER_FREQUENCY[freq];
}
});
const ruleSet = buildRuleSet(values, true);
const startDate = DateTime.fromISO(values.startDate);
const endDate = startDate.plus({ days: rangeToCheck });
const instances = ruleSet.between(
startDate.toJSDate(),
endDate.toJSDate(),
true
);
if (instances.length === 0) {
errors.exceptionFrequency = t`This schedule has no occurrences with the selected exceptions.`;
}
}

return errors;
};

Expand Down
38 changes: 27 additions & 11 deletions awx/ui/src/components/Schedule/shared/buildRuleObj.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,19 @@ function pad(num) {
return num < 10 ? `0${num}` : num;
}

export default function buildRuleObj(values) {
export default function buildRuleObj(values, includeStart) {
const ruleObj = {
interval: values.interval,
};

if (includeStart) {
ruleObj.dtstart = buildDateTime(
values.startDate,
values.startTime,
values.timezone
);
}

switch (values.frequency) {
case 'none':
ruleObj.count = 1;
Expand Down Expand Up @@ -91,16 +99,11 @@ export default function buildRuleObj(values) {
ruleObj.count = values.occurrences;
break;
case 'onDate': {
const [endHour, endMinute] = parseTime(values.endTime);
const localEndDate = DateTime.fromISO(`${values.endDate}T000000`, {
zone: values.timezone,
});
const localEndTime = localEndDate.set({
hour: endHour,
minute: endMinute,
second: 0,
});
ruleObj.until = localEndTime.toJSDate();
ruleObj.until = buildDateTime(
values.endDate,
values.endTime,
values.timezone
);
break;
}
default:
Expand All @@ -110,3 +113,16 @@ export default function buildRuleObj(values) {

return ruleObj;
}

function buildDateTime(dateString, timeString, timezone) {
const localDate = DateTime.fromISO(`${dateString}T000000`, {
zone: timezone,
});
const [hour, minute] = parseTime(timeString);
const localTime = localDate.set({
hour,
minute,
second: 0,
});
return localTime.toJSDate();
}
53 changes: 31 additions & 22 deletions awx/ui/src/components/Schedule/shared/buildRuleSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import buildRuleObj, { buildDtStartObj } from './buildRuleObj';
window.RRuleSet = RRuleSet;

const frequencies = ['minute', 'hour', 'day', 'week', 'month', 'year'];
export default function buildRuleSet(values) {
export default function buildRuleSet(values, includeStart) {
const set = new RRuleSet();

const startRule = buildDtStartObj({
Expand All @@ -15,41 +15,50 @@ export default function buildRuleSet(values) {
set.rrule(startRule);

if (values.frequency.length === 0) {
const rule = buildRuleObj({
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency: 'none',
interval: 1,
});
const rule = buildRuleObj(
{
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency: 'none',
interval: 1,
},
includeStart
);
set.rrule(new RRule(rule));
}

frequencies.forEach((frequency) => {
if (!values.frequency.includes(frequency)) {
return;
}
const rule = buildRuleObj({
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency,
...values.frequencyOptions[frequency],
});
const rule = buildRuleObj(
{
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency,
...values.frequencyOptions[frequency],
},
includeStart
);
set.rrule(new RRule(rule));
});

frequencies.forEach((frequency) => {
if (!values.exceptionFrequency?.includes(frequency)) {
return;
}
const rule = buildRuleObj({
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency,
...values.exceptionOptions[frequency],
});
const rule = buildRuleObj(
{
startDate: values.startDate,
startTime: values.startTime,
timezone: values.timezone,
frequency,
...values.exceptionOptions[frequency],
},
includeStart
);
set.exrule(new RRule(rule));
});

Expand Down

0 comments on commit 3e86206

Please sign in to comment.