diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index a4dcf0f6c73..47db33f1a79 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -3809,11 +3809,6 @@ "count": 1 } }, - "src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx": { "no-nested-ternary": { "count": 3 @@ -3863,11 +3858,6 @@ "count": 1 } }, - "src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/view_logs/LogDetailsDrawer/TruncatedValue.tsx": { "no-restricted-imports": { "count": 1 diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx new file mode 100644 index 00000000000..055e400167b --- /dev/null +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx @@ -0,0 +1,28 @@ +import { render, screen } from "@testing-library/react"; +import { describe, expect, it } from "vitest"; +import { JsonViewer } from "./JsonViewer"; + +describe("JsonViewer", () => { + it("should render a placeholder and no tree when the log entry carries no payload", () => { + render(); + + expect(screen.getByText("No data")).toBeInTheDocument(); + expect(screen.queryByRole("tree")).not.toBeInTheDocument(); + }); + + it("should render the payload as a tree exposing its keys", () => { + render(); + + expect(screen.getByRole("tree")).toBeInTheDocument(); + expect(screen.getByText(/model/)).toBeInTheDocument(); + expect(screen.getByText(/stream/)).toBeInTheDocument(); + expect(screen.queryByText("No data")).not.toBeInTheDocument(); + }); + + it("should treat an empty payload as data rather than showing the placeholder", () => { + render(); + + expect(screen.getByRole("tree")).toBeInTheDocument(); + expect(screen.queryByText("No data")).not.toBeInTheDocument(); + }); +}); diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx index 0a873a7e255..af99eee0d16 100644 --- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx @@ -1,10 +1,7 @@ -import { Typography } from "antd"; import { JsonView, defaultStyles } from "react-json-view-lite"; import "react-json-view-lite/dist/index.css"; import { JSON_MAX_HEIGHT, COLOR_BG_LIGHT, SPACING_LARGE } from "./constants"; -const { Text } = Typography; - interface JsonViewerProps { data: any; mode: "formatted"; @@ -15,7 +12,7 @@ interface JsonViewerProps { * Uses an interactive tree component for easy navigation. */ export function JsonViewer({ data }: JsonViewerProps) { - if (!data) return No data; + if (!data) return No data; return (
count.toLocaleString(); + +describe("TokenFlow", () => { + it("should render the total followed by its prompt and completion breakdown", () => { + render(); + + expect(screen.getByText("12 (9 prompt tokens + 3 completion tokens)")).toBeInTheDocument(); + }); + + it("should group large counts the way the reader's locale does", () => { + render(); + + expect( + screen.getByText( + `${localised(1323579)} (${localised(1234567)} prompt tokens + ${localised(89012)} completion tokens)`, + ), + ).toBeInTheDocument(); + }); + + it("should fall back to zero for counts the log entry does not carry", () => { + render(); + + expect(screen.getByText("12 (0 prompt tokens + 0 completion tokens)")).toBeInTheDocument(); + }); +}); diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx index 5eec3c0a5cb..2183ed53f35 100644 --- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx +++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx @@ -1,7 +1,3 @@ -import { Typography } from "antd"; - -const { Text } = Typography; - interface TokenFlowProps { prompt?: number; completion?: number; @@ -14,9 +10,9 @@ interface TokenFlowProps { */ export function TokenFlow({ prompt = 0, completion = 0, total = 0 }: TokenFlowProps) { return ( - + {total.toLocaleString()} ({prompt.toLocaleString()} prompt tokens + {completion.toLocaleString()} completion tokens) - + ); }