From bc9005c14980778a115639e599bd69e44d5bef71 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Thu, 13 Aug 2026 09:39:37 -0700 Subject: [PATCH] refactor(ui): migrate SectionHeader and ToolsSection to shadcn --- ui/litellm-dashboard/eslint-suppressions.json | 12 +- .../LogDetailsDrawer/SectionHeader.tsx | 107 +++++++----------- .../view_logs/ToolsSection/ToolsSection.tsx | 62 +++++----- 3 files changed, 74 insertions(+), 107 deletions(-) diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index a4dcf0f6c73..70fb98d36da 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -3848,11 +3848,6 @@ "count": 1 } }, - "src/components/view_logs/LogDetailsDrawer/SectionHeader.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/view_logs/LogDetailsDrawer/SimpleMessageBlock.tsx": { "no-restricted-imports": { "count": 1 @@ -3893,11 +3888,6 @@ "count": 1 } }, - "src/components/view_logs/ToolsSection/ToolsSection.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/view_logs/VectorStoreViewer.tsx": { "no-restricted-imports": { "count": 1 @@ -4028,4 +4018,4 @@ "count": 1 } } -} +} \ No newline at end of file diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SectionHeader.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SectionHeader.tsx index 817928f170c..93e9953b2ee 100644 --- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SectionHeader.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SectionHeader.tsx @@ -2,10 +2,10 @@ * SectionHeader - Datadog-style header with icon, label, metrics, and copy */ -import { Typography, Button, Tooltip } from "antd"; -import { MessageOutlined, CopyOutlined, DownOutlined, UpOutlined } from "@ant-design/icons"; - -const { Text } = Typography; +import { ChevronDown, ChevronUp, Copy, MessageSquare } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; +import { cn } from "@/lib/cva.config"; interface SectionHeaderProps { type: "input" | "output"; @@ -29,80 +29,57 @@ export function SectionHeader({ return (
{ - if (onToggleCollapse) { - e.currentTarget.style.background = "#f5f5f5"; - } - }} - onMouseLeave={(e) => { - e.currentTarget.style.background = "#fafafa"; - }} + className={cn( + "flex items-center justify-between bg-muted px-4 py-2.5 transition-colors", + isCollapsed ? "border-b-0" : "border-b border-border", + onToggleCollapse ? "cursor-pointer hover:bg-accent" : "cursor-default", + )} > -
- {/* Collapse Arrow */} - {onToggleCollapse && ( -
- {isCollapsed ? ( - - ) : ( - - )} -
- )} - - {/* Icon + Label */} -
- {type === "input" ? ( - +
+ {onToggleCollapse && + (isCollapsed ? ( + ) : ( - + + ))} + +
+ {type === "input" ? ( + + ) : ( + )} - {type === "input" ? "Input" : "Output"} + {type === "input" ? "Input" : "Output"}
- {/* Tokens */} {tokens !== undefined && ( - - Tokens: {tokens.toLocaleString()} - + Tokens: {tokens.toLocaleString()} )} - {/* Cost */} - {cost !== undefined && ( - - Cost: ${cost.toFixed(6)} - - )} + {cost !== undefined && Cost: ${cost.toFixed(6)}} - {/* Turn count */} {turnCount !== undefined && turnCount > 0 && ( - - Turns: {turnCount} - + Turns: {turnCount} )}
- {/* Copy Button */} - -
); diff --git a/ui/litellm-dashboard/src/components/view_logs/ToolsSection/ToolsSection.tsx b/ui/litellm-dashboard/src/components/view_logs/ToolsSection/ToolsSection.tsx index 2a8cdd6a1ce..46c820caa25 100644 --- a/ui/litellm-dashboard/src/components/view_logs/ToolsSection/ToolsSection.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/ToolsSection/ToolsSection.tsx @@ -3,18 +3,19 @@ * and indicates which ones were actually called in the response */ -import { Collapse, Typography } from "antd"; +import { useState } from "react"; +import { ChevronDown, ChevronRight } from "lucide-react"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { LogEntry } from "../columns"; import { parseToolsFromLog } from "./utils"; import { ToolItem } from "./ToolItem"; -const { Text } = Typography; - interface ToolsSectionProps { log: LogEntry; } export function ToolsSection({ log }: ToolsSectionProps) { + const [open, setOpen] = useState(false); const tools = parseToolsFromLog(log); // Don't render if no tools @@ -32,34 +33,33 @@ export function ToolsSection({ log }: ToolsSectionProps) { const hasMoreTools = tools.length > 2; return ( -
- -

Tools

- - {totalTools} provided, {calledTools} called - - - • {toolNamePreview} - {hasMoreTools && "..."} - -
- ), - children: ( -
- {tools.map((tool) => ( - - ))} -
- ), - }, - ]} - /> +
+ + + {open ? ( + + ) : ( + + )} +
+

Tools

+ + {totalTools} provided, {calledTools} called + + + • {toolNamePreview} + {hasMoreTools && "..."} + +
+
+ +
+ {tools.map((tool) => ( + + ))} +
+
+
); }