Skip to content

fix(ui): migrate the pre-rebrand analytics window preference forward - #8753

Merged
JSONbored merged 2 commits into
JSONbored:mainfrom
tryeverything24:fix-analytics-window-8699-v2
Jul 26, 2026
Merged

fix(ui): migrate the pre-rebrand analytics window preference forward#8753
JSONbored merged 2 commits into
JSONbored:mainfrom
tryeverything24:fix-analytics-window-8699-v2

Conversation

@tryeverything24

Copy link
Copy Markdown
Contributor

Closes #8699

What

app.analytics.tsx called useLocalStorage<AnalyticsWindowDays>(ANALYTICS_WINDOW_STORAGE_KEY, DEFAULT_ANALYTICS_WINDOW_DAYS) with no third legacyKey argument. The key was renamed from "gittensory.analytics.windowDays" to "loopover.analytics.windowDays" in the rebrand commit (75450f1d5) that gave app.runs.tsx and app.workbench.tsx their one-time legacyKey migration — this file was missed. Any returning user who had picked a 30d/90d analytics window before the cutover silently reverted to the 7-day default.

How

apps/loopover-ui/src/routes/app.analytics.tsx now passes "gittensory.analytics.windowDays" as the third useLocalStorage argument, matching the app.runs.tsx / app.workbench.tsx pattern exactly. The hook already implements the one-time fallback: if the new key is absent it reads the legacy key, adopts the value, and writes it forward to the new key (leaving the legacy key in place).

Because the fix intentionally introduces one new "gittensory" string into app.analytics.tsx (the pre-rebrand storage key itself — the same intentional historical reference app.runs.tsx/app.workbench.tsx already carry), scripts/branding-drift-baseline.json is regenerated via npm run branding-drift:update in this same commit, exactly as the branding-drift checker's own guidance instructs for a legitimate legacy-key reference. Without it, branding-drift:check fails on the 0 → 1 count increase for this file.

Deliverables

  • The useLocalStorage call for the analytics window preference includes the "gittensory.analytics.windowDays" legacy key.
  • New test in apps/loopover-ui/src/routes/app.analytics.test.tsx: seeds localStorage["gittensory.analytics.windowDays"] = "30", mounts ProductAnalytics, and asserts the toggle group shows 30d selected (data-state="on", 7d "off"), the dashboard is fetched for ?days=30, and localStorage["loopover.analytics.windowDays"] is backfilled with "30" — mirroring the migration tests used for the runs/workbench keys in use-local-storage.test.ts. A companion test pins the no-keys case: 7d default, and no value invented under either key.
  • scripts/branding-drift-baseline.json regenerated (npm run branding-drift:update) for the intentional legacy-key reference; npm run branding-drift:check green.

Before / after

On unfixed main (fix stashed), the new migration test fails exactly as the issue describes — the seeded 30d preference is ignored and the default wins:

× migrates a pre-rebrand gittensory window preference forward instead of resetting to 7d
  AssertionError: expected 'off' to be 'on'   // 7d is "on", 30d is "off"

With the fix:

✓ src/routes/app.analytics.test.tsx (4 tests)
✓ src/lib/use-local-storage.test.ts (11 tests)

ui:typecheck, ui:lint (eslint + prettier) on the changed files, branding-drift:check, and git diff --check all green.

UI Evidence

/app/analytics, served locally (vite dev, preview session per the contributor skill) with localStorage seeded the way a returning pre-rebrand user's browser looks: gittensory.analytics.windowDays = "30" and no loopover.* key. The operator-dashboard API is answered at the network boundary by a fixture so the page renders its loaded state. Look at the window toggle group: before, the stored 30d preference is ignored and 7d is active (the bug); after, the legacy value is migrated forward and 30d is active, with the dashboard fetched for ?days=30. The UI is a dark-mode-only build, so the Light and Dark rows (captured under emulated prefers-color-scheme) render identically by design.

Viewport · Theme Before After
Desktop · Light Desktop light before — stored 30d ignored, 7d active Desktop light after — legacy 30d migrated, 30d active
Desktop · Dark Desktop dark before — stored 30d ignored, 7d active Desktop dark after — legacy 30d migrated, 30d active
Tablet · Light Tablet light before — stored 30d ignored, 7d active Tablet light after — legacy 30d migrated, 30d active
Tablet · Dark Tablet dark before — stored 30d ignored, 7d active Tablet dark after — legacy 30d migrated, 30d active
Mobile · Light Mobile light before — stored 30d ignored, 7d active Mobile light after — legacy 30d migrated, 30d active
Mobile · Dark Mobile dark before — stored 30d ignored, 7d active Mobile dark after — legacy 30d migrated, 30d active

