Skip to content

feat(ui): analytics dashboard time-window selector (#2199) - #4945

Closed
RealDiligent wants to merge 1 commit into
JSONbored:mainfrom
RealDiligent:feat/ui-analytics-window-2199
Closed

feat(ui): analytics dashboard time-window selector (#2199)#4945
RealDiligent wants to merge 1 commit into
JSONbored:mainfrom
RealDiligent:feat/ui-analytics-window-2199

Conversation

@RealDiligent

Copy link
Copy Markdown
Contributor

Summary

  • Add 7d / 30d / 90d ToggleGroup to the /app/analytics header
  • Thread the selected window through useApiResource(operatorDashboardPath(days)) so usage summary + command-usefulness re-fetch on change
  • Persist the choice in local storage; restore on reload
  • Backend: honor ?days= on GET /v1/app/operator-dashboard and clamp to supported windows

Scope note (addresses #4747 review): gate-precision, cycle-time, fleet, recommendation-quality, and MCP adoption keep their existing fixed lookbacks (90d / 7d). Only usage summary metrics and command usefulness follow the selector.

Closes #2199

Test plan

  • npm run test --workspace=@jsonbored/gittensory-ui -- src/lib/analytics-window.test.ts (6 tests)
  • npx vitest run test/unit/operator-dashboard.test.ts (includes fixed-90d gate/cycle-time regression guard)
  • Rebased onto latest main

UI Evidence

Page / Feature Before After
/app/analytics header
before: fixed 30d window, no selector

after: 7d/30d/90d toggle drives usage fetch

@RealDiligent
RealDiligent requested a review from JSONbored as a code owner July 11, 2026 02:01
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.24%. Comparing base (65422c8) to head (eb63446).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4945      +/-   ##
==========================================
- Coverage   94.24%   94.24%   -0.01%     
==========================================
  Files         444      444              
  Lines       38854    38862       +8     
  Branches    14157    14159       +2     
==========================================
+ Hits        36617    36624       +7     
  Misses       1577     1577              
- Partials      660      661       +1     
Flag Coverage Δ
shard-1 51.33% <80.00%> (-0.15%) ⬇️
shard-2 45.46% <10.00%> (+0.03%) ⬆️
shard-3 41.85% <10.00%> (-0.04%) ⬇️
shard-4 52.06% <100.00%> (+0.16%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/api/routes.ts 94.25% <100.00%> (+<0.01%) ⬆️
src/services/operator-dashboard.ts 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add a persisted 7d/30d/90d toggle on /app/analytics that re-keys the
operator-dashboard fetch and threads days through the backend payload.

Closes JSONbored#2199

Co-authored-by: Cursor <cursoragent@cursor.com>
@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 11, 2026
@loopover-orb

loopover-orb Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-11 02:27:12 UTC

6 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · dirty

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): src/services/operator-dashboard.ts (matched src/services/**).

Review summary
Adds a 7/30/90-day ToggleGroup to /app/analytics, threads the selection through operatorDashboardPath into useApiResource, persists it via useLocalStorage, and clamps `?days=` server-side in operator-dashboard.ts/routes.ts. The scope note is honored correctly: gate-eval and cycle-time stay pinned to a new GATE_ANALYTICS_WINDOW_DAYS=90 constant and MCP adoption keeps its own fixed 7d `mcpSince`, independent of the new variable `usageSince`/`windowDays`, so the previously-fixed cards genuinely can't drift with the selector. Tests cover clamp behavior, the fixed-90d regression guard, and window-driven refetching. One unverified detail: `getCommandUsefulnessSummary(env, { windowDays })` is called with an options object but that function's definition isn't in this diff — the pre-existing `commandUsefulness.windowDays` field on the payload type suggests the option already existed, but worth a contributor confirmation.

Nits — 6 non-blocking
  • operator-dashboard.ts: `clampOperatorDashboardWindowDays` is invoked once in routes.ts and again inside `buildOperatorDashboardPayload` — collapse to a single clamp point (have the route pass the raw query value and let the payload builder be the sole authority) to avoid two sources of truth for the same guard.
  • Please confirm `getCommandUsefulnessSummary` (not touched in this diff) already accepts a `{ windowDays }` options param — if it doesn't, this call site won't actually vary the result and the two new payload tests would be exercising a no-op.
  • app.analytics.tsx: the ToggleGroup only renders once `windowHydrated` is true, so the header briefly renders without the selector on first paint — minor, but consider a fixed-width skeleton to avoid layout shift.
  • The weeklyValueReport `days` field now varies with the selected window (previously always fixed at 7) — this isn't mentioned in the scope note alongside gate/cycle-time/fleet/MCP; confirm that's an intentional behavior change and not an oversight.
  • src/services/operator-dashboard.ts: pick one layer (route or service) to own `clampOperatorDashboardWindowDays` and drop the redundant call in the other.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2199
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 299 registered-repo PR(s), 132 merged, 23 issue(s).
Contributor context ✅ Confirmed Gittensor contributor RealDiligent; Gittensor profile; 299 PR(s), 23 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Review context
  • Author: RealDiligent
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, JavaScript, Ruby, Svelte, TypeScript, Markdown, MDX
  • Official Gittensor activity: 299 PR(s), 23 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/app/analytics desktop before /app/analytics after /app/analytics
/app/analytics mobile before /app/analytics (mobile) after /app/analytics (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb

loopover-orb Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Gittensory is closing this pull request on the maintainer's behalf (conflicts with the base branch — resolve and open a fresh PR). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

feat(ui): time-window selector for the analytics dashboard

2 participants