diff --git a/packages/ra-core/src/controller/button/index.ts b/packages/ra-core/src/controller/button/index.ts
index 313e91771cd..926e94e5424 100644
--- a/packages/ra-core/src/controller/button/index.ts
+++ b/packages/ra-core/src/controller/button/index.ts
@@ -2,3 +2,4 @@ import useDeleteWithUndoController from './useDeleteWithUndoController';
import useDeleteWithConfirmController from './useDeleteWithConfirmController';
export { useDeleteWithUndoController, useDeleteWithConfirmController };
+export * from './useDeleteController';
diff --git a/packages/ra-core/src/controller/button/useDeleteController.tsx b/packages/ra-core/src/controller/button/useDeleteController.tsx
new file mode 100644
index 00000000000..073f2b5eb01
--- /dev/null
+++ b/packages/ra-core/src/controller/button/useDeleteController.tsx
@@ -0,0 +1,184 @@
+import { useCallback, useMemo } from 'react';
+import { UseMutationOptions } from '@tanstack/react-query';
+
+import { useDelete } from '../../dataProvider';
+import { useUnselect } from '../';
+import { useRedirect, RedirectionSideEffect } from '../../routing';
+import { useNotify } from '../../notification';
+import { RaRecord, MutationMode, DeleteParams } from '../../types';
+import { useResourceContext } from '../../core';
+import { useTranslate } from '../../i18n';
+
+/**
+ * Prepare a set of callbacks for a delete button
+ *
+ * @example
+ * const DeleteButton = ({
+ * resource,
+ * record,
+ * redirect,
+ * ...rest
+ * }) => {
+ * const {
+ * isPending,
+ * handleDelete,
+ * } = useDeleteController({
+ * mutationMode: 'pessimistic',
+ * resource,
+ * record,
+ * redirect,
+ * });
+ *
+ * const [open, setOpen] = useState(false);
+ *
+ * return (
+ *
+ *
+ * handleDelete()}
+ * onClose={() => setOpen(false)}
+ * />
+ *
+ * );
+ * };
+ */
+export const useDeleteController = <
+ RecordType extends RaRecord = any,
+ ErrorType = Error,
+>(
+ props: UseDeleteControllerParams
+): UseDeleteControllerReturn => {
+ const {
+ record,
+ redirect: redirectTo = 'list',
+ mutationMode,
+ mutationOptions = {},
+ successMessage,
+ } = props;
+ const { meta: mutationMeta, ...otherMutationOptions } = mutationOptions;
+ const resource = useResourceContext(props);
+ const notify = useNotify();
+ const unselect = useUnselect(resource);
+ const redirect = useRedirect();
+ const translate = useTranslate();
+
+ const [deleteOne, { isPending }] = useDelete(
+ resource,
+ undefined,
+ {
+ onSuccess: () => {
+ notify(
+ successMessage ??
+ `resources.${resource}.notifications.deleted`,
+ {
+ type: 'info',
+ messageArgs: {
+ smart_count: 1,
+ _: translate('ra.notification.deleted', {
+ smart_count: 1,
+ }),
+ },
+ undoable: mutationMode === 'undoable',
+ }
+ );
+ record && unselect([record.id]);
+ redirect(redirectTo, resource);
+ },
+ onError: error => {
+ notify(
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message ||
+ 'ra.notification.http_error',
+ {
+ type: 'error',
+ messageArgs: {
+ _:
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message
+ ? (error as Error).message
+ : undefined,
+ },
+ }
+ );
+ },
+ }
+ );
+
+ const handleDelete = useCallback(() => {
+ if (!record) {
+ throw new Error(
+ 'The record cannot be deleted because no record has been passed'
+ );
+ }
+ deleteOne(
+ resource,
+ {
+ id: record.id,
+ previousData: record,
+ meta: mutationMeta,
+ },
+ {
+ mutationMode,
+ ...otherMutationOptions,
+ }
+ );
+ }, [
+ deleteOne,
+ mutationMeta,
+ mutationMode,
+ otherMutationOptions,
+ record,
+ resource,
+ ]);
+
+ return useMemo(
+ () => ({
+ isPending,
+ isLoading: isPending,
+ handleDelete,
+ }),
+ [isPending, handleDelete]
+ );
+};
+
+export interface UseDeleteControllerParams<
+ RecordType extends RaRecord = any,
+ MutationOptionsError = unknown,
+> {
+ mutationMode?: MutationMode;
+ mutationOptions?: UseMutationOptions<
+ RecordType,
+ MutationOptionsError,
+ DeleteParams
+ >;
+ record?: RecordType;
+ redirect?: RedirectionSideEffect;
+ resource?: string;
+ successMessage?: string;
+}
+
+export interface UseDeleteControllerReturn {
+ isLoading: boolean;
+ isPending: boolean;
+ handleDelete: () => void;
+}
diff --git a/packages/ra-core/src/controller/button/useDeleteWithConfirmController.tsx b/packages/ra-core/src/controller/button/useDeleteWithConfirmController.tsx
index 15b72f8f8d4..c45b70818ec 100644
--- a/packages/ra-core/src/controller/button/useDeleteWithConfirmController.tsx
+++ b/packages/ra-core/src/controller/button/useDeleteWithConfirmController.tsx
@@ -1,21 +1,20 @@
+import { useState, ReactEventHandler, SyntheticEvent } from 'react';
import {
- useState,
- useCallback,
- ReactEventHandler,
- SyntheticEvent,
-} from 'react';
-import { UseMutationOptions } from '@tanstack/react-query';
-
-import { useDelete } from '../../dataProvider';
-import { useUnselect } from '../../controller';
-import { useRedirect, RedirectionSideEffect } from '../../routing';
+ useDeleteController,
+ UseDeleteControllerParams,
+ UseDeleteControllerReturn,
+ useUnselect,
+} from '../';
+import { useRedirect } from '../../routing';
import { useNotify } from '../../notification';
-import { RaRecord, MutationMode, DeleteParams } from '../../types';
+import { RaRecord } from '../../types';
import { useResourceContext } from '../../core';
import { useTranslate } from '../../i18n';
+import { useEvent } from '../../util';
/**
* Prepare a set of callbacks for a delete button guarded by confirmation dialog
+ * @deprecated prefer the useDeleteController hook instead
*
* @example
*
@@ -75,112 +74,92 @@ const useDeleteWithConfirmController = <
props: UseDeleteWithConfirmControllerParams
): UseDeleteWithConfirmControllerReturn => {
const {
- record,
- redirect: redirectTo = 'list',
mutationMode,
onClick,
- mutationOptions = {},
+ record,
+ redirect: redirectTo = 'list',
successMessage,
+ mutationOptions = {},
+ ...rest
} = props;
- const { meta: mutationMeta, ...otherMutationOptions } = mutationOptions;
- const resource = useResourceContext(props);
const [open, setOpen] = useState(false);
+ const resource = useResourceContext(props);
const notify = useNotify();
const unselect = useUnselect(resource);
const redirect = useRedirect();
const translate = useTranslate();
- const [deleteOne, { isPending }] = useDelete(
- resource,
- undefined,
- {
- onSuccess: () => {
- setOpen(false);
- notify(
- successMessage ??
- `resources.${resource}.notifications.deleted`,
- {
- type: 'info',
- messageArgs: {
- smart_count: 1,
- _: translate('ra.notification.deleted', {
+ const { isPending, handleDelete: controllerHandleDelete } =
+ useDeleteController({
+ mutationMode,
+ mutationOptions: {
+ onSuccess: () => {
+ setOpen(false);
+ notify(
+ successMessage ??
+ `resources.${resource}.notifications.deleted`,
+ {
+ type: 'info',
+ messageArgs: {
smart_count: 1,
- }),
- },
- undoable: mutationMode === 'undoable',
- }
- );
- record && unselect([record.id]);
- redirect(redirectTo, resource);
- },
- onError: error => {
- setOpen(false);
+ _: translate('ra.notification.deleted', {
+ smart_count: 1,
+ }),
+ },
+ undoable: mutationMode === 'undoable',
+ }
+ );
+ record && unselect([record.id]);
+ redirect(redirectTo, resource);
+ },
+ onError: error => {
+ setOpen(false);
- notify(
- typeof error === 'string'
- ? error
- : (error as Error)?.message ||
- 'ra.notification.http_error',
- {
- type: 'error',
- messageArgs: {
- _:
- typeof error === 'string'
- ? error
- : (error as Error)?.message
- ? (error as Error).message
- : undefined,
- },
- }
- );
+ notify(
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message ||
+ 'ra.notification.http_error',
+ {
+ type: 'error',
+ messageArgs: {
+ _:
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message
+ ? (error as Error).message
+ : undefined,
+ },
+ }
+ );
+ },
+ ...mutationOptions,
},
- }
- );
+ record,
+ redirect: redirectTo,
+ successMessage,
+ ...rest,
+ });
- const handleDialogOpen = e => {
- setOpen(true);
+ const handleDialogOpen = useEvent((e: any) => {
e.stopPropagation();
- };
+ setOpen(true);
+ });
- const handleDialogClose = e => {
- setOpen(false);
+ const handleDialogClose = useEvent((e: any) => {
e.stopPropagation();
- };
+ setOpen(false);
+ });
- const handleDelete = useCallback(
- event => {
+ const handleDelete = useEvent((event: any) => {
+ if (event && event.stopPropagation) {
event.stopPropagation();
- if (!record) {
- throw new Error(
- 'The record cannot be deleted because no record has been passed'
- );
- }
- deleteOne(
- resource,
- {
- id: record.id,
- previousData: record,
- meta: mutationMeta,
- },
- {
- mutationMode,
- ...otherMutationOptions,
- }
- );
- if (typeof onClick === 'function') {
- onClick(event);
- }
- },
- [
- deleteOne,
- mutationMeta,
- mutationMode,
- otherMutationOptions,
- onClick,
- record,
- resource,
- ]
- );
+ }
+ controllerHandleDelete();
+ if (typeof onClick === 'function') {
+ onClick(event);
+ }
+ });
return {
open,
@@ -195,24 +174,13 @@ const useDeleteWithConfirmController = <
export interface UseDeleteWithConfirmControllerParams<
RecordType extends RaRecord = any,
MutationOptionsError = unknown,
-> {
- mutationMode?: MutationMode;
- record?: RecordType;
- redirect?: RedirectionSideEffect;
- resource?: string;
+> extends UseDeleteControllerParams {
onClick?: ReactEventHandler;
- mutationOptions?: UseMutationOptions<
- RecordType,
- MutationOptionsError,
- DeleteParams
- >;
- successMessage?: string;
}
-export interface UseDeleteWithConfirmControllerReturn {
+export interface UseDeleteWithConfirmControllerReturn
+ extends Omit {
open: boolean;
- isLoading: boolean;
- isPending: boolean;
handleDialogOpen: (e: SyntheticEvent) => void;
handleDialogClose: (e: SyntheticEvent) => void;
handleDelete: ReactEventHandler;
diff --git a/packages/ra-core/src/controller/button/useDeleteWithUndoController.tsx b/packages/ra-core/src/controller/button/useDeleteWithUndoController.tsx
index f04445c4b86..6df1fde0dfe 100644
--- a/packages/ra-core/src/controller/button/useDeleteWithUndoController.tsx
+++ b/packages/ra-core/src/controller/button/useDeleteWithUndoController.tsx
@@ -1,17 +1,16 @@
-import { useCallback, ReactEventHandler } from 'react';
-import { UseMutationOptions } from '@tanstack/react-query';
+import type { ReactEventHandler } from 'react';
-import { useDelete } from '../../dataProvider';
-import { useUnselect } from '../../controller';
-import { useRedirect, RedirectionSideEffect } from '../../routing';
-import { useNotify } from '../../notification';
-import { RaRecord, DeleteParams } from '../../types';
-import { useResourceContext } from '../../core';
-import { useTranslate } from '../../i18n';
+import {
+ useDeleteController,
+ type UseDeleteControllerParams,
+ type UseDeleteControllerReturn,
+} from './useDeleteController';
+import type { RaRecord } from '../../types';
+import { useEvent } from '../../util';
/**
* Prepare callback for a Delete button with undo support
- *
+ * @deprecated prefer the useDeleteController hook instead
* @example
*
* import React from 'react';
@@ -50,96 +49,19 @@ const useDeleteWithUndoController = <
>(
props: UseDeleteWithUndoControllerParams
): UseDeleteWithUndoControllerReturn => {
- const {
- record,
- redirect: redirectTo = 'list',
- onClick,
- mutationOptions = {},
- successMessage,
- } = props;
- const { meta: mutationMeta, ...otherMutationOptions } = mutationOptions;
- const resource = useResourceContext(props);
- const notify = useNotify();
- const unselect = useUnselect(resource);
- const redirect = useRedirect();
- const translate = useTranslate();
- const [deleteOne, { isPending }] = useDelete(
- resource,
- undefined,
- {
- onSuccess: () => {
- notify(
- successMessage ??
- `resources.${resource}.notifications.deleted`,
- {
- type: 'info',
- messageArgs: {
- smart_count: 1,
- _: translate('ra.notification.deleted', {
- smart_count: 1,
- }),
- },
- undoable: true,
- }
- );
- record && unselect([record.id]);
- redirect(redirectTo, resource);
- },
- onError: error => {
- notify(
- typeof error === 'string'
- ? error
- : (error as Error)?.message ||
- 'ra.notification.http_error',
- {
- type: 'error',
- messageArgs: {
- _:
- typeof error === 'string'
- ? error
- : (error as Error)?.message
- ? (error as Error).message
- : undefined,
- },
- }
- );
- },
- }
- );
+ const { onClick } = props;
+ const { isPending, handleDelete: controllerHandleDelete } =
+ useDeleteController({ ...props, mutationMode: 'undoable' });
- const handleDelete = useCallback(
- event => {
+ const handleDelete = useEvent((event: any) => {
+ if (event && event.stopPropagation) {
event.stopPropagation();
- if (!record) {
- throw new Error(
- 'The record cannot be deleted because no record has been passed'
- );
- }
- deleteOne(
- resource,
- {
- id: record.id,
- previousData: record,
- meta: mutationMeta,
- },
- {
- mutationMode: 'undoable',
- ...otherMutationOptions,
- }
- );
- if (typeof onClick === 'function') {
- onClick(event);
- }
- },
- [
- deleteOne,
- mutationMeta,
- otherMutationOptions,
- onClick,
- record,
- resource,
- ]
- );
+ }
+ controllerHandleDelete();
+ if (typeof onClick === 'function') {
+ onClick(event);
+ }
+ });
return { isPending, isLoading: isPending, handleDelete };
};
@@ -147,22 +69,15 @@ const useDeleteWithUndoController = <
export interface UseDeleteWithUndoControllerParams<
RecordType extends RaRecord = any,
MutationOptionsError = unknown,
-> {
- record?: RecordType;
- redirect?: RedirectionSideEffect;
- resource?: string;
+> extends Omit<
+ UseDeleteControllerParams,
+ 'mutationMode'
+ > {
onClick?: ReactEventHandler;
- mutationOptions?: UseMutationOptions<
- RecordType,
- MutationOptionsError,
- DeleteParams
- >;
- successMessage?: string;
}
-export interface UseDeleteWithUndoControllerReturn {
- isPending: boolean;
- isLoading: boolean;
+export interface UseDeleteWithUndoControllerReturn
+ extends Omit {
handleDelete: ReactEventHandler;
}
diff --git a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx
index 02bd5e4a4e8..80a1401b736 100644
--- a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx
+++ b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx
@@ -96,8 +96,8 @@ describe('', () => {
it('should allow to override the resource', async () => {
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
@@ -137,8 +137,8 @@ describe('', () => {
it('should allows to undo the deletion after confirmation if mutationMode is undoable', async () => {
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
@@ -182,8 +182,8 @@ describe('', () => {
it('should allow to override the success side effects', async () => {
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
@@ -226,13 +226,17 @@ describe('', () => {
{ snapshot: [] }
);
});
+ await waitFor(() => {
+ // Check that the dialog is closed
+ expect(screen.queryByText('ra.action.confirm')).toBeNull();
+ });
});
it('should allow to override the error side effects', async () => {
jest.spyOn(console, 'error').mockImplementation(() => {});
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
@@ -275,12 +279,16 @@ describe('', () => {
{ snapshot: [] }
);
});
+ await waitFor(() => {
+ // Check that the dialog is closed
+ expect(screen.queryByText('ra.action.confirm')).toBeNull();
+ });
});
it('should allow to override the translateOptions props', async () => {
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
@@ -322,8 +330,8 @@ describe('', () => {
it('should display success message after successful deletion', async () => {
const successMessage = 'Test Message';
const dataProvider = testDataProvider({
- // @ts-ignore
getOne: () =>
+ // @ts-ignore
Promise.resolve({
data: { id: 123, title: 'lorem' },
}),
diff --git a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.tsx b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.tsx
index 8e665c93bee..321460686f5 100644
--- a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.tsx
+++ b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.tsx
@@ -7,18 +7,18 @@ import {
} from '@mui/material/styles';
import clsx from 'clsx';
-import { UseMutationOptions } from '@tanstack/react-query';
import {
- MutationMode,
RaRecord,
- DeleteParams,
- useDeleteWithConfirmController,
useRecordContext,
useResourceContext,
useTranslate,
- RedirectionSideEffect,
useGetRecordRepresentation,
useResourceTranslation,
+ useDeleteController,
+ useNotify,
+ useUnselect,
+ useRedirect,
+ UseDeleteControllerParams,
} from 'ra-core';
import { humanize, singularize } from 'inflection';
@@ -42,7 +42,7 @@ export const DeleteWithConfirmButton = (
label: labelProp,
mutationMode = 'pessimistic',
onClick,
- redirect = 'list',
+ redirect: redirectTo = 'list',
translateOptions = {},
titleTranslateOptions = translateOptions,
contentTranslateOptions = translateOptions,
@@ -54,27 +54,85 @@ export const DeleteWithConfirmButton = (
const translate = useTranslate();
const record = useRecordContext(props);
const resource = useResourceContext(props);
+ const notify = useNotify();
+ const unselect = useUnselect(resource);
+ const redirect = useRedirect();
+ const [open, setOpen] = React.useState(false);
if (!resource) {
throw new Error(
' components should be used inside a component or provided with a resource prop. (The component set the resource prop for all its children).'
);
}
- const {
- open,
- isPending,
- handleDialogOpen,
- handleDialogClose,
- handleDelete,
- } = useDeleteWithConfirmController({
+ const { onSuccess, onError, ...otherMutationOptions } =
+ mutationOptions || {};
+
+ const { isPending, handleDelete } = useDeleteController({
record,
- redirect,
+ redirect: redirectTo,
mutationMode,
- onClick,
- mutationOptions,
+ mutationOptions: {
+ ...otherMutationOptions,
+ onSuccess: (data, variables, context) => {
+ setOpen(false);
+ if (onSuccess) {
+ onSuccess(data, variables, context);
+ } else {
+ notify(
+ successMessage ??
+ `resources.${resource}.notifications.deleted`,
+ {
+ type: 'info',
+ messageArgs: {
+ smart_count: 1,
+ _: translate('ra.notification.deleted', {
+ smart_count: 1,
+ }),
+ },
+ undoable: mutationMode === 'undoable',
+ }
+ );
+ record && unselect([record.id]);
+ redirect(redirectTo, resource);
+ }
+ },
+ onError: (error, variables, context) => {
+ setOpen(false);
+ if (onError) {
+ onError(error, variables, context);
+ } else {
+ notify(
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message ||
+ 'ra.notification.http_error',
+ {
+ type: 'error',
+ messageArgs: {
+ _:
+ typeof error === 'string'
+ ? error
+ : (error as Error)?.message
+ ? (error as Error).message
+ : undefined,
+ },
+ }
+ );
+ }
+ },
+ },
resource,
successMessage,
});
+
+ const handleDialogOpen: ReactEventHandler = event => {
+ event.stopPropagation();
+ setOpen(true);
+ };
+ const handleDialogClose: ReactEventHandler = () => {
+ setOpen(false);
+ };
+
const getRecordRepresentation = useGetRecordRepresentation(resource);
let recordRepresentation = getRecordRepresentation(record);
const resourceName = translate(`resources.${resource}.forcedCaseName`, {
@@ -156,12 +214,12 @@ const defaultIcon = ;
export interface DeleteWithConfirmButtonProps<
RecordType extends RaRecord = any,
MutationOptionsError = unknown,
-> extends ButtonProps {
+> extends ButtonProps,
+ UseDeleteControllerParams {
confirmTitle?: React.ReactNode;
confirmContent?: React.ReactNode;
icon?: React.ReactNode;
confirmColor?: 'primary' | 'warning';
- mutationMode?: MutationMode;
onClick?: ReactEventHandler;
// May be injected by Toolbar - sanitized in Button
/**
@@ -170,15 +228,6 @@ export interface DeleteWithConfirmButtonProps<
translateOptions?: object;
titleTranslateOptions?: object;
contentTranslateOptions?: object;
- mutationOptions?: UseMutationOptions<
- RecordType,
- MutationOptionsError,
- DeleteParams
- >;
- record?: RecordType;
- redirect?: RedirectionSideEffect;
- resource?: string;
- successMessage?: string;
}
const PREFIX = 'RaDeleteWithConfirmButton';
diff --git a/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.tsx b/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.tsx
index 1b94740f331..c0bbd1c487b 100644
--- a/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.tsx
+++ b/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.tsx
@@ -2,17 +2,15 @@ import * as React from 'react';
import { ReactNode, ReactEventHandler } from 'react';
import ActionDelete from '@mui/icons-material/Delete';
import clsx from 'clsx';
-import { UseMutationOptions } from '@tanstack/react-query';
import {
RaRecord,
- useDeleteWithUndoController,
- DeleteParams,
+ useDeleteController,
useRecordContext,
useResourceContext,
- RedirectionSideEffect,
useTranslate,
useGetRecordRepresentation,
useResourceTranslation,
+ UseDeleteControllerParams,
} from 'ra-core';
import { humanize, singularize } from 'inflection';
@@ -50,14 +48,22 @@ export const DeleteWithUndoButton = (
' components should be used inside a component or provided with a resource prop. (The component set the resource prop for all its children).'
);
}
- const { isPending, handleDelete } = useDeleteWithUndoController({
+ const { isPending, handleDelete } = useDeleteController({
record,
resource,
redirect,
- onClick,
+ mutationMode: 'undoable',
mutationOptions,
successMessage,
});
+ const handleClick: ReactEventHandler = event => {
+ event.stopPropagation();
+ handleDelete();
+ if (onClick) {
+ onClick(event);
+ }
+ };
+
const translate = useTranslate();
const getRecordRepresentation = useGetRecordRepresentation(resource);
let recordRepresentation = getRecordRepresentation(record);
@@ -87,7 +93,7 @@ export const DeleteWithUndoButton = (
return (
{label}>}
@@ -108,18 +114,10 @@ const defaultIcon = ;
export interface DeleteWithUndoButtonProps<
RecordType extends RaRecord = any,
MutationOptionsError = unknown,
-> extends ButtonProps {
+> extends ButtonProps,
+ UseDeleteControllerParams {
icon?: ReactNode;
onClick?: ReactEventHandler;
- mutationOptions?: UseMutationOptions<
- RecordType,
- MutationOptionsError,
- DeleteParams
- >;
- record?: RecordType;
- redirect?: RedirectionSideEffect;
- resource?: string;
- successMessage?: string;
}
const PREFIX = 'RaDeleteWithUndoButton';