mirror of
https://github.com/ansible/awx.git
synced 2026-03-10 14:09:28 -02:30
Merge pull request #11216 from AlexSCorey/11214-DisableDefaultInstanceDelete
Disable default instance delete
This commit is contained in:
@@ -31,24 +31,29 @@ function InstanceGroup({ setBreadcrumb }) {
|
|||||||
isLoading,
|
isLoading,
|
||||||
error: contentError,
|
error: contentError,
|
||||||
request: fetchInstanceGroups,
|
request: fetchInstanceGroups,
|
||||||
result: { instanceGroup, defaultControlPlane },
|
result: { instanceGroup, defaultControlPlane, defaultExecution },
|
||||||
} = useRequest(
|
} = useRequest(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const [
|
const [
|
||||||
{ data },
|
{ data },
|
||||||
{
|
{
|
||||||
data: { DEFAULT_CONTROL_PLANE_QUEUE_NAME },
|
data: {
|
||||||
|
DEFAULT_CONTROL_PLANE_QUEUE_NAME,
|
||||||
|
DEFAULT_EXECUTION_QUEUE_NAME,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
InstanceGroupsAPI.readDetail(id),
|
InstanceGroupsAPI.readDetail(id),
|
||||||
SettingsAPI.readAll(),
|
SettingsAPI.readAll(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
instanceGroup: data,
|
instanceGroup: data,
|
||||||
defaultControlPlane: DEFAULT_CONTROL_PLANE_QUEUE_NAME,
|
defaultControlPlane: DEFAULT_CONTROL_PLANE_QUEUE_NAME,
|
||||||
|
defaultExecution: DEFAULT_EXECUTION_QUEUE_NAME,
|
||||||
};
|
};
|
||||||
}, [id]),
|
}, [id]),
|
||||||
{ instanceGroup: null, defaultControlPlane: '' }
|
{ instanceGroup: null, defaultControlPlane: '', defaultExecution: '' }
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -130,11 +135,13 @@ function InstanceGroup({ setBreadcrumb }) {
|
|||||||
<Route path="/instance_groups/:id/edit">
|
<Route path="/instance_groups/:id/edit">
|
||||||
<InstanceGroupEdit
|
<InstanceGroupEdit
|
||||||
instanceGroup={instanceGroup}
|
instanceGroup={instanceGroup}
|
||||||
|
defaultExecution={defaultExecution}
|
||||||
defaultControlPlane={defaultControlPlane}
|
defaultControlPlane={defaultControlPlane}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/instance_groups/:id/details">
|
<Route path="/instance_groups/:id/details">
|
||||||
<InstanceGroupDetails
|
<InstanceGroupDetails
|
||||||
|
defaultExecution={defaultExecution}
|
||||||
defaultControlPlane={defaultControlPlane}
|
defaultControlPlane={defaultControlPlane}
|
||||||
instanceGroup={instanceGroup}
|
instanceGroup={instanceGroup}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ const Unavailable = styled.span`
|
|||||||
color: var(--pf-global--danger-color--200);
|
color: var(--pf-global--danger-color--200);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function InstanceGroupDetails({ instanceGroup, defaultControlPlane }) {
|
function InstanceGroupDetails({
|
||||||
|
instanceGroup,
|
||||||
|
defaultControlPlane,
|
||||||
|
defaultExecution,
|
||||||
|
}) {
|
||||||
const { id, name } = instanceGroup;
|
const { id, name } = instanceGroup;
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -42,7 +46,8 @@ function InstanceGroupDetails({ instanceGroup, defaultControlPlane }) {
|
|||||||
const { error, dismissError } = useDismissableError(deleteError);
|
const { error, dismissError } = useDismissableError(deleteError);
|
||||||
const deleteDetailsRequests =
|
const deleteDetailsRequests =
|
||||||
relatedResourceDeleteRequests.instanceGroup(instanceGroup);
|
relatedResourceDeleteRequests.instanceGroup(instanceGroup);
|
||||||
|
const isDefaultInstanceGroup =
|
||||||
|
name === defaultControlPlane || name === defaultExecution;
|
||||||
return (
|
return (
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<DetailList>
|
<DetailList>
|
||||||
@@ -110,7 +115,7 @@ function InstanceGroupDetails({ instanceGroup, defaultControlPlane }) {
|
|||||||
{t`Edit`}
|
{t`Edit`}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{name !== defaultControlPlane &&
|
{!isDefaultInstanceGroup &&
|
||||||
instanceGroup.summary_fields.user_capabilities &&
|
instanceGroup.summary_fields.user_capabilities &&
|
||||||
instanceGroup.summary_fields.user_capabilities.delete && (
|
instanceGroup.summary_fields.user_capabilities.delete && (
|
||||||
<DeleteButton
|
<DeleteButton
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import { CardBody } from 'components/Card';
|
|||||||
import { InstanceGroupsAPI } from 'api';
|
import { InstanceGroupsAPI } from 'api';
|
||||||
import InstanceGroupForm from '../shared/InstanceGroupForm';
|
import InstanceGroupForm from '../shared/InstanceGroupForm';
|
||||||
|
|
||||||
function InstanceGroupEdit({ instanceGroup, defaultControlPlane }) {
|
function InstanceGroupEdit({
|
||||||
|
instanceGroup,
|
||||||
|
defaultControlPlane,
|
||||||
|
defaultExecution,
|
||||||
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [submitError, setSubmitError] = useState(null);
|
const [submitError, setSubmitError] = useState(null);
|
||||||
const detailsUrl = `/instance_groups/${instanceGroup.id}/details`;
|
const detailsUrl = `/instance_groups/${instanceGroup.id}/details`;
|
||||||
@@ -28,6 +32,7 @@ function InstanceGroupEdit({ instanceGroup, defaultControlPlane }) {
|
|||||||
<InstanceGroupForm
|
<InstanceGroupForm
|
||||||
instanceGroup={instanceGroup}
|
instanceGroup={instanceGroup}
|
||||||
defaultControlPlane={defaultControlPlane}
|
defaultControlPlane={defaultControlPlane}
|
||||||
|
defaultExecution={defaultExecution}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
submitError={submitError}
|
submitError={submitError}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -3,27 +3,42 @@ import { func, shape } from 'prop-types';
|
|||||||
import { Formik, useField } from 'formik';
|
import { Formik, useField } from 'formik';
|
||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Form } from '@patternfly/react-core';
|
import { Form, Tooltip } from '@patternfly/react-core';
|
||||||
|
|
||||||
import FormField, { FormSubmitError } from 'components/FormField';
|
import FormField, { FormSubmitError } from 'components/FormField';
|
||||||
import FormActionGroup from 'components/FormActionGroup';
|
import FormActionGroup from 'components/FormActionGroup';
|
||||||
import { required, minMaxValue } from 'util/validators';
|
import { required, minMaxValue } from 'util/validators';
|
||||||
import { FormColumnLayout } from 'components/FormLayout';
|
import { FormColumnLayout } from 'components/FormLayout';
|
||||||
|
|
||||||
function InstanceGroupFormFields({ defaultControlPlane }) {
|
function InstanceGroupFormFields({ defaultControlPlane, defaultExecution }) {
|
||||||
const [instanceGroupNameField, ,] = useField('name');
|
const [{ value }, ,] = useField('name');
|
||||||
|
const isDisabled =
|
||||||
|
value === defaultExecution || value === defaultControlPlane;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
{isDisabled ? (
|
||||||
name="name"
|
<Tooltip content={t`Name cannot be changed on this Instance Group`}>
|
||||||
id="instance-group-name"
|
<FormField
|
||||||
label={t`Name`}
|
name="name"
|
||||||
type="text"
|
id="instance-group-name"
|
||||||
validate={required(null)}
|
label={t`Name`}
|
||||||
isRequired
|
type="text"
|
||||||
isDisabled={instanceGroupNameField.value === defaultControlPlane}
|
validate={required(null)}
|
||||||
/>
|
isRequired
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<FormField
|
||||||
|
name="name"
|
||||||
|
id="instance-group-name"
|
||||||
|
label={t`Name`}
|
||||||
|
type="text"
|
||||||
|
validate={required(null)}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<FormField
|
<FormField
|
||||||
id="instance-group-policy-instance-minimum"
|
id="instance-group-policy-instance-minimum"
|
||||||
label={t`Policy instance minimum`}
|
label={t`Policy instance minimum`}
|
||||||
|
|||||||
@@ -116,4 +116,44 @@ describe('<InstanceGroupForm/>', () => {
|
|||||||
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
|
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
|
||||||
expect(onCancel).toBeCalled();
|
expect(onCancel).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Name field should be disabled, default', async () => {
|
||||||
|
let defaultInstanceGroupWrapper;
|
||||||
|
await act(async () => {
|
||||||
|
defaultInstanceGroupWrapper = mountWithContexts(
|
||||||
|
<InstanceGroupForm
|
||||||
|
onCancel={onCancel}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
defaultControlPlane="controlplane"
|
||||||
|
defaultExecution="default"
|
||||||
|
instanceGroup={{ ...instanceGroup, name: 'default' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
defaultInstanceGroupWrapper
|
||||||
|
.find('TextInput[name="name"]')
|
||||||
|
.prop('isDisabled')
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Name field should be disabled, controlplane', async () => {
|
||||||
|
let defaultInstanceGroupWrapper;
|
||||||
|
await act(async () => {
|
||||||
|
defaultInstanceGroupWrapper = mountWithContexts(
|
||||||
|
<InstanceGroupForm
|
||||||
|
onCancel={onCancel}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
defaultControlPlane="controlplane"
|
||||||
|
defaultExecution="default"
|
||||||
|
instanceGroup={{ ...instanceGroup, name: 'controlplane' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
defaultInstanceGroupWrapper
|
||||||
|
.find('TextInput[name="name"]')
|
||||||
|
.prop('isDisabled')
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user