diff --git a/awx/ui_next/src/components/JobList/JobList.jsx b/awx/ui_next/src/components/JobList/JobList.jsx
index c08401acbc..ead8916fe8 100644
--- a/awx/ui_next/src/components/JobList/JobList.jsx
+++ b/awx/ui_next/src/components/JobList/JobList.jsx
@@ -122,7 +122,7 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ type, id }) => {
switch (type) {
diff --git a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.jsx b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.jsx
index 2afeefde7e..4568c477e4 100644
--- a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.jsx
+++ b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.jsx
@@ -66,7 +66,7 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
if (typeof deletionRole.team_id !== 'undefined') {
return TeamsAPI.disassociateRole(deletionRole.team_id, deletionRole.id);
}
diff --git a/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.jsx b/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.jsx
index 8cd20a4759..e6874b65a5 100644
--- a/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.jsx
+++ b/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.jsx
@@ -4,7 +4,7 @@ import { t } from '@lingui/macro';
import { Link, useHistory } from 'react-router-dom';
import { Button } from '@patternfly/react-core';
-import { useDeleteItems } from '../../../util/useRequest';
+import useRequest, { useDismissableError } from '../../../util/useRequest';
import AlertModal from '../../../components/AlertModal';
import { CardBody, CardActionsRow } from '../../../components/Card';
import { Detail, DetailList } from '../../../components/DetailList';
@@ -21,16 +21,17 @@ function ApplicationDetails({
const history = useHistory();
const {
isLoading: deleteLoading,
- deletionError,
- deleteItems: handleDeleteApplications,
- clearDeletionError,
- } = useDeleteItems(
+ error: deletionError,
+ request: deleteApplications,
+ } = useRequest(
useCallback(async () => {
await ApplicationsAPI.destroy(application.id);
history.push('/applications');
}, [application.id, history])
);
+ const { error, dismissError } = useDismissableError(deletionError);
+
const getAuthorizationGrantType = type => {
let value;
authorizationOptions.filter(option => {
@@ -104,22 +105,22 @@ function ApplicationDetails({
{i18n._(t`Delete`)}
)}
- {deletionError && (
+ {error && (
{i18n._(t`Failed to delete application.`)}
-
+
)}
diff --git a/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.test.jsx b/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.test.jsx
index 8c6339c78d..27fdb5f2f4 100644
--- a/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.test.jsx
+++ b/awx/ui_next/src/screens/Application/ApplicationDetails/ApplicationDetails.test.jsx
@@ -1,5 +1,6 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
+import { createMemoryHistory } from 'history';
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import { ApplicationsAPI } from '../../../api';
@@ -126,21 +127,27 @@ describe('', () => {
});
test('should delete properly', async () => {
- ApplicationsAPI.destroy.mockResolvedValue({ data: {} });
+ const history = createMemoryHistory({
+ initialEntries: ['/applications/1/details'],
+ });
await act(async () => {
wrapper = mountWithContexts(
+ />,
+ {
+ context: { router: { history } },
+ }
);
});
- await act(async () =>
- wrapper.find('Button[aria-label="Delete"]').prop('onClick')()
- );
- wrapper.update();
- await act(async () => wrapper.find('DeleteButton').prop('onConfirm')());
+ expect(history.location.pathname).toEqual('/applications/1/details');
+ await act(async () => {
+ wrapper.find('DeleteButton').invoke('onConfirm')();
+ });
+ expect(ApplicationsAPI.destroy).toHaveBeenCalledTimes(1);
+ expect(history.location.pathname).toBe('/applications');
expect(ApplicationsAPI.destroy).toBeCalledWith(10);
});
diff --git a/awx/ui_next/src/screens/Application/ApplicationTokens/ApplicationTokenList.jsx b/awx/ui_next/src/screens/Application/ApplicationTokens/ApplicationTokenList.jsx
index 2ad56eaa7f..018829623d 100644
--- a/awx/ui_next/src/screens/Application/ApplicationTokens/ApplicationTokenList.jsx
+++ b/awx/ui_next/src/screens/Application/ApplicationTokens/ApplicationTokenList.jsx
@@ -76,8 +76,8 @@ function ApplicationTokenList({ i18n }) {
deleteItems: handleDeleteApplications,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
- await Promise.all(
+ useCallback(() => {
+ return Promise.all(
selected.map(({ id: tokenId }) => TokensAPI.destroy(tokenId))
);
}, [selected]),
diff --git a/awx/ui_next/src/screens/Application/ApplicationsList/ApplicationsList.jsx b/awx/ui_next/src/screens/Application/ApplicationsList/ApplicationsList.jsx
index 28cad08057..b35ecc7d68 100644
--- a/awx/ui_next/src/screens/Application/ApplicationsList/ApplicationsList.jsx
+++ b/awx/ui_next/src/screens/Application/ApplicationsList/ApplicationsList.jsx
@@ -80,11 +80,11 @@ function ApplicationsList({ i18n }) {
const {
isLoading: deleteLoading,
deletionError,
- deleteItems: handleDeleteApplications,
+ deleteItems: deleteApplications,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
- await Promise.all(selected.map(({ id }) => ApplicationsAPI.destroy(id)));
+ useCallback(() => {
+ return Promise.all(selected.map(({ id }) => ApplicationsAPI.destroy(id)));
}, [selected]),
{
qsConfig: QS_CONFIG,
@@ -93,8 +93,8 @@ function ApplicationsList({ i18n }) {
}
);
- const handleDelete = async () => {
- await handleDeleteApplications();
+ const handleDeleteApplications = async () => {
+ await deleteApplications();
setSelected([]);
};
@@ -163,7 +163,7 @@ function ApplicationsList({ i18n }) {
: []),
,
diff --git a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
index 0e2ea6fab0..26272ee4ad 100644
--- a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
+++ b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
@@ -62,7 +62,7 @@ function CredentialList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(({ id }) => CredentialsAPI.destroy(id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx b/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx
index 188f78cdd1..e22112e9ba 100644
--- a/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx
+++ b/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx
@@ -83,8 +83,8 @@ function CredentialTypeList({ i18n }) {
deleteItems: deleteCredentialTypes,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
- await Promise.all(
+ useCallback(() => {
+ return Promise.all(
selected.map(({ id }) => CredentialTypesAPI.destroy(id))
);
}, [selected]),
diff --git a/awx/ui_next/src/screens/Dashboard/shared/DashboardTemplateList.jsx b/awx/ui_next/src/screens/Dashboard/shared/DashboardTemplateList.jsx
index 91e9ad5326..05d4cd3ab2 100644
--- a/awx/ui_next/src/screens/Dashboard/shared/DashboardTemplateList.jsx
+++ b/awx/ui_next/src/screens/Dashboard/shared/DashboardTemplateList.jsx
@@ -99,7 +99,7 @@ function DashboardTemplateList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ type, id }) => {
if (type === 'job_template') {
diff --git a/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.jsx b/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.jsx
index f902b5e0a6..3cb8974d2a 100644
--- a/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.jsx
+++ b/awx/ui_next/src/screens/Host/HostGroups/HostGroupsList.jsx
@@ -91,7 +91,7 @@ function HostGroupsList({ i18n, host }) {
deleteItems: disassociateHosts,
deletionError: disassociateError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(group => HostsAPI.disassociateGroup(hostId, group))
);
diff --git a/awx/ui_next/src/screens/Host/HostList/HostList.jsx b/awx/ui_next/src/screens/Host/HostList/HostList.jsx
index c801fe8c6e..1f5e0833bf 100644
--- a/awx/ui_next/src/screens/Host/HostList/HostList.jsx
+++ b/awx/ui_next/src/screens/Host/HostList/HostList.jsx
@@ -72,7 +72,7 @@ function HostList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(host => HostsAPI.destroy(host.id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx
index ca4aed2feb..5e56d18f73 100644
--- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx
+++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx
@@ -102,8 +102,8 @@ function InstanceGroupList({ i18n }) {
deleteItems: deleteInstanceGroups,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
- await Promise.all(
+ useCallback(() => {
+ return Promise.all(
selected.map(({ id }) => InstanceGroupsAPI.destroy(id))
);
}, [selected]),
diff --git a/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.jsx b/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.jsx
index f666cecd27..ba89d888f7 100644
--- a/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.jsx
+++ b/awx/ui_next/src/screens/InstanceGroup/Instances/InstanceList.jsx
@@ -86,7 +86,7 @@ function InstanceList({ i18n }) {
deleteItems: disassociateInstances,
deletionError: disassociateError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(instance =>
InstanceGroupsAPI.disassociateInstance(instanceGroupId, instance.id)
diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx
index 707fb0130c..1215413c3d 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx
@@ -85,7 +85,7 @@ function InventoryGroupHostList({ i18n }) {
deleteItems: disassociateHosts,
deletionError: disassociateErr,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(host => GroupsAPI.disassociateHost(groupId, host))
);
diff --git a/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.jsx b/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.jsx
index 74d929d779..d3efe96c08 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryHostGroups/InventoryHostGroupsList.jsx
@@ -90,7 +90,7 @@ function InventoryHostGroupsList({ i18n }) {
deleteItems: disassociateHosts,
deletionError: disassociateError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(group => HostsAPI.disassociateGroup(hostId, group))
);
diff --git a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostList.jsx b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostList.jsx
index fbee9ae6d5..f66d218264 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostList.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryHosts/InventoryHostList.jsx
@@ -87,12 +87,17 @@ function InventoryHostList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
- await Promise.all(selected.map(host => HostsAPI.destroy(host.id)));
+ useCallback(() => {
+ return Promise.all(selected.map(host => HostsAPI.destroy(host.id)));
}, [selected]),
{ qsConfig: QS_CONFIG, fetchItems: fetchData }
);
+ const handleDeleteHosts = async () => {
+ await deleteHosts();
+ setSelected([]);
+ };
+
const canAdd =
actions && Object.prototype.hasOwnProperty.call(actions, 'POST');
const isAllSelected = selected.length > 0 && selected.length === hosts.length;
@@ -150,7 +155,7 @@ function InventoryHostList({ i18n }) {
/>,
,
diff --git a/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx b/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx
index 0bd51ca380..6bb721a427 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryList/InventoryList.jsx
@@ -95,7 +95,7 @@ function InventoryList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(team => InventoriesAPI.destroy(team.id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceList.jsx b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceList.jsx
index 84048f450a..13f0d79f77 100644
--- a/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceList.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventorySources/InventorySourceList.jsx
@@ -89,7 +89,7 @@ function InventorySourceList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ id: sourceId }) =>
InventorySourcesAPI.destroy(sourceId)
diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx
index 96bad47c5d..8e06cfbd24 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplateList/NotificationTemplateList.jsx
@@ -67,7 +67,7 @@ function NotificationTemplatesList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ id }) => NotificationTemplatesAPI.destroy(id))
);
diff --git a/awx/ui_next/src/screens/Organization/OrganizationList/OrganizationList.jsx b/awx/ui_next/src/screens/Organization/OrganizationList/OrganizationList.jsx
index ee20fb1eb2..9b4dca7413 100644
--- a/awx/ui_next/src/screens/Organization/OrganizationList/OrganizationList.jsx
+++ b/awx/ui_next/src/screens/Organization/OrganizationList/OrganizationList.jsx
@@ -81,7 +81,7 @@ function OrganizationsList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ id }) => OrganizationsAPI.destroy(id))
);
diff --git a/awx/ui_next/src/screens/Project/ProjectJobTemplatesList/ProjectJobTemplatesList.jsx b/awx/ui_next/src/screens/Project/ProjectJobTemplatesList/ProjectJobTemplatesList.jsx
index f22c393866..58d53341aa 100644
--- a/awx/ui_next/src/screens/Project/ProjectJobTemplatesList/ProjectJobTemplatesList.jsx
+++ b/awx/ui_next/src/screens/Project/ProjectJobTemplatesList/ProjectJobTemplatesList.jsx
@@ -80,7 +80,7 @@ function ProjectJobTemplatesList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(template => JobTemplatesAPI.destroy(template.id))
);
diff --git a/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx b/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx
index 659c600e1d..0fff5472da 100644
--- a/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx
+++ b/awx/ui_next/src/screens/Project/ProjectList/ProjectList.jsx
@@ -82,7 +82,7 @@ function ProjectList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(({ id }) => ProjectsAPI.destroy(id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx b/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx
index f7889df2b4..e128e9890a 100644
--- a/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx
+++ b/awx/ui_next/src/screens/Team/TeamList/TeamList.jsx
@@ -78,7 +78,7 @@ function TeamList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(team => TeamsAPI.destroy(team.id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/Template/TemplateList/TemplateList.jsx b/awx/ui_next/src/screens/Template/TemplateList/TemplateList.jsx
index d2d242450d..961178bf54 100644
--- a/awx/ui_next/src/screens/Template/TemplateList/TemplateList.jsx
+++ b/awx/ui_next/src/screens/Template/TemplateList/TemplateList.jsx
@@ -91,7 +91,7 @@ function TemplateList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ type, id }) => {
if (type === 'job_template') {
diff --git a/awx/ui_next/src/screens/User/UserList/UserList.jsx b/awx/ui_next/src/screens/User/UserList/UserList.jsx
index a0dfdc18de..635073acc6 100644
--- a/awx/ui_next/src/screens/User/UserList/UserList.jsx
+++ b/awx/ui_next/src/screens/User/UserList/UserList.jsx
@@ -79,7 +79,7 @@ function UserList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.map(user => UsersAPI.destroy(user.id)));
}, [selected]),
{
diff --git a/awx/ui_next/src/screens/User/UserTeams/UserTeamList.jsx b/awx/ui_next/src/screens/User/UserTeams/UserTeamList.jsx
index b8085905b6..df47f1c783 100644
--- a/awx/ui_next/src/screens/User/UserTeams/UserTeamList.jsx
+++ b/awx/ui_next/src/screens/User/UserTeams/UserTeamList.jsx
@@ -110,7 +110,7 @@ function UserTeamList({ i18n }) {
deleteItems: disassociateTeams,
deletionError: disassociateError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(selected.flatMap(team => disassociateUserRoles(team)));
/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [selected]),
diff --git a/awx/ui_next/src/screens/User/UserTokenList/UserTokenList.jsx b/awx/ui_next/src/screens/User/UserTokenList/UserTokenList.jsx
index 4427b4c886..a60f4412b6 100644
--- a/awx/ui_next/src/screens/User/UserTokenList/UserTokenList.jsx
+++ b/awx/ui_next/src/screens/User/UserTokenList/UserTokenList.jsx
@@ -78,7 +78,7 @@ function UserTokenList({ i18n }) {
deletionError,
clearDeletionError,
} = useDeleteItems(
- useCallback(async () => {
+ useCallback(() => {
return Promise.all(
selected.map(({ id: tokenId }) => TokensAPI.destroy(tokenId))
);