Rename onLoading/onDoneLoading props to onCopyStart and onCopyFinish. Wrap the functions being passed in as those props in useCallback to keep them hooks safe.

This commit is contained in:
mabashian 2020-09-10 16:21:24 -04:00
parent 4b566e9388
commit d84615f64b
6 changed files with 64 additions and 18 deletions

View File

@ -9,17 +9,24 @@ import useRequest, { useDismissableError } from '../../util/useRequest';
import AlertModal from '../AlertModal';
import ErrorDetail from '../ErrorDetail';
function CopyButton({ i18n, copyItem, onLoading, onDoneLoading, helperText }) {
function CopyButton({
i18n,
copyItem,
isDisabled,
onCopyStart,
onCopyFinish,
helperText,
}) {
const { isLoading, error: copyError, request: copyItemToAPI } = useRequest(
copyItem
);
useEffect(() => {
if (isLoading) {
return onLoading();
return onCopyStart();
}
return onDoneLoading();
}, [isLoading, onLoading, onDoneLoading]);
return onCopyFinish();
}, [isLoading, onCopyStart, onCopyFinish]);
const { error, dismissError } = useDismissableError(copyError);
@ -27,6 +34,7 @@ function CopyButton({ i18n, copyItem, onLoading, onDoneLoading, helperText }) {
<>
<Tooltip content={helperText.tooltip} position="top">
<Button
isDisabled={isDisabled}
aria-label={i18n._(t`Copy`)}
variant="plain"
onClick={copyItemToAPI}
@ -50,11 +58,17 @@ function CopyButton({ i18n, copyItem, onLoading, onDoneLoading, helperText }) {
CopyButton.propTypes = {
copyItem: PropTypes.func.isRequired,
onLoading: PropTypes.func.isRequired,
onDoneLoading: PropTypes.func.isRequired,
onCopyStart: PropTypes.func.isRequired,
onCopyFinish: PropTypes.func.isRequired,
helperText: PropTypes.shape({
tooltip: PropTypes.string.isRequired,
errorMessage: PropTypes.string.isRequired,
}).isRequired,
isDisabled: PropTypes.bool,
};
CopyButton.defaultProps = {
isDisabled: false,
};
export default withI18n()(CopyButton);

View File

@ -8,8 +8,8 @@ describe('<CopyButton/>', () => {
test('shold mount properly', () => {
const wrapper = mountWithContexts(
<CopyButton
onLoading={() => {}}
onDoneLoading={() => {}}
onCopyStart={() => {}}
onCopyFinish={() => {}}
copyItem={() => {}}
helperText={{
tooltip: `Copy Template`,
@ -22,8 +22,8 @@ describe('<CopyButton/>', () => {
test('should render proper tooltip', () => {
const wrapper = mountWithContexts(
<CopyButton
onLoading={() => {}}
onDoneLoading={() => {}}
onCopyStart={() => {}}
onCopyFinish={() => {}}
copyItem={() => {}}
helperText={{
tooltip: `Copy Template`,

View File

@ -48,6 +48,14 @@ function CredentialListItem({
await fetchCredentials();
}, [credential.id, credential.name, fetchCredentials]);
const handleCopyStart = useCallback(() => {
setIsDisabled(true);
}, []);
const handleCopyFinish = useCallback(() => {
setIsDisabled(false);
}, []);
return (
<DataListItem
key={credential.id}
@ -95,8 +103,8 @@ function CredentialListItem({
{credential.summary_fields.user_capabilities.copy && (
<CopyButton
isDisabled={isDisabled}
onLoading={() => setIsDisabled(true)}
onDoneLoading={() => setIsDisabled(false)}
onCopyStart={handleCopyStart}
onCopyFinish={handleCopyFinish}
copyItem={copyCredential}
helperText={{
tooltip: i18n._(t`Copy Credential`),

View File

@ -52,6 +52,14 @@ function InventoryListItem({
await fetchInventories();
}, [inventory.id, inventory.name, fetchInventories]);
const handleCopyStart = useCallback(() => {
setIsDisabled(true);
}, []);
const handleCopyFinish = useCallback(() => {
setIsDisabled(false);
}, []);
const labelId = `check-action-${inventory.id}`;
let syncStatus = 'disabled';
@ -128,8 +136,8 @@ function InventoryListItem({
<CopyButton
copyItem={copyInventory}
isDisabled={isDisabled}
onLoading={() => setIsDisabled(true)}
onDoneLoading={() => setIsDisabled(false)}
onCopyStart={handleCopyStart}
onCopyFinish={handleCopyFinish}
helperText={{
tooltip: i18n._(t`Copy Inventory`),
errorMessage: i18n._(t`Failed to copy inventory.`),

View File

@ -79,6 +79,14 @@ function ProjectListItem({
);
};
const handleCopyStart = useCallback(() => {
setIsDisabled(true);
}, []);
const handleCopyFinish = useCallback(() => {
setIsDisabled(false);
}, []);
const labelId = `check-action-${project.id}`;
return (
<DataListItem
@ -182,8 +190,8 @@ function ProjectListItem({
<CopyButton
copyItem={copyProject}
isDisabled={isDisabled}
onLoading={() => setIsDisabled(true)}
onDoneLoading={() => setIsDisabled(false)}
onCopyStart={handleCopyStart}
onCopyFinish={handleCopyFinish}
helperText={{
tooltip: i18n._(t`Copy Project`),
errorMessage: i18n._(t`Failed to copy project.`),

View File

@ -60,6 +60,14 @@ function TemplateListItem({
await fetchTemplates();
}, [fetchTemplates, template.id, template.name, template.type]);
const handleCopyStart = useCallback(() => {
setIsDisabled(true);
}, []);
const handleCopyFinish = useCallback(() => {
setIsDisabled(false);
}, []);
const missingResourceIcon =
template.type === 'job_template' &&
(!template.summary_fields.project ||
@ -157,8 +165,8 @@ function TemplateListItem({
errorMessage: i18n._(t`Failed to copy template.`),
}}
isDisabled={isDisabled}
onLoading={() => setIsDisabled(true)}
onDoneLoading={() => setIsDisabled(false)}
onCopyStart={handleCopyStart}
onCopyFinish={handleCopyFinish}
copyItem={copyTemplate}
/>
)}