mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 15:36:04 -03:30
Add system prompt and config
This commit is contained in:
@@ -3359,6 +3359,13 @@ class SystemJobTemplateSerializer(UnifiedJobTemplateSerializer):
|
|||||||
del result['default_days']
|
del result['default_days']
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SystemJobTemplateSerializer, self).__init__(*args, **kwargs)
|
||||||
|
for field_name, field_instance in self.fields.items():
|
||||||
|
if field_name != 'default_days':
|
||||||
|
field_instance.read_only = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SystemJobSerializer(UnifiedJobSerializer):
|
class SystemJobSerializer(UnifiedJobSerializer):
|
||||||
|
|
||||||
|
|||||||
@@ -3423,7 +3423,7 @@ class SystemJobTemplateList(ListAPIView):
|
|||||||
return super(SystemJobTemplateList, self).get(request, *args, **kwargs)
|
return super(SystemJobTemplateList, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class SystemJobTemplateDetail(RetrieveAPIView):
|
class SystemJobTemplateDetail(RetrieveUpdateAPIView):
|
||||||
|
|
||||||
model = models.SystemJobTemplate
|
model = models.SystemJobTemplate
|
||||||
serializer_class = serializers.SystemJobTemplateSerializer
|
serializer_class = serializers.SystemJobTemplateSerializer
|
||||||
|
|||||||
@@ -1,9 +1,71 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { withI18n } from '@lingui/react';
|
||||||
|
import { Formik } from 'formik';
|
||||||
|
import { Form } from '@patternfly/react-core';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { SystemJobTemplatesAPI } from '../../../api';
|
||||||
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
|
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||||
|
import { FormColumnLayout } from '../../../components/FormLayout';
|
||||||
|
import { minMaxValue } from '../../../util/validators';
|
||||||
|
|
||||||
import { CardBody } from '../../../components/Card';
|
import { CardBody } from '../../../components/Card';
|
||||||
|
|
||||||
function ManagementJobEdit() {
|
function ManagementJobEdit({ i18n, managementJob }) {
|
||||||
return <CardBody>Management Job Edit</CardBody>;
|
const history = useHistory();
|
||||||
|
const [formError, setFormError] = useState(null);
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
history.push(`/management_jobs/${managementJob?.id}/details`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async values => {
|
||||||
|
try {
|
||||||
|
await SystemJobTemplatesAPI.update(managementJob?.id, {
|
||||||
|
default_days: values.dataRetention,
|
||||||
|
});
|
||||||
|
history.push(`/management_jobs/${managementJob?.id}/details`);
|
||||||
|
} catch (error) {
|
||||||
|
setFormError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CardBody>
|
||||||
|
{managementJob?.default_days ? (
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
dataRetention: managementJob?.default_days || null,
|
||||||
|
description: i18n._(t`Delete data older than this number of days.`),
|
||||||
|
}}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{formik => (
|
||||||
|
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||||
|
<FormColumnLayout>
|
||||||
|
<FormField
|
||||||
|
id="data-retention"
|
||||||
|
name="dataRetention"
|
||||||
|
type="number"
|
||||||
|
label={i18n._(t`Data Retention (Days)`)}
|
||||||
|
tooltip={i18n._(
|
||||||
|
t`Delete data older than this number of days.`
|
||||||
|
)}
|
||||||
|
validate={minMaxValue(0, Number.MAX_SAFE_INTEGER, i18n)}
|
||||||
|
/>
|
||||||
|
<FormSubmitError error={formError} />
|
||||||
|
<FormActionGroup
|
||||||
|
onCancel={handleCancel}
|
||||||
|
onSubmit={formik.handleSubmit}
|
||||||
|
/>
|
||||||
|
</FormColumnLayout>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
) : null}
|
||||||
|
</CardBody>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ManagementJobEdit;
|
export default withI18n()(ManagementJobEdit);
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { withI18n } from '@lingui/react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Button, TextInput, Tooltip } from '@patternfly/react-core';
|
||||||
|
import { RocketIcon } from '@patternfly/react-icons';
|
||||||
|
|
||||||
|
import AlertModal from '../../../components/AlertModal';
|
||||||
|
|
||||||
|
const clamp = (val, min, max) => {
|
||||||
|
if (val < min) {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
if (val > max) {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
function LaunchManagementPrompt({
|
||||||
|
i18n,
|
||||||
|
isOpen,
|
||||||
|
isLoading,
|
||||||
|
onClick,
|
||||||
|
onClose,
|
||||||
|
onConfirm,
|
||||||
|
defaultDays,
|
||||||
|
}) {
|
||||||
|
const [dataRetention, setDataRetention] = useState(defaultDays);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tooltip content={i18n._(t`Launch management job`)} position="top">
|
||||||
|
<Button
|
||||||
|
aria-label={i18n._(t`Launch management job`)}
|
||||||
|
variant="plain"
|
||||||
|
onClick={onClick}
|
||||||
|
isDisabled={isLoading}
|
||||||
|
>
|
||||||
|
<RocketIcon />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<AlertModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
variant="info"
|
||||||
|
onClose={onClose}
|
||||||
|
title={i18n._(t`Launch management job`)}
|
||||||
|
label={i18n._(t`Launch management job`)}
|
||||||
|
actions={[
|
||||||
|
<Button
|
||||||
|
id="launch-job-confirm-button"
|
||||||
|
key="delete"
|
||||||
|
variant="primary"
|
||||||
|
isDisabled={isLoading}
|
||||||
|
aria-label={i18n._(t`Launch`)}
|
||||||
|
onClick={() => onConfirm(dataRetention)}
|
||||||
|
>
|
||||||
|
{i18n._(t`Launch`)}
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
id="launch-job-cancel-button"
|
||||||
|
key="cancel"
|
||||||
|
variant="secondary"
|
||||||
|
aria-label={i18n._(t`Cancel`)}
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
{i18n._(t`Cancel`)}
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{i18n._(t`Set how many days of data should be retained.`)}
|
||||||
|
<TextInput
|
||||||
|
value={dataRetention}
|
||||||
|
type="number"
|
||||||
|
onChange={value =>
|
||||||
|
setDataRetention(clamp(value, 0, Number.MAX_SAFE_INTEGER))
|
||||||
|
}
|
||||||
|
aria-label={i18n._(t`Launch`)}
|
||||||
|
/>
|
||||||
|
</AlertModal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withI18n()(LaunchManagementPrompt);
|
||||||
@@ -91,6 +91,7 @@ function ManagementJobList({ i18n }) {
|
|||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
has_configurable_retention,
|
has_configurable_retention,
|
||||||
|
default_days,
|
||||||
}) => (
|
}) => (
|
||||||
<ManagementJobListItem
|
<ManagementJobListItem
|
||||||
key={id}
|
key={id}
|
||||||
@@ -99,6 +100,7 @@ function ManagementJobList({ i18n }) {
|
|||||||
description={description}
|
description={description}
|
||||||
isSuperUser={me?.is_superuser}
|
isSuperUser={me?.is_superuser}
|
||||||
isConfigurable={has_configurable_retention}
|
isConfigurable={has_configurable_retention}
|
||||||
|
defaultDays={default_days}
|
||||||
onLaunchError={setLaunchError}
|
onLaunchError={setLaunchError}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -11,10 +11,13 @@ import {
|
|||||||
DataListItemCells,
|
DataListItemCells,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { PencilAltIcon, RocketIcon } from '@patternfly/react-icons';
|
import { RocketIcon, PencilAltIcon } from '@patternfly/react-icons';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { SystemJobTemplatesAPI } from '../../../api';
|
import { SystemJobTemplatesAPI } from '../../../api';
|
||||||
|
import AlertModal from '../../../components/AlertModal';
|
||||||
|
import ErrorDetail from '../../../components/ErrorDetail';
|
||||||
|
import LaunchManagementPrompt from './LaunchManagementPrompt';
|
||||||
|
|
||||||
const DataListAction = styled(_DataListAction)`
|
const DataListAction = styled(_DataListAction)`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -31,6 +34,7 @@ function ManagementJobListItem({
|
|||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
|
defaultDays,
|
||||||
}) {
|
}) {
|
||||||
const detailsUrl = `/management_jobs/${id}/details`;
|
const detailsUrl = `/management_jobs/${id}/details`;
|
||||||
const editUrl = `/management_jobs/${id}/edit`;
|
const editUrl = `/management_jobs/${id}/edit`;
|
||||||
@@ -39,6 +43,28 @@ function ManagementJobListItem({
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [isLaunchLoading, setIsLaunchLoading] = useState(false);
|
const [isLaunchLoading, setIsLaunchLoading] = useState(false);
|
||||||
|
|
||||||
|
const [isManagementPromptOpen, setIsManagementPromptOpen] = useState(false);
|
||||||
|
const [isManagementPromptLoading, setIsManagementPromptLoading] = useState(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
const [managementPromptError, setManagementPromptError] = useState(null);
|
||||||
|
const handleManagementPromptClick = () => setIsManagementPromptOpen(true);
|
||||||
|
const handleManagementPromptClose = () => setIsManagementPromptOpen(false);
|
||||||
|
|
||||||
|
const handleManagementPromptConfirm = async days => {
|
||||||
|
setIsManagementPromptLoading(true);
|
||||||
|
try {
|
||||||
|
const { data } = await SystemJobTemplatesAPI.launch(id, {
|
||||||
|
extra_vars: { days },
|
||||||
|
});
|
||||||
|
history.push(`/jobs/management/${data.id}/output`);
|
||||||
|
} catch (error) {
|
||||||
|
setManagementPromptError(error);
|
||||||
|
} finally {
|
||||||
|
setIsManagementPromptLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleLaunch = async () => {
|
const handleLaunch = async () => {
|
||||||
setIsLaunchLoading(true);
|
setIsLaunchLoading(true);
|
||||||
try {
|
try {
|
||||||
@@ -52,67 +78,89 @@ function ManagementJobListItem({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataListItem key={id} id={id} aria-labelledby={labelId}>
|
<>
|
||||||
<DataListItemRow>
|
<DataListItem key={id} id={id} aria-labelledby={labelId}>
|
||||||
<DataListItemCells
|
<DataListItemRow>
|
||||||
dataListCells={[
|
<DataListItemCells
|
||||||
<DataListCell
|
dataListCells={[
|
||||||
key="name"
|
<DataListCell
|
||||||
aria-label={i18n._(t`management job name`)}
|
key="name"
|
||||||
>
|
aria-label={i18n._(t`management job name`)}
|
||||||
<Link to={detailsUrl}>
|
|
||||||
<b>{name}</b>
|
|
||||||
</Link>
|
|
||||||
</DataListCell>,
|
|
||||||
<DataListCell
|
|
||||||
key="description"
|
|
||||||
aria-label={i18n._(t`management job description`)}
|
|
||||||
>
|
|
||||||
<strong>{i18n._(t`Description:`)}</strong> {description}
|
|
||||||
</DataListCell>,
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<DataListAction
|
|
||||||
aria-label="actions"
|
|
||||||
aria-labelledby={labelId}
|
|
||||||
id={labelId}
|
|
||||||
>
|
|
||||||
{isSuperUser ? (
|
|
||||||
<>
|
|
||||||
<Tooltip
|
|
||||||
content={i18n._(t`Launch management job`)}
|
|
||||||
position="top"
|
|
||||||
>
|
>
|
||||||
<Button
|
<Link to={detailsUrl}>
|
||||||
aria-label={i18n._(t`Launch management job`)}
|
<b>{name}</b>
|
||||||
variant="plain"
|
</Link>
|
||||||
onClick={handleLaunch}
|
</DataListCell>,
|
||||||
isDisabled={isLaunchLoading}
|
<DataListCell
|
||||||
>
|
key="description"
|
||||||
<RocketIcon />
|
aria-label={i18n._(t`management job description`)}
|
||||||
</Button>
|
>
|
||||||
</Tooltip>
|
<strong>{i18n._(t`Description:`)}</strong> {description}
|
||||||
{isConfigurable ? (
|
</DataListCell>,
|
||||||
<Tooltip
|
]}
|
||||||
content={i18n._(t`Edit management job`)}
|
/>
|
||||||
position="top"
|
<DataListAction aria-labelledby={labelId} id={labelId}>
|
||||||
>
|
{isSuperUser ? (
|
||||||
<Button
|
<>
|
||||||
aria-label={i18n._(t`Edit management job`)}
|
{isConfigurable ? (
|
||||||
variant="plain"
|
<>
|
||||||
component={Link}
|
<LaunchManagementPrompt
|
||||||
to={editUrl}
|
isOpen={isManagementPromptOpen}
|
||||||
isDisabled={isLaunchLoading}
|
isLoading={isManagementPromptLoading}
|
||||||
|
onClick={handleManagementPromptClick}
|
||||||
|
onClose={handleManagementPromptClose}
|
||||||
|
onConfirm={handleManagementPromptConfirm}
|
||||||
|
defaultDays={defaultDays}
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
content={i18n._(t`Edit management job`)}
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit management job`)}
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={editUrl}
|
||||||
|
isDisabled={isLaunchLoading}
|
||||||
|
>
|
||||||
|
<PencilAltIcon />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Tooltip
|
||||||
|
content={i18n._(t`Launch management job`)}
|
||||||
|
position="top"
|
||||||
>
|
>
|
||||||
<PencilAltIcon />
|
<Button
|
||||||
</Button>
|
aria-label={i18n._(t`Launch management job`)}
|
||||||
</Tooltip>
|
variant="plain"
|
||||||
) : null}
|
onClick={handleLaunch}
|
||||||
</>
|
isDisabled={isLaunchLoading}
|
||||||
) : null}
|
>
|
||||||
</DataListAction>
|
<RocketIcon />
|
||||||
</DataListItemRow>
|
</Button>
|
||||||
</DataListItem>
|
</Tooltip>
|
||||||
|
)}{' '}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</DataListAction>
|
||||||
|
</DataListItemRow>
|
||||||
|
</DataListItem>
|
||||||
|
{managementPromptError && (
|
||||||
|
<>
|
||||||
|
<AlertModal
|
||||||
|
isOpen={managementPromptError}
|
||||||
|
variant="danger"
|
||||||
|
onClose={() => setManagementPromptError(null)}
|
||||||
|
title={i18n._(t`Management job launch error`)}
|
||||||
|
label={i18n._(t`Management job launch error`)}
|
||||||
|
>
|
||||||
|
<ErrorDetail error={managementPromptError} />
|
||||||
|
</AlertModal>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user