Files
traefik-llmgateway/webui
lukaszraczylo 655bbcbf2c feat(webui): vue admin panel source
Vue 3 + TypeScript + Pinia + Tailwind v4 + shadcn-vue + Chart.js admin
panel source under webui/, built with Vite. Views: Overview (providers,
redis/cache/retry status, model aliases), Usage (per-user/per-group/total
tables with tokensIn/tokensOut/cost + limits), Charts (scope selector,
req/tokens(stacked in-out)/cost metric tabs, 24h/30d/12mo window
switcher, fed by GET /admin/api/usage/history). Pinia stores: auth
(sessionStorage key gate, x-api-key header, 401/403 re-prompt),
dashboard (5s poll), history (fetch-on-selection + 30s refresh).

Design: deliberate neutral warm-neutral palette with a signature teal
accent (no default Inter/purple-gradient/glassmorphism), real
typographic hierarchy via the platform UI/mono font stacks (zero
external assets - no Google Fonts), dark+light via prefers-color-scheme
(no class toggle, no theme switcher). Charts: zero-based bars, honest
axes, Okabe-Ito colorblind-safe series, tokens-in/out as a
distinguishable stacked pair.

vite.config.ts: base '/admin/' (matches admin.go's route layout) and
build.modulePreload.polyfill:false (no inline bootstrap script, so the
tightened admin CSP needs no 'unsafe-inline'). Code-split: Chart.js
(ChartsView) loads lazily, not in the initial bundle.

generate.mjs reads dist/ after `vite build` and writes
../admin_assets_gen.go (not committed by this change) - base64-encodes
every asset, decoded once at package-var init; documented rationale in
the script's own header comment.

Hygiene: webui/go.mod walls webui/ off from the repo root's `go build`/
`vet`/`test ./...` (npm's node_modules bundles a stray .go file that
would otherwise be swept in); tools/yaegi-check/main.go excludes webui/
from its GOPATH copy for the same reason. webui/ export-ignored
(.gitattributes) from release source tarballs; webui/node_modules/
gitignored. tsconfig.app.json/tsconfig.node.json's JSONC comments
dropped (TS itself is fine with either; the global pre-commit JSON
validator is not) - no config values changed.
2026-08-21 09:21:41 +01:00
..
2026-08-21 09:21:41 +01:00
2026-08-21 09:21:41 +01:00
2026-08-21 09:21:41 +01:00
2026-08-21 09:21:41 +01:00
2026-08-21 09:21:41 +01:00

Admin panel (webui)

Source for the traefik-llmgateway read-only admin dashboard: Vue 3 + TypeScript + Pinia + Tailwind v4 + shadcn-vue + Chart.js, built with Vite.

See the repo root README.md's Admin section for what the dashboard shows and how its API/auth works, and the Development section for make admin-ui — the only way this directory's output (../admin_assets_gen.go) is meant to be regenerated. Nothing here runs at request time: the plugin serves the built, baked-in output, never webui/ itself.

Local development

npm ci
npm run dev      # Vite dev server — /admin/api/* calls need a real
                  # gateway to fetch from; point one at the same origin or
                  # accept the "refresh failed" state while iterating on
                  # layout/styling alone.
npm run build     # what `make admin-ui` runs, plus webui/generate.mjs

Structure

  • src/stores/ — Pinia: auth (the sessionStorage key gate), dashboard (Overview/Usage, 5s poll), history (Charts, fetch-on-selection + 30s refresh).
  • src/components/ — AuthGate, OverviewView, UsageView, ChartsView/UsageChart, UsageTable; ui/ holds the shadcn-vue primitives this panel actually uses (Card, Table, Tabs, Button, Input, Alert, Select, Badge) — nothing installed and unused.
  • src/lib/ — api.ts (the /admin/api/* fetch wrapper), format.ts, key-storage.ts, chart-setup.ts.
  • src/types/api.ts — TypeScript mirrors of admin.go's JSON response shapes (adminOverviewResponse, adminUsageResponse, usageHistoryResponse).
  • generate.mjs — reads dist/ after vite build and writes ../admin_assets_gen.go; see its own header comment for why every asset is base64-encoded rather than embedded as a raw string literal.