action-dialog
Controlled dialog that renders a Quickback action's inputs, runs it, and shows the result or error.
npx shadcn add @quickback/action-dialogimport { useState } from "react"
import { buttonVariants } from "@/components/ui/button"
import { ActionDialog } from "@/components/action-dialog"
function CloseJobButton({ id }: { id: string }) {
const [open, setOpen] = useState(false)
return (
<>
<button type="button" className={buttonVariants({ variant: "outline" })} onClick={() => setOpen(true)}>
Close
</button>
<ActionDialog table="jobs" action="close" id={id} open={open} onOpenChange={setOpen} />
</>
)
}The dialog is controlled. You own open and render your own trigger. It
ships no trigger, so it never needs base-ui's render= or Radix's asChild.
Props
| Prop | Type | Description |
|---|---|---|
table | string | Schema-registry table name. Required. |
action | string | Action name as declared on the table. Required. |
id | string | Record id. Required for record-bound actions. Leave it out for standalone ones. |
params | Record<string, string> | Path parameters for standalone actions whose path has them. |
open | boolean | Required. |
onOpenChange | (open: boolean) => void | Required. |
onSuccess | (output: unknown) => void | Called with the action's output. |
Behavior
- Inputs come from the action's
inputFieldsin the schema registry. Enums render as selects, booleans as checkboxes, and numbers as number inputs. Everything else renders as text. Array inputs take a comma-separated list. Empty fields are left out of the input. - Title and description come from the action's
cms.label(else its name) and itsdescription. - Confirmation. An action with
cms.destructiveorcms.confirmasks before it runs. A stringconfirmis the message. Otherwise the dialog asks<Action> can't be undone. Continue?(destructive) orRun <Action>?.confirm: falsenever asks. - Access. When the caller's roles
plainly fail the action's
access.roles, the dialog showsYour role can't run <Action>.instead of the form. - On success, the dialog shows "Done." and the output as JSON. Every
cached query for the table is invalidated, so an open
ResourceTablerefreshes. - On error, the problem's
detailshows at the top. Per-field messages show under their inputs. Guard rejections, access denials (403), and failed record preconditions all arrive this way. - An unknown
actionshows"<name>" is not an action on <Table>.Calling a record-bound action withoutidfails withAction "<name>" on "<table>" needs a record id.