Agent Ops@paxeer/agent-ops/approval-gateimplemented
Approval gate
Operator approval using Alert + Dialog.
Install
$
pnpm exec designx add @paxeer/agent-ops/approval-gatePreview
Loading preview...
Source code
components/designx/agent-ops/approval-gate.tsxtsx
"use client";
import { useState } from "react";
import {
Alert,
AlertDescription,
AlertTitle,
Button,
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@paxeer/core";
export function ApprovalGate({
title = "Approve outgoing action",
summary = "helix-exec wants to submit a 1.50 ETH limit bid at 2480.40.",
}: {
title?: string;
summary?: string;
}) {
const [decision, setDecision] = useState<"pending" | "approved" | "rejected">("pending");
return (
<Card className="gap-3 py-4" data-slot="approval-gate">
<CardHeader className="px-4">
<CardTitle className="text-[length:var(--md-sys-typescale-title-small-size)]">
{title}
</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-3 px-4">
<Alert variant={decision === "rejected" ? "destructive" : "default"}>
<AlertTitle>
{decision === "pending"
? "Waiting on an operator"
: decision === "approved"
? "Approved"
: "Rejected"}
</AlertTitle>
<AlertDescription>{summary}</AlertDescription>
</Alert>
</CardContent>
<CardFooter className="gap-2 px-4">
<Dialog>
<DialogTrigger asChild>
<Button size="dense" disabled={decision !== "pending"}>
Review
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Confirm approval</DialogTitle>
<DialogDescription>{summary}</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outlined" onClick={() => setDecision("rejected")}>
Reject
</Button>
<Button onClick={() => setDecision("approved")}>Approve</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Button
size="dense"
variant="outlined"
disabled={decision !== "pending"}
onClick={() => setDecision("rejected")}
>
Reject
</Button>
</CardFooter>
</Card>
);
}
Dependencies
Registry dependencies