…legacyKey fallback

app.analytics.tsx called useLocalStorage with no third legacyKey
argument, unlike its rebrand siblings app.runs.tsx and app.workbench.tsx.
The storage key was renamed from gittensory.analytics.windowDays to
loopover.analytics.windowDays in the same rebrand commit (75450f1)
that added the legacyKey migration elsewhere, so a returning user who
had picked a 30d/90d window silently reverted to the 7-day default.

Pass gittensory.analytics.windowDays as the legacy key: the hook reads
it once when the new key is absent, adopts the value, and backfills the
new key, exactly like the runs/workbench view preferences. Regenerates
scripts/branding-drift-baseline.json (branding-drift:update) for the
one intentional legacy-key reference this adds, so branding-drift:check
stays green.

Closes JSONbored#8699
@superagent-security

Copy link
Copy Markdown
Contributor

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

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 26, 2026
@loopover-orb

loopover-orb Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-26 05:25:31 UTC

3 files · 1 AI reviewer · no blockers · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
The fix adds the missing third `legacyKey` argument ("gittensory.analytics.windowDays") to the `useLocalStorage` call in app.analytics.tsx, matching the pattern already used in app.runs.tsx/app.workbench.tsx, so returning users' pre-rebrand window preference is now migrated forward instead of silently reverting to the 7-day default. The branding-drift-baseline.json is correctly regenerated to reflect the intentional legacy-key string, and the new test exercises the real migration path (seeding the legacy key, asserting the toggle state, the fetched URL, and the backfilled new key) plus the no-migration default case. This is a narrow, well-targeted one-line fix tied to a real bug (#8699) with solid test coverage of both branches.

Nits — 2 non-blocking
  • The screenshot evidence provided shows no visual diff, which is expected since this is a pure logic/data fix with no UI change, but it's worth noting the screenshots don't actually demonstrate the fix.
  • None beyond what's already covered — the diff is small, focused, and the test asserts the exact behavior described in the PR.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #8699
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: 94 registered-repo PR(s), 44 merged, 4 issue(s).
Contributor context ✅ Confirmed Gittensor contributor tryeverything24; Gittensor profile; 94 PR(s), 4 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The diff adds the legacyKey "gittensory.analytics.windowDays" as the third useLocalStorage argument in app.analytics.tsx, matching the runs/workbench pattern, and adds a test seeding the legacy key, verifying 30d is selected and the new key is backfilled, exactly per the Deliverables.

Review context
  • Author: tryeverything24
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: JavaScript, TypeScript, Python, HTML, C++, Java, PHP, C#
  • Official Gittensor activity: 94 PR(s), 4 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Triage stale or unlinked PRs.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/app/analytics/test desktop before /app/analytics/test
before /app/analytics/test
after /app/analytics/test
after /app/analytics/test
/app/analytics/test mobile before /app/analytics/test (mobile)
before /app/analytics/test (mobile)
after /app/analytics/test (mobile)
after /app/analytics/test (mobile)
/app/analytics desktop before /app/analytics
before /app/analytics
after /app/analytics
after /app/analytics
/app/analytics mobile before /app/analytics (mobile)
before /app/analytics (mobile)
after /app/analytics (mobile)
after /app/analytics (mobile)

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

Scroll preview
Route Before (production) After (this PR's preview)
/app/analytics/test before /app/analytics/test (scroll)
before /app/analytics/test (scroll)
after /app/analytics/test (scroll)
after /app/analytics/test (scroll)
/app/analytics before /app/analytics (scroll)
before /app/analytics (scroll)
after /app/analytics (scroll)
after /app/analytics (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 26, 2026
@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.80%. Comparing base (a93ae0a) to head (759b6d6).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8753   +/-   ##
=======================================
  Coverage   93.80%   93.80%           
=======================================
  Files         797      797           
  Lines       79517    79517           
  Branches    24097    24097           
=======================================
  Hits        74593    74593           
  Misses       3556     3556           
  Partials     1368     1368           
Flag Coverage Δ
backend 95.08% <ø> (ø)

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

@JSONbored
JSONbored merged commit e1e5802 into JSONbored:main Jul 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ui): analytics window preference has no rebrand-migration legacyKey fallback, silently resetting returning users to the 7-day default

2 participants