feat(069-B2): usage charts + Usage.vue + Dashboard switcher#571
Merged
Conversation
Spec 069 Stream B2 (frontend). Surfaces the activity-log usage aggregate (GET /api/v1/activity/usage, A3) as Web UI graphs. - usage/CallHistogram.vue, ResponseSizeRanking.vue (size-based token-sink proxy, FR-006), ErrorRateChart.vue (+ per-tool p50/p95 latency table), Timeline.vue (calls/errors stacked, honors window/filters, FR-008). - views/Usage.vue: tokens-saved headline from ServerTokenMetrics (FR-007), window selector (24h/7d/all), status/sort filters, empty/low-data state (FR-009), 30s auto-refresh against the cached snapshot. - Dashboard.vue: Overview<->Usage switcher (T016); Overview kept via v-show so its state survives a round-trip (SC-006); Usage code-split via defineAsyncComponent so the chart bundle/fetch don't block first paint (SC-004). - api.ts getActivityUsage() (T017) + UsageAggregateResponse types. - utils/usageFormat.ts shared formatters + palette. Covers T016-T023. Verified with a Playwright sweep (7/7, 0 console errors) against populated + empty instances; report kept local per QA-report policy. Related #745
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 26795813629 --repo smart-mcp-proxy/mcpproxy-go
|
# Conflicts: # frontend/src/services/api.ts # frontend/src/views/Dashboard.vue
This was referenced Jun 2, 2026
Merged
Dumbris
added a commit
that referenced
this pull request
Jun 3, 2026
The 069-B1 switcher tests broke when 069-B2 (#571) swapped the inline usage panel for the real async Usage.vue. Two mount-side problems: - The usage panel wrapper carried v-if="usageEverActive", so it was absent from the DOM on first paint and the exists() assertion failed. Move the lazy gate onto the inner <Suspense> instead: the wrapper div is now always present (hidden via v-show), while the chart bundle + usage fetch inside UsageView still mount only on first switch (SC-004), and the Overview subtree is preserved across switches (SC-006). - shallowMount stubbed both <Suspense> and the async UsageView, so the real Usage.vue never rendered (no fetch, no window buttons). Un-stub Suspense and swap the async wrapper for an eagerly-imported Usage.vue so the fetch-on-activation and window-re-fetch logic actually runs; a dynamic import() never settles inside flushPromises + Suspense. Usage's chart grandchildren stay shallow-stubbed (no jsdom canvas). Related #571
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec 069 Stream B2 (Frontend/Vue) — MCP-752
Surfaces the activity-log usage aggregate (
GET /api/v1/activity/usage, shipped in A3 #565) as Web UI usage graphs. Covers tasks T016–T023.What's in it
components/usage/CallHistogram.vue— calls per tool (horizontal bars).components/usage/ResponseSizeRanking.vue— token-sink ranking by total response bytes, captioned as a size-based proxy for token cost (FR-006).components/usage/ErrorRateChart.vue— error-rate bars + per-tool p50/p95 latency table (T019).components/usage/Timeline.vue— stacked calls/errors over time, honoring the active window/filters (FR-008).views/Usage.vue— tokens-saved headline fromServerTokenMetrics(FR-007), window selector (24h/7d/all), status + sort filters, and an empty/low-data state (FR-009); light 30s auto-refresh against the cached snapshot.views/Dashboard.vue— Overview↔Usage switcher (T016). Overview is kept withv-showso its state survives a round-trip (SC-006); Usage is code-split viadefineAsyncComponentso the chart bundle + fetch don't block Dashboard first paint (SC-004 — confirmed: separate 13 kBUsage-*.jschunk).services/api.tsgetActivityUsage()(T017) +UsageAggregateResponsetypes.utils/usageFormat.ts— shared formatters + palette.Verification (T023)
Playwright sweep (CLAUDE.md Web-UI workflow) against a populated instance (everything server, 4 tools seeded via MCP) and a fresh empty instance:
vue-tsctypecheck clean;vite build+go build(embedded UI) green.HTML report + screenshots kept local (per repo QA-report policy), not committed.
PR — do not self-merge. Related #745.