import {
useState,
useCallback,
ReactEventHandler,
SyntheticEvent,
} from 'react';
import { UseMutationOptions } from 'react-query';
import { useDelete } from '../../dataProvider';
import { useUnselect } from '../../controller';
import { useRedirect, RedirectionSideEffect } from '../../routing';
import { useNotify } from '../../notification';
import { RaRecord, MutationMode, DeleteParams } from '../../types';
import { useResourceContext } from '../../core';
/**
* Prepare a set of callbacks for a delete button guarded by confirmation dialog
*
* @example
*
* const DeleteButton = ({
* resource,
* record,
* redirect,
* onClick,
* ...rest
* }) => {
* const {
* open,
* isLoading,
* handleDialogOpen,
* handleDialogClose,
* handleDelete,
* } = useDeleteWithConfirmController({
* resource,
* record,
* redirect,
* onClick,
* });
*
* return (
*
*
*
*
* );
* };
*/
const useDeleteWithConfirmController = (
props: UseDeleteWithConfirmControllerParams
): UseDeleteWithConfirmControllerReturn => {
const {
record,
redirect: redirectTo,
mutationMode,
onClick,
mutationOptions = {},
} = props;
const { meta: mutationMeta, ...otherMutationOptions } = mutationOptions;
const resource = useResourceContext(props);
const [open, setOpen] = useState(false);
const notify = useNotify();
const unselect = useUnselect(resource);
const redirect = useRedirect();
const [deleteOne, { isLoading }] = useDelete();
const handleDialogOpen = e => {
setOpen(true);
e.stopPropagation();
};
const handleDialogClose = e => {
setOpen(false);
e.stopPropagation();
};
const handleDelete = useCallback(
event => {
event.stopPropagation();
deleteOne(
resource,
{
id: record.id,
previousData: record,
meta: mutationMeta,
},
{
onSuccess: () => {
setOpen(false);
notify('ra.notification.deleted', {
type: 'info',
messageArgs: { smart_count: 1 },
undoable: mutationMode === 'undoable',
});
unselect([record.id]);
redirect(redirectTo, resource);
},
onError: (error: Error) => {
setOpen(false);
notify(
typeof error === 'string'
? error
: error.message || 'ra.notification.http_error',
{
type: 'error',
messageArgs: {
_:
typeof error === 'string'
? error
: error && error.message
? error.message
: undefined,
},
}
);
},
mutationMode,
...otherMutationOptions,
}
);
if (typeof onClick === 'function') {
onClick(event);
}
},
[
deleteOne,
mutationMeta,
mutationMode,
otherMutationOptions,
notify,
onClick,
record,
redirect,
redirectTo,
resource,
unselect,
]
);
return {
open,
isLoading,
handleDialogOpen,
handleDialogClose,
handleDelete,
};
};
export interface UseDeleteWithConfirmControllerParams<
RecordType extends RaRecord = any,
MutationOptionsError = unknown
> {
mutationMode?: MutationMode;
record?: RecordType;
redirect?: RedirectionSideEffect;
// @deprecated. This hook get the resource from the context
resource?: string;
onClick?: ReactEventHandler;
mutationOptions?: UseMutationOptions<
RecordType,
MutationOptionsError,
DeleteParams
>;
}
export interface UseDeleteWithConfirmControllerReturn {
open: boolean;
isLoading: boolean;
handleDialogOpen: (e: SyntheticEvent) => void;
handleDialogClose: (e: SyntheticEvent) => void;
handleDelete: ReactEventHandler;
}
export default useDeleteWithConfirmController;