Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d26c52a
feat(ui): extract trace drawer into a shared SidePanel that closes on…
yujonglee-berri Oct 4, 2026
282f36e
feat(ui): center Lens mode switch in a notch joined to the content card
yujonglee-berri Oct 4, 2026
5297476
fix(ui): stronger Lens frame border and header spacing
yujonglee-berri Oct 4, 2026
7ecdb25
fix(ui): align Lens notch fillet with the notch border
yujonglee-berri Oct 4, 2026
07eb0dd
fix(ui): centered Lens loading/error states and proxy JSON calls in dev
yujonglee-berri Oct 4, 2026
e7c3092
refactor(ui): theme-scale type and shape in trace views, aligned pane…
yujonglee-berri Oct 4, 2026
cf324d3
fix(ui): restore AgentTracesSection emptied in e7c3092571
yujonglee-berri Oct 4, 2026
efa2210
feat(ui): move Set up tracing into the empty runs state
yujonglee-berri Oct 4, 2026
59b69cd
refactor(ui): let the runs table gate the setup CTA on an empty range
yujonglee-berri Oct 4, 2026
95fcfa7
feat(ui): mark Lens demo mode with a blue toggle and frame instead of…
yujonglee-berri Oct 4, 2026
472cf07
fix(ui): draw Lens notch corners with CSS borders and thicken the dem…
yujonglee-berri Oct 4, 2026
908b7ac
refactor(ui): drop the redundant Lens timeline header
yujonglee-berri Oct 4, 2026
c5a4e17
fix(ui): keep drawer shortcuts out of open menus and use usehooks-ts …
yujonglee-berri Oct 4, 2026
ff21c83
fix(ui): offer tracing setup when filters hide every run
yujonglee-berri Oct 4, 2026
613f669
feat(ui): replace Lens runs filters with a single ProseMirror query box
yujonglee-berri Oct 4, 2026
a20c0b2
fix(ui): keep the open trace on screen while the next one loads
yujonglee-berri Oct 4, 2026
2ae4988
feat(ui): virtualize the Lens runs table and drop its status footer
yujonglee-berri Oct 4, 2026
42d635e
refactor(ui): load traces with Suspense and show the previous run via…
yujonglee-berri Oct 4, 2026
264cb02
fix(ui): open investigation details from list rows instead of the edi…
yujonglee-berri Oct 4, 2026
73e4a8a
fix(ui): harden Lens investigation and run search behavior
yujonglee-berri Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ui/litellm-dashboard/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ const eslintConfig = [
],
rules: { "local/no-ad-hoc-z-index": ["error", { allowPopupLayer: true }] },
},
{
files: ["src/components/view_logs/TraceView/**/*.tsx", "src/components/lens/**/*.tsx"],
ignores: ["src/**/*.test.tsx"],
rules: { "local/no-arbitrary-design-value": "error" },
},
{
files: ["tests/eslint-rules/**/*.{ts,tsx}"],
rules: { "local/no-noop-hover-variant": "off", "local/no-ad-hoc-z-index": "off" },
Expand Down
9 changes: 8 additions & 1 deletion ui/litellm-dashboard/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ const nextConfig = {
? {
async rewrites() {
return {
beforeFiles: [{ source: "/ui/:path*", destination: "/:path*" }],
beforeFiles: [
{
source: "/:path*",
has: [{ type: "header", key: "content-type", value: "application/json.*" }],
destination: `${devProxyUrl}/:path*`,
},
{ source: "/ui/:path*", destination: "/:path*" },
],
fallback: [{ source: "/:path*", destination: `${devProxyUrl}/:path*` }],
};
},
Expand Down
172 changes: 172 additions & 0 deletions ui/litellm-dashboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions ui/litellm-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
"dependencies": {
"@anthropic-ai/sdk": "0.92.0",
"@base-ui/react": "^1.6.0",
"@handlewithcare/react-prosemirror": "3.2.9",
"@headlessui/tailwindcss": "0.2.2",
"@heroicons/react": "1.0.6",
"@hookform/resolvers": "5.4.0",
"@shadcn/react": "0.3.1",
"@tanstack/react-pacer": "0.22.1",
"@tanstack/react-query": "5.100.7",
"@tanstack/react-table": "8.21.3",
"@tanstack/react-virtual": "3.14.13",
"@types/papaparse": "5.5.2",
"class-variance-authority": "0.7.1",
"clsx": "^2.1.1",
Expand All @@ -49,18 +51,24 @@
"openapi-fetch": "^0.17.0",
"openapi-react-query": "^0.5.4",
"papaparse": "5.5.3",
"prosemirror-model": "1.25.12",
"prosemirror-state": "1.4.4",
"prosemirror-view": "1.42.3",
"react": "19.2.8",
"react-copy-to-clipboard": "5.1.1",
"react-dom": "19.2.8",
"react-error-boundary": "6.1.6",
"react-hook-form": "7.82.0",
"react-intersection-observer": "11.0.1",
"react-json-view-lite": "2.5.0",
"react-markdown": "9.1.0",
"react-reconciler": "0.33.0",
"react-syntax-highlighter": "15.6.6",
"recharts": "3.9.2",
"remark-gfm": "4.0.1",
"sonner": "2.0.8",
"tailwind-merge": "3.4.0",
"usehooks-ts": "3.1.1",
"uuid": "14.0.0",
"zod": "4.6.5"
},
Expand Down
2 changes: 2 additions & 0 deletions ui/litellm-dashboard/scripts/eslint-rules/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import noComplexJsxArrow from "./no-complex-jsx-arrow.mjs";
import filenamePascalCase from "./filename-pascal-case.mjs";
import noNoopHoverVariant from "./no-noop-hover-variant.mjs";
import noAdHocZIndex from "./no-ad-hoc-z-index.mjs";
import noArbitraryDesignValue from "./no-arbitrary-design-value.mjs";

const plugin = {
rules: {
Expand All @@ -13,6 +14,7 @@ const plugin = {
"filename-pascal-case": filenamePascalCase,
"no-noop-hover-variant": noNoopHoverVariant,
"no-ad-hoc-z-index": noAdHocZIndex,
"no-arbitrary-design-value": noArbitraryDesignValue,
},
};

Expand Down
23 changes: 2 additions & 21 deletions ui/litellm-dashboard/scripts/eslint-rules/no-ad-hoc-z-index.mjs
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
const AD_HOC_Z = /^-?z-(?:\d+|\[[^\]]*\]|\([^)]*\))$/;

const OPENERS = { "[": "]", "(": ")" };
import { utilityOf } from "./tailwind-utility.mjs";

const utilityOf = (token) => {
const closers = [];
const lastTopLevelColon = [...token].reduce((found, ch, i) => {
if (closers.length > 0 && ch === closers[closers.length - 1]) {
closers.pop();
return found;
}
if (ch in OPENERS) {
closers.push(OPENERS[ch]);
return found;
}
return ch === ":" && closers.length === 0 ? i : found;
}, -1);
return token
.slice(lastTopLevelColon + 1)
.replace(/^!/, "")
.replace(/!$/, "");
};
const AD_HOC_Z = /^-?z-(?:\d+|\[[^\]]*\]|\([^)]*\))$/;

const classify = (token, allowPopupLayer) => {
const utility = utilityOf(token);
Expand Down
Loading
Loading