Commit Graph
4 Commits
Author SHA1 Message Date
lukaszraczylo a25ebf0567 fix(webui): resilient dashboard polling (SF7)
useDashboardStore.refresh() used Promise.all across overview/usage/
targets: one route rejecting threw before any of the three state
fields were assigned, so a single flaky GET /admin/api/targets blanked
the already-working Providers and Usage views too.

Switched to Promise.allSettled with per-section assignment: a
fulfilled result updates its own field, a rejected one leaves the
PREVIOUS value in place rather than nulling it. lastUpdated still
advances on a partial success (some fresh data did arrive); error
names which section(s) failed. A 401/403 on any section still defers
to the auth store exactly as before (AdminApiError check unchanged).

Added dashboard.spec.ts — the first Pinia store under vitest in this
package (a store needs no DOM, so it fits the existing 'node'
environment without pulling in jsdom); vite.config.ts's own test-scope
comment updated to say so.
2026-08-21 19:16:32 +01:00
lukaszraczylo 7ad573b63e feat(webui): MCP & Agents admin tab
New 'MCP & Agents' tab (after Charts) fed by GET /admin/api/targets:
two Card panels, each a sortable DataTable (reusing DataTable/
SortHeaderButton — no hand-rolled table markup) listing configured
MCP servers and agents with name, url (muted, truncated with a title
tooltip), access (Badge per allowed group, muted 'All groups' when
unrestricted — the same idiom UsageView's own group Access block
already uses), and req/min, req/day, req/month.

- types/api.ts: AdminTargetCountersView/AdminTargetView/
  AdminTargetsResponse matching admin.go's JSON exactly.
- stores/dashboard.ts: targets fetched in the SAME Promise.all/5s
  poll as overview and usage — one store, one timer, not a third.
- lib/target-columns.ts: shared ColumnDef set both DataTables use.
- components/TargetsView.vue: SearchInput + useSearchQuery name
  filter (inline matching, mirroring ProvidersView's own single-field
  aliasMatches — not every filter needs a lib/*-search.ts module).
2026-08-21 18:27:04 +01:00
lukaszraczylo bb4fa4420e refactor(webui): rename Overview tab to Providers
Mechanical rename: OverviewView.vue -> ProvidersView.vue (file, component
import, tab label/value in App.vue), plus doc-comment/README references
across webui/ that named the view by its old tab label.

The backend GET /admin/api/overview endpoint, adminOverviewResponse type,
and the frontend AdminOverviewResponse/dashboard.overview field all keep
their original names unchanged (API surface) -- only the UI tab label and
the component/file that renders it changed. No behavior or layout change
to the view itself.
2026-08-21 13:17:11 +01:00
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