diff --git a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx
index b0d27ccc6e..d505049cf0 100644
--- a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx
+++ b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx
@@ -23,6 +23,7 @@ function FieldWithPrompt({
promptId,
promptName,
tooltip,
+ isDisabled,
}) {
return (
@@ -39,6 +40,7 @@ function FieldWithPrompt({
{tooltip && }
diff --git a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
index c67e0087c6..a31fd8fd7d 100644
--- a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
+++ b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
@@ -33,6 +33,7 @@ function CredentialLookup({
history,
i18n,
tooltip,
+ isDisabled,
}) {
const {
result: { count, credentials, relatedSearchableKeys, searchableKeys },
@@ -108,6 +109,7 @@ function CredentialLookup({
onChange={onChange}
required={required}
qsConfig={QS_CONFIG}
+ isDisabled={isDisabled}
renderOptionsList={({ state, dispatch, canDelete }) => (
+
+ (
+ dispatch({ type: 'SELECT_ITEM', item })}
+ deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })}
+ />
+ )}
+ />
+
+
+ >
+ ) : (
<>
1);
+ const canDelete =
+ (!required || (multiple && value.length > 1)) && !isDisabled;
let items = [];
if (multiple) {
items = value;
@@ -110,11 +111,7 @@ function Lookup(props) {
>
-
+
{items.map(item =>
renderItemChip({
diff --git a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx
index 61b1467bcf..7790989aa9 100644
--- a/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx
+++ b/awx/ui_next/src/screens/Template/JobTemplateEdit/JobTemplateEdit.test.jsx
@@ -12,6 +12,7 @@ import {
JobTemplatesAPI,
LabelsAPI,
ProjectsAPI,
+ InventoriesAPI,
} from '../../../api';
import JobTemplateEdit from './JobTemplateEdit';
@@ -181,6 +182,12 @@ JobTemplatesAPI.readCredentials.mockResolvedValue({
ProjectsAPI.readPlaybooks.mockResolvedValue({
data: mockRelatedProjectPlaybooks,
});
+InventoriesAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+});
+ProjectsAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+});
LabelsAPI.read.mockResolvedValue({ data: { results: [] } });
CredentialsAPI.read.mockResolvedValue({
data: {
diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
index c75efc036f..ae68594205 100644
--- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
+++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
@@ -234,17 +234,15 @@ function JobTemplateForm({
}}
/>
-
+ <>
inventoryHelpers.setTouched()}
onChange={value => {
inventoryHelpers.setValue(value ? value.id : null);
@@ -263,7 +261,7 @@ function JobTemplateForm({
{inventoryMeta.error}
)}
-
+ >
projectHelpers.setTouched()}
diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx
index a373fefe37..f6c6c3e486 100644
--- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx
+++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.test.jsx
@@ -14,6 +14,7 @@ import {
ProjectsAPI,
CredentialsAPI,
CredentialTypesAPI,
+ InventoriesAPI,
} from '../../../api';
jest.mock('../../../api');
@@ -111,14 +112,23 @@ describe('', () => {
JobTemplatesAPI.updateWebhookKey.mockReturnValue({
data: { webhook_key: 'webhook key' },
});
- ProjectsAPI.readPlaybooks.mockReturnValue({
- data: ['debug.yml'],
+ JobTemplatesAPI.updateWebhookKey.mockReturnValue({
+ data: { webhook_key: 'webhook key' },
});
ProjectsAPI.readDetail.mockReturnValue({
name: 'foo',
id: 1,
allow_override: true,
});
+ ProjectsAPI.readPlaybooks.mockReturnValue({
+ data: ['debug.yml'],
+ });
+ InventoriesAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+ });
+ ProjectsAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+ });
});
afterEach(() => {
diff --git a/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx b/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx
index 83dfc590af..5a66cc0a78 100644
--- a/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx
+++ b/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx
@@ -35,7 +35,7 @@ function PlaybookSelect({ projectId, isValid, field, onBlur, onError, i18n }) {
});
return opts;
}, [projectId, i18n]),
- [field.value]
+ []
);
useEffect(() => {
diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx
index 4ea77786f9..bb13418aac 100644
--- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx
+++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx
@@ -110,23 +110,21 @@ function WorkflowJobTemplateForm({
value={organizationField.value}
isValid={!organizationMeta.error}
/>
-
-
+ <>
inventoryHelpers.setTouched()}
onChange={value => {
inventoryHelpers.setValue(value);
}}
- required={askInventoryOnLaunchField.value}
+ required={!askInventoryOnLaunchField.value}
touched={inventoryMeta.touched}
error={inventoryMeta.error}
/>
@@ -139,8 +137,7 @@ function WorkflowJobTemplateForm({
{inventoryMeta.error}
)}
-
-
+ >
', () => {
let wrapper;
@@ -71,6 +75,15 @@ describe('', () => {
{ id: 2, name: 'Bar' },
],
});
+ CredentialTypesAPI.read.mockResolvedValue({
+ data: { results: [{ id: 1 }] },
+ });
+ InventoriesAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+ });
+ ProjectsAPI.readOptions.mockResolvedValue({
+ data: { actions: { GET: {}, POST: {} } },
+ });
history = createMemoryHistory({
initialEntries: ['/templates/workflow_job_template/6/edit'],