diff --git a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
index c3ef0ebff5..cec7e309fe 100644
--- a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
+++ b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useCallback } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@@ -11,6 +11,7 @@ import PaginatedDataList, {
ToolbarAddButton,
ToolbarDeleteButton,
} from '@components/PaginatedDataList';
+import useRequest from '@util/useRequest';
import {
getQSConfig,
parseQueryString,
@@ -26,53 +27,74 @@ const QS_CONFIG = getQSConfig('credential', {
});
function CredentialList({ i18n }) {
- const [actions, setActions] = useState(null);
- const [contentError, setContentError] = useState(null);
- const [credentialCount, setCredentialCount] = useState(0);
- const [credentials, setCredentials] = useState([]);
- const [deletionError, setDeletionError] = useState(null);
- const [hasContentLoading, setHasContentLoading] = useState(true);
+ const [showDeletionError, setShowDeletionError] = useState(false);
const [selected, setSelected] = useState([]);
const location = useLocation();
const history = useHistory();
- const loadCredentials = async ({ search }) => {
- const params = parseQueryString(QS_CONFIG, search);
- setContentError(null);
- setHasContentLoading(true);
- try {
- const [
- {
- data: { count, results },
- },
- {
- data: { actions: optionActions },
- },
- ] = await Promise.all([
+ const {
+ result: { credentials, credentialCount, actions },
+ error: contentError,
+ isLoading,
+ request: fetchCredentials,
+ } = useRequest(
+ useCallback(async () => {
+ const params = parseQueryString(QS_CONFIG, location.search);
+ const [creds, credActions] = await Promise.all([
CredentialsAPI.read(params),
- loadCredentialActions(),
+ CredentialsAPI.readOptions(),
]);
-
- setCredentials(results);
- setCredentialCount(count);
- setActions(optionActions);
- } catch (error) {
- setContentError(error);
- } finally {
- setHasContentLoading(false);
+ return {
+ credentials: creds.data.results,
+ credentialCount: creds.data.count,
+ actions: credActions.data.actions,
+ };
+ }, [location]),
+ {
+ credentials: [],
+ credentialCount: 0,
+ actions: {},
}
- };
+ );
useEffect(() => {
- loadCredentials(location);
- }, [location]); // eslint-disable-line react-hooks/exhaustive-deps
+ fetchCredentials();
+ }, [fetchCredentials]);
- const loadCredentialActions = () => {
- if (actions) {
- return Promise.resolve({ data: { actions } });
+ const {
+ isLoading: isDeleteLoading,
+ error: deletionError,
+ request: deleteCredentials,
+ } = useRequest(
+ useCallback(async () => {
+ return Promise.all(selected.map(({ id }) => CredentialsAPI.destroy(id)));
+ }, [selected])
+ );
+
+ useEffect(() => {
+ if (deletionError) {
+ setShowDeletionError(true);
+ }
+ }, [deletionError]);
+
+ const handleDelete = async () => {
+ await deleteCredentials();
+ adjustPagination();
+ setSelected([]);
+ };
+
+ const adjustPagination = () => {
+ const params = parseQueryString(QS_CONFIG, location.search);
+ if (params.page > 1 && selected.length === credentials.length) {
+ const newParams = encodeNonDefaultQueryString(
+ QS_CONFIG,
+ replaceParams(params, { page: params.page - 1 })
+ );
+ history.push(`${location.pathname}?${newParams}`);
+ } else {
+ fetchCredentials();
}
- return CredentialsAPI.readOptions();
};
const handleSelectAll = isSelected => {
@@ -87,34 +109,6 @@ function CredentialList({ i18n }) {
}
};
- const handleDelete = async () => {
- setHasContentLoading(true);
-
- try {
- await Promise.all(
- selected.map(credential => CredentialsAPI.destroy(credential.id))
- );
- } catch (error) {
- setDeletionError(error);
- }
-
- adjustPagination();
- setSelected([]);
- };
-
- const adjustPagination = () => {
- const params = parseQueryString(QS_CONFIG, location.search);
- if (params.page > 1 && selected.length === credentials.length) {
- const newParams = encodeNonDefaultQueryString(
- QS_CONFIG,
- replaceParams(params, { page: params.page - 1 })
- );
- history.push(`${location.pathname}?${newParams}`);
- } else {
- loadCredentials(location);
- }
- };
-
const canAdd =
actions && Object.prototype.hasOwnProperty.call(actions, 'POST');
const isAllSelected =
@@ -125,7 +119,7 @@ function CredentialList({ i18n }) {
setDeletionError(null)}
+ onClose={() => setShowDeletionError(false)}
>
{i18n._(t`Failed to delete one or more credentials.`)}