feat(page): replace move-to-trash confirm dialog with undo toast
Soft-deleting a page no longer opens a "Move this page to trash?" confirmation modal. The page is moved to trash immediately and the "Page moved to trash" toast now exposes an inline Undo action that restores the page via the existing restore flow. - Add move-to-trash-notification.tsx helper that builds the toast body (status text + Undo button) as a ReactNode, so it can be used from the non-TSX page-query module. - useRemovePageMutation: show the toast with a stable id, 8s autoClose, and an Undo handler that hides the toast and triggers restore. - space-tree-node-menu / page-header-menu: call handleDelete directly and drop the now-unused useDeletePageModal usage. Permanent delete keeps its confirmation modal. - useRestorePageMutation: read the live tree from the jotai store at execution time and insert via a functional updater, so Undo restores child pages correctly even after the originating component unmounted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,6 @@ import { notifications } from "@mantine/notifications";
|
||||
import { getAppUrl } from "@/lib/config.ts";
|
||||
import { extractPageSlugId } from "@/lib";
|
||||
import { useTreeMutation } from "@/features/page/tree/hooks/use-tree-mutation.ts";
|
||||
import { useDeletePageModal } from "@/features/page/hooks/use-delete-page-modal.tsx";
|
||||
import { PageWidthToggle } from "@/features/user/components/page-width-pref.tsx";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import ExportModal from "@/components/common/export-modal";
|
||||
@@ -143,7 +142,6 @@ function PageActionMenu({ readOnly }: PageActionMenuProps) {
|
||||
const { data: page, isLoading } = usePageQuery({
|
||||
pageId: extractPageSlugId(pageSlug),
|
||||
});
|
||||
const { openDeleteModal } = useDeletePageModal();
|
||||
const { handleDelete } = useTreeMutation(page?.spaceId ?? "");
|
||||
const [exportOpened, { open: openExportModal, close: closeExportModal }] =
|
||||
useDisclosure(false);
|
||||
@@ -189,7 +187,7 @@ function PageActionMenu({ readOnly }: PageActionMenuProps) {
|
||||
};
|
||||
|
||||
const handleDeletePage = () => {
|
||||
openDeleteModal({ onConfirm: () => handleDelete(page.id) });
|
||||
handleDelete(page.id);
|
||||
};
|
||||
|
||||
const handleToggleFavorite = () => {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Button, Group, Text } from "@mantine/core";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
type MoveToTrashNotificationProps = {
|
||||
message: string;
|
||||
undoLabel: string;
|
||||
onUndo: () => void;
|
||||
};
|
||||
|
||||
// Builds the body of the "page moved to trash" toast: the status text plus an
|
||||
// inline Undo action that restores the page from trash. Returned as a ReactNode
|
||||
// so it can be passed as the `message` of a Mantine notification from a
|
||||
// non-TSX module (page-query.ts).
|
||||
export function moveToTrashNotificationMessage({
|
||||
message,
|
||||
undoLabel,
|
||||
onUndo,
|
||||
}: MoveToTrashNotificationProps): ReactNode {
|
||||
return (
|
||||
<Group justify="space-between" wrap="nowrap" gap="md">
|
||||
<Text size="sm">{message}</Text>
|
||||
<Button variant="subtle" size="compact-sm" onClick={onUndo}>
|
||||
{undoLabel}
|
||||
</Button>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user