diff --git a/awx/ui/src/components/Lookup/InventoryLookup.js b/awx/ui/src/components/Lookup/InventoryLookup.js index 04f7e522df..e37805451d 100644 --- a/awx/ui/src/components/Lookup/InventoryLookup.js +++ b/awx/ui/src/components/Lookup/InventoryLookup.js @@ -26,7 +26,6 @@ function InventoryLookup({ hideSmartInventories, history, isDisabled, - isOverrideDisabled, isPromptableField, onBlur, onChange, @@ -39,13 +38,7 @@ function InventoryLookup({ const autoPopulateLookup = useAutoPopulateLookup(onChange); const { - result: { - inventories, - count, - relatedSearchableKeys, - searchableKeys, - canEdit, - }, + result: { inventories, count, relatedSearchableKeys, searchableKeys }, request: fetchInventories, error, isLoading, @@ -85,8 +78,6 @@ function InventoryLookup({ key, type: actionsResponse.data.actions?.GET[key].type, })), - canEdit: - Boolean(actionsResponse.data.actions.POST) || isOverrideDisabled, }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [autoPopulate, autoPopulateLookup, history.location]), @@ -95,7 +86,6 @@ function InventoryLookup({ count: 0, relatedSearchableKeys: [], searchableKeys: [], - canEdit: false, } ); @@ -129,7 +119,7 @@ function InventoryLookup({ label={t`Inventory`} promptId={promptId} promptName={promptName} - isDisabled={!canEdit || isDisabled} + isDisabled={isDisabled} tooltip={t`Select the inventory containing the hosts you want this job to manage.`} > @@ -145,7 +135,7 @@ function InventoryLookup({ fieldName={fieldName} validate={validate} isLoading={isLoading} - isDisabled={!canEdit || isDisabled} + isDisabled={isDisabled} qsConfig={QS_CONFIG} renderOptionsList={({ state, dispatch, canDelete }) => ( ( {}, value: null, diff --git a/awx/ui/src/components/Lookup/InventoryLookup.test.js b/awx/ui/src/components/Lookup/InventoryLookup.test.js index 7c20846d32..120b4927e9 100644 --- a/awx/ui/src/components/Lookup/InventoryLookup.test.js +++ b/awx/ui/src/components/Lookup/InventoryLookup.test.js @@ -99,7 +99,7 @@ describe('InventoryLookup', () => { await act(async () => { wrapper = mountWithContexts( - {}} /> + {}} /> ); }); @@ -121,7 +121,7 @@ describe('InventoryLookup', () => { await act(async () => { wrapper = mountWithContexts( - {}} /> + {}} /> ); }); diff --git a/awx/ui/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.js b/awx/ui/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.js index 6357f4adf2..d4929ec663 100644 --- a/awx/ui/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.js +++ b/awx/ui/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.js @@ -3,7 +3,12 @@ import { useHistory } from 'react-router-dom'; import { CardBody } from 'components/Card'; import { getAddedAndRemoved } from 'util/lists'; -import { WorkflowJobTemplatesAPI, OrganizationsAPI, UsersAPI } from 'api'; +import { + InventoriesAPI, + WorkflowJobTemplatesAPI, + OrganizationsAPI, + UsersAPI, +} from 'api'; import { useConfig } from 'contexts/Config'; import useRequest from 'hooks/useRequest'; import ContentError from 'components/ContentError'; @@ -80,15 +85,16 @@ function WorkflowJobTemplateEdit({ template }) { }; const { - isLoading, + isLoading: isFetchUserRoleLoading, request: fetchUserRole, result: { orgAdminResults, isOrgAdmin }, - error: contentError, + error: fetchUserRoleError, } = useRequest( useCallback(async () => { const { data: { results, count }, } = await UsersAPI.readAdminOfOrganizations(me?.id); + return { isOrgAdmin: count > 0, orgAdminResults: results }; }, [me.id]), { isOrgAdmin: false, orgAdminResults: null } @@ -98,11 +104,37 @@ function WorkflowJobTemplateEdit({ template }) { fetchUserRole(); }, [fetchUserRole]); - if (contentError) { - return ; + const { + isLoading: isFetchInventoryLoading, + request: fetchInventory, + result: { canChangeInventory }, + error: fetchInventoryError, + } = useRequest( + useCallback(async () => { + if (template.inventory) { + const { + data: { count }, + } = await InventoriesAPI.read({ + role_level: 'use_role', + id: template.inventory, + }); + return { canChangeInventory: count && count > 0 }; + } + + return { canChangeInventory: true }; + }, [template.inventory]), + { canChangeInventory: false } + ); + + useEffect(() => { + fetchInventory(); + }, [fetchInventory]); + + if (fetchUserRoleError || fetchInventoryError) { + return ; } - if (isLoading || !orgAdminResults) { + if (isFetchUserRoleLoading || isFetchInventoryLoading || !orgAdminResults) { return ; } @@ -114,6 +146,7 @@ function WorkflowJobTemplateEdit({ template }) { template={template} submitError={formSubmitError} isOrgAdmin={isOrgAdmin} + isInventoryDisabled={!canChangeInventory} /> ); diff --git a/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js b/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js index 9d974f3105..70146b2889 100644 --- a/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js +++ b/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js @@ -39,6 +39,7 @@ function WorkflowJobTemplateForm({ handleCancel, submitError, isOrgAdmin, + isInventoryDisabled, }) { const helpText = getHelpText(); const { setFieldValue, setFieldTouched } = useFormikContext(); @@ -150,6 +151,7 @@ function WorkflowJobTemplateForm({ onChange={handleInventoryUpdate} touched={inventoryMeta.touched} error={inventoryMeta.error} + isDisabled={isInventoryDisabled} />