build useDeleteItems hook

This commit is contained in:
Keith Grant
2020-02-14 09:14:33 -08:00
parent c824f0d590
commit 69a1a02c70
2 changed files with 53 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useCallback } from 'react'; 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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { CredentialsAPI } from '@api'; import { CredentialsAPI } from '@api';
@@ -11,8 +11,7 @@ import PaginatedDataList, {
ToolbarAddButton, ToolbarAddButton,
ToolbarDeleteButton, ToolbarDeleteButton,
} from '@components/PaginatedDataList'; } from '@components/PaginatedDataList';
import useRequest from '@util/useRequest'; import useRequest, { useDeleteItems } from '@util/useRequest';
import updateUrlAfterDelete from '@util/updateUrlAfterDelete';
import { getQSConfig, parseQueryString } from '@util/qs'; import { getQSConfig, parseQueryString } from '@util/qs';
import { CredentialListItem } from '.'; import { CredentialListItem } from '.';
@@ -23,11 +22,8 @@ const QS_CONFIG = getQSConfig('credential', {
}); });
function CredentialList({ i18n }) { function CredentialList({ i18n }) {
const [showDeletionError, setShowDeletionError] = useState(false);
const [selected, setSelected] = useState([]); const [selected, setSelected] = useState([]);
const location = useLocation(); const location = useLocation();
const history = useHistory();
const { const {
result: { credentials, credentialCount, actions }, result: { credentials, credentialCount, actions },
@@ -60,33 +56,23 @@ function CredentialList({ i18n }) {
const { const {
isLoading: isDeleteLoading, isLoading: isDeleteLoading,
error: deletionError, deleteItems: deleteCredentials,
request: deleteCredentials, deletionError,
} = useRequest( clearDeletionError,
} = useDeleteItems(
useCallback(async () => { useCallback(async () => {
return Promise.all(selected.map(({ id }) => CredentialsAPI.destroy(id))); return Promise.all(selected.map(({ id }) => CredentialsAPI.destroy(id)));
}, [selected]) }, [selected]),
); {
qsConfig: QS_CONFIG,
useEffect(() => { items: credentials,
if (deletionError) { selected,
setShowDeletionError(true); fetchItems: fetchCredentials,
} }
}, [deletionError]); );
const handleDelete = async () => { const handleDelete = async () => {
await deleteCredentials(); await deleteCredentials();
const url = updateUrlAfterDelete(
QS_CONFIG,
location,
credentials,
selected
);
if (url) {
history.push(url);
} else {
fetchCredentials();
}
setSelected([]); setSelected([]);
}; };
@@ -149,10 +135,10 @@ function CredentialList({ i18n }) {
/> />
</Card> </Card>
<AlertModal <AlertModal
isOpen={showDeletionError} isOpen={deletionError}
variant="danger" variant="danger"
title={i18n._(t`Error!`)} title={i18n._(t`Error!`)}
onClose={() => setShowDeletionError(false)} onClose={clearDeletionError}
> >
{i18n._(t`Failed to delete one or more credentials.`)} {i18n._(t`Failed to delete one or more credentials.`)}
<ErrorDetail error={deletionError} /> <ErrorDetail error={deletionError} />

View File

@@ -1,4 +1,10 @@
import { useEffect, useState, useRef, useCallback } from 'react'; 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 * The useRequest hook accepts a request function and returns an object with
@@ -47,3 +53,35 @@ export default function useRequest(makeRequest, initialValue) {
}, [makeRequest]), }, [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),
};
}