diff --git a/CHANGELOG.md b/CHANGELOG.md
index d10327b2fb..a5c527b004 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ This is a list of high-level changes for each release of AWX. A full list of com
- Playbook, credential type, and inventory file inputs now support type-ahead and manual type-in! https://github.com/ansible/awx/pull/9120
- Added ability to relaunch against failed hosts: https://github.com/ansible/awx/pull/9225
- Added pending workflow approval count to the application header https://github.com/ansible/awx/pull/9334
+- Added user interface for management jobs: https://github.com/ansible/awx/pull/9224
# 17.0.1 (January 26, 2021)
- Fixed pgdocker directory permissions issue with Local Docker installer: https://github.com/ansible/awx/pull/9152
diff --git a/awx/ui_next/src/components/Schedule/Schedule.jsx b/awx/ui_next/src/components/Schedule/Schedule.jsx
index e1e59c5d85..a725215029 100644
--- a/awx/ui_next/src/components/Schedule/Schedule.jsx
+++ b/awx/ui_next/src/components/Schedule/Schedule.jsx
@@ -95,6 +95,14 @@ function Schedule({
if (!pathname.includes('schedules/') || pathname.endsWith('edit')) {
showCardHeader = false;
}
+
+ // For some management jobs that delete data, we want to provide an additional
+ // field on the scheduler for configuring the number of days to retain.
+ const hasDaysToKeepField = [
+ 'cleanup_activitystream',
+ 'cleanup_jobs',
+ ].includes(schedule?.summary_fields?.unified_job_template?.job_type);
+
return (
<>
{showCardHeader && }
@@ -107,6 +115,7 @@ function Schedule({
{schedule && [
-
+
,
]}
diff --git a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
index c9e4f17fa4..2c00d989b1 100644
--- a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
+++ b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
@@ -26,6 +26,7 @@ import DeleteButton from '../../DeleteButton';
import ErrorDetail from '../../ErrorDetail';
import ChipGroup from '../../ChipGroup';
import { VariablesDetail } from '../../CodeMirrorInput';
+import { parseVariableField } from '../../../util/yaml';
const PromptDivider = styled(Divider)`
margin-top: var(--pf-global--spacer--lg);
@@ -42,7 +43,7 @@ const PromptDetailList = styled(DetailList)`
padding: 0px 20px;
`;
-function ScheduleDetail({ schedule, i18n, surveyConfig }) {
+function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
const {
id,
created,
@@ -233,6 +234,16 @@ function ScheduleDetail({ schedule, i18n, surveyConfig }) {
return ;
}
+ let daysToKeep = null;
+ if (hasDaysToKeepField && extra_data) {
+ if (typeof extra_data === 'string' && extra_data !== '') {
+ daysToKeep = parseVariableField(extra_data).days;
+ }
+ if (typeof extra_data === 'object') {
+ daysToKeep = extra_data?.days;
+ }
+ }
+
return (
+ {hasDaysToKeepField ? (
+
+ ) : null}
0) {
await Promise.all([
...removed.map(({ id }) =>
@@ -111,6 +122,7 @@ function ScheduleEdit({
history.push(`${pathRoot}schedules/${schedule.id}/details`)
}
diff --git a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
index 3088996a3d..cbe1526331 100644
--- a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
+++ b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
@@ -25,6 +25,7 @@ import {
import { dateToInputDateTime, formatDateStringUTC } from '../../../util/dates';
import useRequest from '../../../util/useRequest';
import { required } from '../../../util/validators';
+import { parseVariableField } from '../../../util/yaml';
import FrequencyDetailSubform from './FrequencyDetailSubform';
import SchedulePromptableFields from './SchedulePromptableFields';
@@ -77,7 +78,7 @@ const generateRunOnTheDay = (days = []) => {
return null;
};
-function ScheduleFormFields({ i18n, zoneOptions }) {
+function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
const [startDateTime, startDateTimeMeta] = useField({
name: 'startDateTime',
validate: required(
@@ -169,6 +170,16 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
{...frequency}
/>
+ {hasDaysToKeepField ? (
+
+ ) : null}
{frequency.value !== 'none' && (
@@ -184,6 +195,7 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
}
function ScheduleForm({
+ hasDaysToKeepField,
handleCancel,
handleSubmit,
i18n,
@@ -344,6 +356,22 @@ function ScheduleForm({
);
};
+ if (hasDaysToKeepField) {
+ let initialDaysToKeep = 30;
+ if (schedule?.extra_data) {
+ if (
+ typeof schedule?.extra_data === 'string' &&
+ schedule?.extra_data !== ''
+ ) {
+ initialDaysToKeep = parseVariableField(schedule?.extra_data).days;
+ }
+ if (typeof schedule?.extra_data === 'object') {
+ initialDaysToKeep = schedule?.extra_data?.days;
+ }
+ }
+ initialValues.daysToKeep = initialDaysToKeep;
+ }
+
const overriddenValues = {};
if (Object.keys(schedule).length > 0) {
@@ -487,6 +515,7 @@ function ScheduleForm({