"use client"; /** * T-139 — the bulk page-action confirm dialog. Mounted at the workspace shell * (like MoveToDialog) so the sidebar's BulkActionBar can open it. Reads the * pending action + selection from the ui-store, shows a count, and on Confirm * fires `useBulkPages` (POST /pages/bulk). The server returns `{ succeeded, * failed }` — a page the caller lacks EDIT on lands in `failed` (403), never * silently skipped — so a partial result toasts both counts. */ import { Dialog, DialogFooter } from "@/components/dialogs/dialog"; import { useBulkPages } from "@/hooks/use-pages"; import { toast, useUiStore, type BulkAction } from "@/stores/ui-store"; const ACTION_COPY: Record = { trash: { verb: "Move to trash", confirm: "Move to trash", noun: "page" }, archive: { verb: "Archive", confirm: "Archive", noun: "page" }, unarchive: { verb: "Unarchive", confirm: "Unarchive", noun: "page" }, favorite: { verb: "Add to favorites", confirm: "Add to favorites", noun: "page" }, unfavorite: { verb: "Remove from favorites", confirm: "Remove from favorites", noun: "page" } }; export function BulkActionsDialog() { const bulkOpen = useUiStore((s) => s.bulkOpen); const bulkAction = useUiStore((s) => s.bulkAction); const pageSelection = useUiStore((s) => s.pageSelection); const setBulk = useUiStore((s) => s.setBulk); const bulk = useBulkPages(pageSelection.workspaceId); if (!bulkOpen || !bulkAction) return null; const copy = ACTION_COPY[bulkAction]; const count = pageSelection.ids.length; const destructive = bulkAction === "trash"; const onConfirm = () => { const ids = pageSelection.ids; bulk.mutate( { action: bulkAction, ids }, { onSuccess: (res) => { const { succeeded, failed } = res; const unit = (n: number) => `${n} ${n === 1 ? copy.noun : copy.noun + "s"}`; if (failed.length === 0) { toast("success", `${copy.confirm} ${unit(succeeded.length)}`); } else if (succeeded.length === 0) { toast("error", `${copy.confirm} failed`, `${unit(failed.length)} — no permission or missing.`); } else { toast("info", `${copy.confirm}: ${unit(succeeded.length)}`, `${unit(failed.length)} skipped (no permission or missing).`); } }, onError: (e: Error) => toast("error", `${copy.confirm} failed`, e.message) } ); }; return ( setBulk(false)} footer={ setBulk(false)} onAction={onConfirm} actionLabel={copy.confirm} busy={bulk.isPending} destructive={destructive} /> } >

{count} {count === 1 ? copy.noun : copy.noun + "s"} will be affected. Pages you cannot edit are skipped and reported.

); }