mirror of
https://github.com/ansible/awx.git
synced 2026-03-23 11:55:04 -02:30
Merge pull request #13915 from marshmalien/10877-dup-freq-types-schedule
Show schedule details warning when RRule is unsupported
This commit is contained in:
@@ -11,7 +11,8 @@ import { JobTemplatesAPI, SchedulesAPI, WorkflowJobTemplatesAPI } from 'api';
|
|||||||
import { parseVariableField, jsonToYaml } from 'util/yaml';
|
import { parseVariableField, jsonToYaml } from 'util/yaml';
|
||||||
import { useConfig } from 'contexts/Config';
|
import { useConfig } from 'contexts/Config';
|
||||||
import InstanceGroupLabels from 'components/InstanceGroupLabels';
|
import InstanceGroupLabels from 'components/InstanceGroupLabels';
|
||||||
import parseRuleObj from '../shared/parseRuleObj';
|
import parseRuleObj, { UnsupportedRRuleError } from '../shared/parseRuleObj';
|
||||||
|
import UnsupportedRRuleAlert from '../shared/UnsupportedRRuleAlert';
|
||||||
import FrequencyDetails from './FrequencyDetails';
|
import FrequencyDetails from './FrequencyDetails';
|
||||||
import AlertModal from '../../AlertModal';
|
import AlertModal from '../../AlertModal';
|
||||||
import { CardBody, CardActionsRow } from '../../Card';
|
import { CardBody, CardActionsRow } from '../../Card';
|
||||||
@@ -182,8 +183,20 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
|
|||||||
month: t`Month`,
|
month: t`Month`,
|
||||||
year: t`Year`,
|
year: t`Year`,
|
||||||
};
|
};
|
||||||
const { frequency, frequencyOptions, exceptionFrequency, exceptionOptions } =
|
let rruleError;
|
||||||
parseRuleObj(schedule);
|
let frequency = [];
|
||||||
|
let frequencyOptions = {};
|
||||||
|
let exceptionFrequency = [];
|
||||||
|
let exceptionOptions = {};
|
||||||
|
try {
|
||||||
|
({ frequency, frequencyOptions, exceptionFrequency, exceptionOptions } =
|
||||||
|
parseRuleObj(schedule));
|
||||||
|
} catch (parseRuleError) {
|
||||||
|
if (parseRuleError instanceof UnsupportedRRuleError) {
|
||||||
|
rruleError = parseRuleError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const repeatFrequency = frequency.length
|
const repeatFrequency = frequency.length
|
||||||
? frequency.map((f) => frequencies[f]).join(', ')
|
? frequency.map((f) => frequencies[f]).join(', ')
|
||||||
: t`None (Run Once)`;
|
: t`None (Run Once)`;
|
||||||
@@ -602,6 +615,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
|
|||||||
</PromptDetailList>
|
</PromptDetailList>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{rruleError && <UnsupportedRRuleAlert schedule={schedule} />}
|
||||||
<CardActionsRow>
|
<CardActionsRow>
|
||||||
{summary_fields?.user_capabilities?.edit && (
|
{summary_fields?.user_capabilities?.edit && (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -587,4 +587,31 @@ describe('<ScheduleDetail />', () => {
|
|||||||
(el) => el.prop('isDisabled') === true
|
(el) => el.prop('isDisabled') === true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
test('should display warning for unsupported recurrence rules ', async () => {
|
||||||
|
const unsupportedSchedule = {
|
||||||
|
...schedule,
|
||||||
|
rrule:
|
||||||
|
'DTSTART:20221220T161500Z RRULE:FREQ=HOURLY;INTERVAL=1 EXRULE:FREQ=HOURLY;INTERVAL=1;BYDAY=TU;BYMONTHDAY=1,2,3,4,5,6,7 EXRULE:FREQ=HOURLY;INTERVAL=1;BYDAY=WE;BYMONTHDAY=2,3,4,5,6,7,8',
|
||||||
|
};
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<Route
|
||||||
|
path="/templates/job_template/:id/schedules/:scheduleId"
|
||||||
|
component={() => <ScheduleDetail schedule={unsupportedSchedule} />}
|
||||||
|
/>,
|
||||||
|
{
|
||||||
|
context: {
|
||||||
|
router: {
|
||||||
|
history,
|
||||||
|
route: {
|
||||||
|
location: history.location,
|
||||||
|
match: { params: { id: 1 } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(wrapper.find('UnsupportedRRuleAlert').length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Alert } from '@patternfly/react-core';
|
||||||
|
|
||||||
|
const AlertWrapper = styled.div`
|
||||||
|
margin-top: var(--pf-global--spacer--lg);
|
||||||
|
margin-bottom: var(--pf-global--spacer--lg);
|
||||||
|
`;
|
||||||
|
const RulesTitle = styled.p`
|
||||||
|
margin-top: var(--pf-global--spacer--lg);
|
||||||
|
margin-bottom: var(--pf-global--spacer--lg);
|
||||||
|
font-weight: var(--pf-global--FontWeight--bold);
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function UnsupportedRRuleAlert({ schedule }) {
|
||||||
|
return (
|
||||||
|
<AlertWrapper>
|
||||||
|
<Alert
|
||||||
|
isInline
|
||||||
|
variant="danger"
|
||||||
|
ouiaId="schedule-warning"
|
||||||
|
title={t`This schedule uses complex rules that are not supported in the
|
||||||
|
UI. Please use the API to manage this schedule.`}
|
||||||
|
/>
|
||||||
|
<RulesTitle>{t`Schedule Rules`}:</RulesTitle>
|
||||||
|
<pre css="white-space: pre; font-family: var(--pf-global--FontFamily--monospace)">
|
||||||
|
{schedule.rrule.split(' ').join('\n')}
|
||||||
|
</pre>
|
||||||
|
</AlertWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -82,11 +82,7 @@ const frequencyTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function parseRrule(rruleString, schedule, values) {
|
function parseRrule(rruleString, schedule, values) {
|
||||||
const { frequency, options } = parseRule(
|
const { frequency, options } = parseRule(rruleString, schedule);
|
||||||
rruleString,
|
|
||||||
schedule,
|
|
||||||
values.exceptionFrequency
|
|
||||||
);
|
|
||||||
|
|
||||||
if (values.frequencyOptions[frequency]) {
|
if (values.frequencyOptions[frequency]) {
|
||||||
throw new UnsupportedRRuleError(
|
throw new UnsupportedRRuleError(
|
||||||
@@ -105,11 +101,7 @@ function parseRrule(rruleString, schedule, values) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseExRule(exruleString, schedule, values) {
|
function parseExRule(exruleString, schedule, values) {
|
||||||
const { frequency, options } = parseRule(
|
const { frequency, options } = parseRule(exruleString, schedule);
|
||||||
exruleString,
|
|
||||||
schedule,
|
|
||||||
values.exceptionFrequency
|
|
||||||
);
|
|
||||||
|
|
||||||
if (values.exceptionOptions[frequency]) {
|
if (values.exceptionOptions[frequency]) {
|
||||||
throw new UnsupportedRRuleError(
|
throw new UnsupportedRRuleError(
|
||||||
@@ -129,7 +121,7 @@ function parseExRule(exruleString, schedule, values) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseRule(ruleString, schedule, frequencies) {
|
function parseRule(ruleString, schedule) {
|
||||||
const {
|
const {
|
||||||
origOptions: {
|
origOptions: {
|
||||||
bymonth,
|
bymonth,
|
||||||
@@ -178,9 +170,6 @@ function parseRule(ruleString, schedule, frequencies) {
|
|||||||
throw new Error(`Unexpected rrule frequency: ${freq}`);
|
throw new Error(`Unexpected rrule frequency: ${freq}`);
|
||||||
}
|
}
|
||||||
const frequency = frequencyTypes[freq];
|
const frequency = frequencyTypes[freq];
|
||||||
if (frequencies.includes(frequency)) {
|
|
||||||
throw new Error(`Duplicate frequency types not supported (${frequency})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (freq === RRule.WEEKLY && byweekday) {
|
if (freq === RRule.WEEKLY && byweekday) {
|
||||||
options.daysOfWeek = byweekday;
|
options.daysOfWeek = byweekday;
|
||||||
|
|||||||
Reference in New Issue
Block a user