From 8a052c1ea6fbe20ebd59fb12b72d95a54d18c877 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Apr 2026 12:47:09 +0000 Subject: [PATCH] feat(ui): templates/KeyInfoHeader to shadcn - antd Button/Typography/Tooltip/Space/Divider/Flex + @ant-design icon set (10 icons) \u2192 shadcn Button/Tooltip + lucide equivalents (ArrowLeft, RefreshCcw, Trash2, Plus, User, Mail, Calendar, Clock, Zap, Shield, Wallet, Copy, Check). - Built a small CopyableInline helper for the Typography.Text copyable contract. Regenerate-tooltip only renders when the prop is set so the Tooltip doesn't flash empty. - Destructive buttons use outline + text-destructive / border-destructive tinting for Reset Spend and Delete. - Horizontal rule dividers are plain
. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang --- .../components/templates/KeyInfoHeader.tsx | 206 +++++++++++++----- 1 file changed, 151 insertions(+), 55 deletions(-) diff --git a/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.tsx b/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.tsx index 93ebae9c4be..a73a3bbcc28 100644 --- a/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.tsx +++ b/ui/litellm-dashboard/src/components/templates/KeyInfoHeader.tsx @@ -1,22 +1,28 @@ -import React from "react"; -import { Button, Typography, Tooltip, Space, Divider, Flex } from "antd"; +import React, { useState } from "react"; +import { Button } from "@/components/ui/button"; import { - ArrowLeftOutlined, - SyncOutlined, - DeleteOutlined, - PlusOutlined, - UserOutlined, - MailOutlined, - CalendarOutlined, - ClockCircleOutlined, - ThunderboltOutlined, - SafetyCertificateOutlined, - TransactionOutlined, -} from "@ant-design/icons"; + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { + ArrowLeft, + Calendar, + Check, + Clock, + Copy, + Mail, + Plus, + RefreshCcw, + Shield, + Trash2, + User, + Wallet, + Zap, +} from "lucide-react"; import LabeledField from "../common_components/LabeledField"; -const { Title, Text } = Typography; - export interface KeyInfoData { keyName: string; keyId: string; @@ -41,6 +47,48 @@ interface KeyInfoHeaderProps { regenerateTooltip?: string; } +const CopyableInline: React.FC<{ + text: string; + label: string; + copyTooltip: string; +}> = ({ text, label, copyTooltip }) => { + const [copied, setCopied] = useState(false); + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(text); + setCopied(true); + setTimeout(() => setCopied(false), 1500); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_err) { + /* noop */ + } + }; + return ( + + {label} + + + + + + {copied ? "Copied!" : copyTooltip} + + + + ); +}; + export function KeyInfoHeader({ data, onBack, @@ -56,83 +104,131 @@ export function KeyInfoHeader({ return (
{onCreateNew && ( -
-
)} -
-
- +
- - {data.keyName} - - - Key ID: {data.keyId} - +

+ +

+
+ +
{canModifyKey && ( - - - - - - +
+ + + + + + + + {regenerateTooltip && ( + {regenerateTooltip} + )} + + {onResetSpend && ( - )} - - +
)} - +
- - - } /> +
+
+ } + /> } + icon={} truncate copyable defaultUserIdCheck /> - +
- +
- - } /> +
+ } + /> } + icon={} truncate copyable defaultUserIdCheck /> - +
- +
- - } /> - } /> - - +
+ } + /> + } + /> +
+
); }