From 9e21ef879f47ce3c70c74679df1ee09058bf3f9f Mon Sep 17 00:00:00 2001 From: dotta Date: Wed, 18 Mar 2026 21:26:36 -0500 Subject: [PATCH] Show agent name in inbox approval labels (e.g. "Hire Agent: Designer") Instead of the generic "Hire Agent" label, display the agent's name from the approval payload for hire_agent approvals across inbox, approval card, and approval detail views. Co-Authored-By: Paperclip Co-Authored-By: Claude Opus 4.6 --- ui/src/components/ApprovalCard.tsx | 4 ++-- ui/src/components/ApprovalPayload.tsx | 9 +++++++++ ui/src/pages/ApprovalDetail.tsx | 4 ++-- ui/src/pages/Inbox.tsx | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ui/src/components/ApprovalCard.tsx b/ui/src/components/ApprovalCard.tsx index ee0a4163..2123fc57 100644 --- a/ui/src/components/ApprovalCard.tsx +++ b/ui/src/components/ApprovalCard.tsx @@ -2,7 +2,7 @@ import { CheckCircle2, XCircle, Clock } from "lucide-react"; import { Link } from "@/lib/router"; import { Button } from "@/components/ui/button"; import { Identity } from "./Identity"; -import { typeLabel, typeIcon, defaultTypeIcon, ApprovalPayloadRenderer } from "./ApprovalPayload"; +import { approvalLabel, typeIcon, defaultTypeIcon, ApprovalPayloadRenderer } from "./ApprovalPayload"; import { timeAgo } from "../lib/timeAgo"; import type { Approval, Agent } from "@paperclipai/shared"; @@ -32,7 +32,7 @@ export function ApprovalCard({ isPending: boolean; }) { const Icon = typeIcon[approval.type] ?? defaultTypeIcon; - const label = typeLabel[approval.type] ?? approval.type; + const label = approvalLabel(approval.type, approval.payload as Record | null); const showResolutionButtons = approval.type !== "budget_override_required" && (approval.status === "pending" || approval.status === "revision_requested"); diff --git a/ui/src/components/ApprovalPayload.tsx b/ui/src/components/ApprovalPayload.tsx index 3eb793d6..97cb1ad5 100644 --- a/ui/src/components/ApprovalPayload.tsx +++ b/ui/src/components/ApprovalPayload.tsx @@ -7,6 +7,15 @@ export const typeLabel: Record = { budget_override_required: "Budget Override", }; +/** Build a contextual label for an approval, e.g. "Hire Agent: Designer" */ +export function approvalLabel(type: string, payload?: Record | null): string { + const base = typeLabel[type] ?? type; + if (type === "hire_agent" && payload?.name) { + return `${base}: ${String(payload.name)}`; + } + return base; +} + export const typeIcon: Record = { hire_agent: UserPlus, approve_ceo_strategy: Lightbulb, diff --git a/ui/src/pages/ApprovalDetail.tsx b/ui/src/pages/ApprovalDetail.tsx index 741f9657..c3f27de6 100644 --- a/ui/src/pages/ApprovalDetail.tsx +++ b/ui/src/pages/ApprovalDetail.tsx @@ -8,7 +8,7 @@ import { useBreadcrumbs } from "../context/BreadcrumbContext"; import { queryKeys } from "../lib/queryKeys"; import { StatusBadge } from "../components/StatusBadge"; import { Identity } from "../components/Identity"; -import { typeLabel, typeIcon, defaultTypeIcon, ApprovalPayloadRenderer } from "../components/ApprovalPayload"; +import { approvalLabel, typeIcon, defaultTypeIcon, ApprovalPayloadRenderer } from "../components/ApprovalPayload"; import { PageSkeleton } from "../components/PageSkeleton"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; @@ -203,7 +203,7 @@ export function ApprovalDetail() {
-

{typeLabel[approval.type] ?? approval.type.replace(/_/g, " ")}

+

{approvalLabel(approval.type, approval.payload as Record | null)}

{approval.id}

diff --git a/ui/src/pages/Inbox.tsx b/ui/src/pages/Inbox.tsx index 2ddd4ed4..74a6144a 100644 --- a/ui/src/pages/Inbox.tsx +++ b/ui/src/pages/Inbox.tsx @@ -18,7 +18,7 @@ import { IssueRow } from "../components/IssueRow"; import { PriorityIcon } from "../components/PriorityIcon"; import { StatusIcon } from "../components/StatusIcon"; import { StatusBadge } from "../components/StatusBadge"; -import { defaultTypeIcon, typeIcon, typeLabel } from "../components/ApprovalPayload"; +import { approvalLabel, defaultTypeIcon, typeIcon } from "../components/ApprovalPayload"; import { timeAgo } from "../lib/timeAgo"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; @@ -253,7 +253,7 @@ function ApprovalInboxRow({ isPending: boolean; }) { const Icon = typeIcon[approval.type] ?? defaultTypeIcon; - const label = typeLabel[approval.type] ?? approval.type; + const label = approvalLabel(approval.type, approval.payload as Record | null); const showResolutionButtons = approval.type !== "budget_override_required" && ACTIONABLE_APPROVAL_STATUSES.has(approval.status);