From 69a1a02c7020a10bd16d675a7540b7838f3eefa1 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Fri, 14 Feb 2020 09:14:33 -0800 Subject: [PATCH] build useDeleteItems hook --- .../CredentialList/CredentialList.jsx | 44 +++++++------------ awx/ui_next/src/util/useRequest.js | 38 ++++++++++++++++ 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx index cf3ab374dc..e08b1d5194 100644 --- a/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialList/CredentialList.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useCallback } from 'react'; -import { useLocation, useHistory } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import { CredentialsAPI } from '@api'; @@ -11,8 +11,7 @@ import PaginatedDataList, { ToolbarAddButton, ToolbarDeleteButton, } from '@components/PaginatedDataList'; -import useRequest from '@util/useRequest'; -import updateUrlAfterDelete from '@util/updateUrlAfterDelete'; +import useRequest, { useDeleteItems } from '@util/useRequest'; import { getQSConfig, parseQueryString } from '@util/qs'; import { CredentialListItem } from '.'; @@ -23,11 +22,8 @@ const QS_CONFIG = getQSConfig('credential', { }); function CredentialList({ i18n }) { - const [showDeletionError, setShowDeletionError] = useState(false); const [selected, setSelected] = useState([]); - const location = useLocation(); - const history = useHistory(); const { result: { credentials, credentialCount, actions }, @@ -60,33 +56,23 @@ function CredentialList({ i18n }) { const { isLoading: isDeleteLoading, - error: deletionError, - request: deleteCredentials, - } = useRequest( + deleteItems: deleteCredentials, + deletionError, + clearDeletionError, + } = useDeleteItems( useCallback(async () => { return Promise.all(selected.map(({ id }) => CredentialsAPI.destroy(id))); - }, [selected]) - ); - - useEffect(() => { - if (deletionError) { - setShowDeletionError(true); + }, [selected]), + { + qsConfig: QS_CONFIG, + items: credentials, + selected, + fetchItems: fetchCredentials, } - }, [deletionError]); + ); const handleDelete = async () => { await deleteCredentials(); - const url = updateUrlAfterDelete( - QS_CONFIG, - location, - credentials, - selected - ); - if (url) { - history.push(url); - } else { - fetchCredentials(); - } setSelected([]); }; @@ -149,10 +135,10 @@ function CredentialList({ i18n }) { /> setShowDeletionError(false)} + onClose={clearDeletionError} > {i18n._(t`Failed to delete one or more credentials.`)} diff --git a/awx/ui_next/src/util/useRequest.js b/awx/ui_next/src/util/useRequest.js index f6e9426dc8..b3e7fed599 100644 --- a/awx/ui_next/src/util/useRequest.js +++ b/awx/ui_next/src/util/useRequest.js @@ -1,4 +1,10 @@ import { useEffect, useState, useRef, useCallback } from 'react'; +import { useLocation, useHistory } from 'react-router-dom'; +import { + parseQueryString, + replaceParams, + encodeNonDefaultQueryString, +} from './qs'; /* * The useRequest hook accepts a request function and returns an object with @@ -47,3 +53,35 @@ export default function useRequest(makeRequest, initialValue) { }, [makeRequest]), }; } + +export function useDeleteItems( + makeRequest, + { qsConfig, items, selected, fetchItems } +) { + const location = useLocation(); + const history = useHistory(); + const [showError, setShowError] = useState(false); + + const { error, isLoading, request } = useRequest(makeRequest, null); + + const deleteItems = async () => { + await request(); + const params = parseQueryString(qsConfig, location.search); + if (params.page > 1 && selected.length === items.length) { + const newParams = encodeNonDefaultQueryString( + qsConfig, + replaceParams(params, { page: params.page - 1 }) + ); + history.push(`${location.pathname}?${newParams}`); + } else { + fetchItems(); + } + }; + + return { + isLoading, + deleteItems, + deletionError: showError && error, + clearDeletionError: () => setShowError(false), + }; +}