From be56b43dcbeeba71d61175c9767675d12a0155cc Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Mon, 6 Jul 2026 13:00:38 -0700 Subject: [PATCH] fix(ui): close the alert dialog when AlertDialogAction is clicked The base-vega registry template renders AlertDialogAction as a plain Button with no Close binding, so confirm buttons fired their onClick but left the dialog open; both consumers (conversation delete, MCP credential revoke) were written against the Radix semantics where Action dismisses on click. Binds Action to AlertDialogPrimitive.Close via the render prop, mirroring AlertDialogCancel, and pins the behavior with a test so a future shadcn add --overwrite cannot silently reintroduce the template's non-closing Action. --- .../src/components/ui/alert-dialog.test.tsx | 61 +++++++++++++++++++ .../src/components/ui/alert-dialog.tsx | 16 ++++- 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 ui/litellm-dashboard/src/components/ui/alert-dialog.test.tsx diff --git a/ui/litellm-dashboard/src/components/ui/alert-dialog.test.tsx b/ui/litellm-dashboard/src/components/ui/alert-dialog.test.tsx new file mode 100644 index 00000000000..4b0a197b129 --- /dev/null +++ b/ui/litellm-dashboard/src/components/ui/alert-dialog.test.tsx @@ -0,0 +1,61 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, expect, it, vi } from "vitest"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "./alert-dialog"; +import { Button } from "./button"; + +function ConfirmDialog({ onConfirm }: { onConfirm: () => void }) { + return ( + + Open} /> + + + Delete this? + Cannot be undone + + + Cancel + Confirm + + + + ); +} + +describe("AlertDialog", () => { + it("fires the action handler and closes the dialog on confirm", async () => { + const user = userEvent.setup(); + const onConfirm = vi.fn(); + render(); + + await user.click(screen.getByRole("button", { name: "Open" })); + expect(screen.getByText("Delete this?")).toBeInTheDocument(); + + await user.click(screen.getByRole("button", { name: "Confirm" })); + + expect(onConfirm).toHaveBeenCalledOnce(); + expect(screen.queryByText("Delete this?")).not.toBeInTheDocument(); + }); + + it("closes without firing the action on cancel", async () => { + const user = userEvent.setup(); + const onConfirm = vi.fn(); + render(); + + await user.click(screen.getByRole("button", { name: "Open" })); + await user.click(screen.getByRole("button", { name: "Cancel" })); + + expect(onConfirm).not.toHaveBeenCalled(); + expect(screen.queryByText("Delete this?")).not.toBeInTheDocument(); + }); +}); diff --git a/ui/litellm-dashboard/src/components/ui/alert-dialog.tsx b/ui/litellm-dashboard/src/components/ui/alert-dialog.tsx index 34c45e81055..164dc310ae7 100644 --- a/ui/litellm-dashboard/src/components/ui/alert-dialog.tsx +++ b/ui/litellm-dashboard/src/components/ui/alert-dialog.tsx @@ -122,8 +122,20 @@ function AlertDialogDescription({ ); } -function AlertDialogAction({ className, ...props }: React.ComponentProps) { - return