From 4a3dcd5e8ebc579e5e3dc5f2bcf00c702899e57d Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Sat, 29 Aug 2026 11:53:14 -0700 Subject: [PATCH] refactor(ui): give the collapsed log drawer its own sidebar toggle Open, the trace sidebar is byte-identical to before: the toggle sits over its header exactly where it did, and the header keeps the padding that makes room for it. Collapsed, that button has nowhere to live, so the drawer header shows one instead, on the model row or the request id row when the log names no model. Both come from SidebarToggle, so they cannot drift in design. The chevrons now point the way the sidebar will move: right while it is open, left while it is collapsed. --- .../LogDetailsDrawer/LogDetailsDrawer.tsx | 160 +++++++++--------- .../LogDetailsDrawer/SidebarToggle.tsx | 10 +- 2 files changed, 88 insertions(+), 82 deletions(-) diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx index 9849c95de71..ddd0a650c04 100644 --- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx @@ -312,90 +312,94 @@ export function LogDetailsDrawer({ {logEntry?.request_id ? `Request ${logEntry.request_id} details` : "Request details"} -
+
{!isSidebarCollapsed && ( -
-
- setIsSidebarCollapsed((collapsed) => !collapsed)} - /> -
-
- {isSessionMode ? "Session" : "Trace"} + setIsSidebarCollapsed(true)} + className="absolute top-2 left-2 z-raised" + /> + )} + {!isSidebarCollapsed && ( +
+
+
+
+
+ {isSessionMode ? "Session" : "Trace"} +
+
+ {leftPanelDisplayId} + +
-
- {leftPanelDisplayId} - -
-
- {logsForList.length} req - {[ - isSessionMode - ? llmCount - : logsForList.filter( - (row) => - !MCP_CALL_TYPES.includes(row.call_type) && !AGENT_CALL_TYPES.includes(row.call_type), - ).length, - isSessionMode - ? agentCount - : logsForList.filter((row) => AGENT_CALL_TYPES.includes(row.call_type)).length, - isSessionMode - ? mcpCount - : logsForList.filter((row) => MCP_CALL_TYPES.includes(row.call_type)).length, - ].map((count, i) => { - const label = [" LLM", " Agent", " MCP"][i]; - return count > 0 ? ( - - · - {count} - {label} - - ) : null; - })} - · - {isSessionMode ? getSpendString(totalSessionCost) : getSpendString(currentLog.spend || 0)} - {isSessionMode && ( - <> +
+
+ {logsForList.length} req + {[ + isSessionMode + ? llmCount + : logsForList.filter( + (row) => !MCP_CALL_TYPES.includes(row.call_type) && !AGENT_CALL_TYPES.includes(row.call_type), + ).length, + isSessionMode + ? agentCount + : logsForList.filter((row) => AGENT_CALL_TYPES.includes(row.call_type)).length, + isSessionMode + ? mcpCount + : logsForList.filter((row) => MCP_CALL_TYPES.includes(row.call_type)).length, + ].map((count, i) => { + const label = [" LLM", " Agent", " MCP"][i]; + return count > 0 ? ( + · - {sessionDurationSeconds}s - - )} -
+ {count} + {label} + + ) : null; + })} + · + {isSessionMode ? getSpendString(totalSessionCost) : getSpendString(currentLog.spend || 0)} {isSessionMode && ( -
- {cacheHitCount}/{logsForList.length} cached -
- )} - {isSessionMode && sessionTruncated && ( -
- Showing most recent {logsForList.length} of {sessionTotalCount} -
- )} - {isSessionMode && ( - setSessionSortMode(value as SessionLogSortMode)} - > - - - Duration - - - Start time - - - + <> + · + {sessionDurationSeconds}s + )}
+ {isSessionMode && ( +
+ {cacheHitCount}/{logsForList.length} cached +
+ )} + {isSessionMode && sessionTruncated && ( +
+ Showing most recent {logsForList.length} of {sessionTotalCount} +
+ )} + {isSessionMode && ( + setSessionSortMode(value as SessionLogSortMode)} + > + + + Duration + + + Start time + + + + )}
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SidebarToggle.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SidebarToggle.tsx index b4ee191f4cd..a1ba7ff2491 100644 --- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SidebarToggle.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/SidebarToggle.tsx @@ -1,21 +1,23 @@ import { ChevronLeft, ChevronRight } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/cva.config"; export interface SidebarToggleProps { isCollapsed: boolean; onToggle: () => void; + className?: string; } -export function SidebarToggle({ isCollapsed, onToggle }: SidebarToggleProps) { +export function SidebarToggle({ isCollapsed, onToggle, className }: SidebarToggleProps) { return ( ); }