Disable inventory field when editing host

Disable inventory field when editing host

See: https://github.com/ansible/awx/issues/10229
This commit is contained in:
nixocio
2021-06-10 16:27:23 -04:00
committed by Shane McDonald
parent 372baa12a5
commit 04f6fe6cd2
5 changed files with 56 additions and 19 deletions

View File

@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
import { bool, func, shape } from 'prop-types'; import { bool, func, shape } from 'prop-types';
import { Formik, useField, useFormikContext } from 'formik'; import { Formik, useField, useFormikContext } from 'formik';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Form, FormGroup } from '@patternfly/react-core'; import { Form, FormGroup, Tooltip } from '@patternfly/react-core';
import FormField, { FormSubmitError } from '../FormField'; import FormField, { FormSubmitError } from '../FormField';
import FormActionGroup from '../FormActionGroup/FormActionGroup'; import FormActionGroup from '../FormActionGroup/FormActionGroup';
import { VariablesField } from '../CodeEditor'; import { VariablesField } from '../CodeEditor';
@@ -11,7 +11,7 @@ import { FormColumnLayout, FormFullWidthLayout } from '../FormLayout';
import Popover from '../Popover'; import Popover from '../Popover';
import { required } from '../../util/validators'; import { required } from '../../util/validators';
const InventoryLookupField = () => { const InventoryLookupField = ({ isDisabled }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [inventoryField, inventoryMeta, inventoryHelpers] = useField( const [inventoryField, inventoryMeta, inventoryHelpers] = useField(
'inventory' 'inventory'
@@ -25,6 +25,23 @@ const InventoryLookupField = () => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const renderInventoryLookup = (
<InventoryLookup
fieldId="inventory-lookup"
value={inventoryField.value}
onBlur={() => inventoryHelpers.setTouched()}
tooltip={t`Select the inventory that this host will belong to.`}
isValid={!inventoryMeta.touched || !inventoryMeta.error}
helperTextInvalid={inventoryMeta.error}
onChange={handleInventoryUpdate}
required
touched={inventoryMeta.touched}
error={inventoryMeta.error}
validate={required(t`Select a value for this field`)}
isDisabled={isDisabled}
/>
);
return ( return (
<FormGroup <FormGroup
label={t`Inventory`} label={t`Inventory`}
@@ -40,19 +57,13 @@ const InventoryLookupField = () => {
} }
helperTextInvalid={inventoryMeta.error} helperTextInvalid={inventoryMeta.error}
> >
<InventoryLookup {isDisabled ? (
fieldId="inventory-lookup" <Tooltip content={t`Unable to change inventory on a host`}>
value={inventoryField.value} {renderInventoryLookup}
onBlur={() => inventoryHelpers.setTouched()} </Tooltip>
tooltip={t`Select the inventory that this host will belong to.`} ) : (
isValid={!inventoryMeta.touched || !inventoryMeta.error} renderInventoryLookup
helperTextInvalid={inventoryMeta.error} )}
onChange={handleInventoryUpdate}
required
touched={inventoryMeta.touched}
error={inventoryMeta.error}
validate={required(t`Select a value for this field`)}
/>
</FormGroup> </FormGroup>
); );
}; };
@@ -63,6 +74,7 @@ const HostForm = ({
host, host,
isInventoryVisible, isInventoryVisible,
submitError, submitError,
disableInventoryLookup,
}) => { }) => {
return ( return (
<Formik <Formik
@@ -91,7 +103,9 @@ const HostForm = ({
type="text" type="text"
label={t`Description`} label={t`Description`}
/> />
{isInventoryVisible && <InventoryLookupField />} {isInventoryVisible && (
<InventoryLookupField isDisabled={disableInventoryLookup} />
)}
<FormFullWidthLayout> <FormFullWidthLayout>
<VariablesField <VariablesField
id="host-variables" id="host-variables"
@@ -117,6 +131,7 @@ HostForm.propTypes = {
host: shape({}), host: shape({}),
isInventoryVisible: bool, isInventoryVisible: bool,
submitError: shape({}), submitError: shape({}),
disableInventoryLookup: bool,
}; };
HostForm.defaultProps = { HostForm.defaultProps = {
@@ -131,6 +146,7 @@ HostForm.defaultProps = {
}, },
isInventoryVisible: true, isInventoryVisible: true,
submitError: null, submitError: null,
disableInventoryLookup: false,
}; };
export { HostForm as _HostForm }; export { HostForm as _HostForm };

View File

@@ -55,6 +55,7 @@ describe('<HostForm />', () => {
expect(wrapper.find('input#host-description').prop('value')).toEqual( expect(wrapper.find('input#host-description').prop('value')).toEqual(
'new bar' 'new bar'
); );
expect(wrapper.find('InventoryLookup').prop('isDisabled')).toEqual(false);
}); });
test('calls handleSubmit when form submitted', async () => { test('calls handleSubmit when form submitted', async () => {
@@ -84,4 +85,18 @@ describe('<HostForm />', () => {
}); });
expect(wrapper.find('InventoryLookupField').length).toBe(0); expect(wrapper.find('InventoryLookupField').length).toBe(0);
}); });
test('inventory lookup field should be disabled', async () => {
await act(async () => {
wrapper = mountWithContexts(
<HostForm
host={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
disableInventoryLookup
/>
);
});
expect(wrapper.find('InventoryLookup').prop('isDisabled')).toEqual(true);
});
}); });

View File

@@ -31,6 +31,7 @@ function InventoryLookup({
isOverrideDisabled, isOverrideDisabled,
validate, validate,
fieldName, fieldName,
isDisabled,
}) { }) {
const { const {
result: { result: {
@@ -105,7 +106,7 @@ function InventoryLookup({
label={t`Inventory`} label={t`Inventory`}
promptId={promptId} promptId={promptId}
promptName={promptName} promptName={promptName}
isDisabled={!canEdit} isDisabled={!canEdit || isDisabled}
tooltip={t`Select the inventory containing the hosts tooltip={t`Select the inventory containing the hosts
you want this job to manage.`} you want this job to manage.`}
> >
@@ -120,7 +121,7 @@ function InventoryLookup({
fieldName={fieldName} fieldName={fieldName}
validate={validate} validate={validate}
isLoading={isLoading} isLoading={isLoading}
isDisabled={!canEdit} isDisabled={!canEdit || isDisabled}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
renderOptionsList={({ state, dispatch, canDelete }) => ( renderOptionsList={({ state, dispatch, canDelete }) => (
<OptionsList <OptionsList
@@ -176,7 +177,7 @@ function InventoryLookup({
onBlur={onBlur} onBlur={onBlur}
required={required} required={required}
isLoading={isLoading} isLoading={isLoading}
isDisabled={!canEdit} isDisabled={!canEdit || isDisabled}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
renderOptionsList={({ state, dispatch, canDelete }) => ( renderOptionsList={({ state, dispatch, canDelete }) => (
<OptionsList <OptionsList
@@ -228,6 +229,7 @@ InventoryLookup.propTypes = {
isOverrideDisabled: bool, isOverrideDisabled: bool,
validate: func, validate: func,
fieldName: string, fieldName: string,
isDisabled: bool,
}; };
InventoryLookup.defaultProps = { InventoryLookup.defaultProps = {
@@ -236,6 +238,7 @@ InventoryLookup.defaultProps = {
isOverrideDisabled: false, isOverrideDisabled: false,
validate: () => {}, validate: () => {},
fieldName: 'inventory', fieldName: 'inventory',
isDisabled: false,
}; };
export default withRouter(InventoryLookup); export default withRouter(InventoryLookup);

View File

@@ -215,6 +215,7 @@ Lookup.propTypes = {
fieldName: string.isRequired, fieldName: string.isRequired,
validate: func, validate: func,
onDebounce: func, onDebounce: func,
isDisabled: bool,
}; };
Lookup.defaultProps = { Lookup.defaultProps = {
@@ -235,6 +236,7 @@ Lookup.defaultProps = {
), ),
validate: () => undefined, validate: () => undefined,
onDebounce: () => undefined, onDebounce: () => undefined,
isDisabled: false,
}; };
export { Lookup as _Lookup }; export { Lookup as _Lookup };

View File

@@ -34,6 +34,7 @@ function HostEdit({ host }) {
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
handleCancel={handleCancel} handleCancel={handleCancel}
submitError={formError} submitError={formError}
disableInventoryLookup
/> />
</CardBody> </CardBody>
); );