Skip to content

fix: restore analysis on reload instead of rendering a blank page - #205

Merged
bhavik-mangla merged 1 commit into
AOSSIE-Org:mainfrom
bhavik-mangla:fix/blank-screen-no-analysis
Aug 30, 2026
Merged

fix: restore analysis on reload instead of rendering a blank page#205
bhavik-mangla merged 1 commit into
AOSSIE-Org:mainfrom
bhavik-mangla:fix/blank-screen-no-analysis

Conversation

@bhavik-mangla

@bhavik-mangla bhavik-mangla commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Addressed Issues:

Fixes #204

What was wrong

The analytical model lived only in React state. Any fresh page load — a reload, a bookmark, a shared link — started with model === null, and nothing restored it. Two different failures followed:

Route Behaviour before
/overview, /repositories, /contributors, /analytics, /governance if (!model) return null → blank page between navbar and footer
/network crashTypeError: Cannot read properties of null (reading 'allRepos') at NetworkPage.jsx:257

NetworkPage was simply missing the null guard its five sibling pages already had.

Reproducible on main today: npm run dev, then open http://localhost:5173/overview directly — <main> renders with 0 children.

The fix

Two parts, matching the approach suggested in #204:

1. Persist and restore the analysis (src/services/cache.js)

Cache the model in IndexedDB with a one-hour TTL — the same "1HR intelligent cache" the landing page already advertises — and restore it on startup. A reload now costs zero API calls, which matters against a 60 req/hr unauthenticated budget.

IndexedDB rather than localStorage because a single model runs to several megabytes for a large org (239 repos for one the size of Vercel), well past the ~5MB quota. Every cache operation is best-effort, so a private window or a browser with storage disabled degrades to the old behaviour rather than breaking.

Audit and pull-request results are cached too — they are the most expensive data to refetch.

2. Guard the routes that need a model (src/components/RequireAnalysis.jsx)

For the case where there is genuinely nothing to restore (no cache, or an expired one), redirect to the organization picker — the only place an analysis can be started — instead of rendering an empty page.

Two details worth review:

  • It waits on hydrating, so a reload is not redirected away a fraction of a second before its own cached data arrives.
  • It keeps children mounted while explore() refetches, because explore() clears the model first and each page shows its own skeleton during that window.

/settings and /support-us are deliberately left unguarded — Settings is where a PAT is added, so it has to work with no analysis loaded.

One subtlety handled: the write-back skips the save that would immediately follow a restore. Without that, every page load would stamp a fresh savedAt and the entry would never reach its TTL.

Verification

Check Result
npm test 44/44 passing (40 before, +4 new for RequireAnalysis)
npm run build ✅ passes
Reload with a valid cache ✅ analysis restored, stays on route, 0 GitHub API calls
Reload with an expired cache ✅ stale entry purged, redirected to the picker
TTL not refreshed by a restore ✅ entry still reports its original age after reload
/network with no analysis ✅ redirects — was 4 console TypeErrors
/overview with no analysis ✅ redirects — was 0 children in <main>

Verified in a real browser against real IndexedDB, seeding the cache directly so the restore path could be exercised without spending API quota.

Additional Notes:

Checklist

  • My code follows the project's code style and conventions
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contributing Guidelines

⚠️ AI Notice - Important!

AI assistance was used to diagnose and implement this change. Both failure modes were reproduced on a clean main checkout before any code was written, the fix was verified in a real browser against real IndexedDB (including TTL expiry and the no-API-calls claim), and the full build and test suite were run before submitting. New unit tests cover all four states of the route guard.

Summary by CodeRabbit

  • New Features

    • Restores recent analysis results automatically when returning to the app.
    • Saves analysis data locally for up to one hour, including analytics and audit results.
    • Shows analysis pages only when analysis data is available.
  • Bug Fixes

    • Prevents analysis pages from displaying blank or broken states during loading and restoration.
    • Fixes errors when opening the Network page without loaded analysis data.

The analytical model lived only in React state, so any fresh page load
discarded it. Five pages then returned null and rendered nothing between
the navbar and the footer, and /network threw "Cannot read properties of
null (reading 'allRepos')".

Cache the analysis in IndexedDB with a one-hour TTL, matching the cache
the landing page already advertises, and restore it on startup so a
reload, bookmark or shared link costs no API calls. IndexedDB rather than
localStorage because a single model can run to several megabytes.

Add a RequireAnalysis route guard for the case where there is genuinely
nothing to restore: send people to the organization picker, which is the
only place an analysis can be started. It waits for the cache read so a
reload is not redirected away a moment before its own data arrives, and
keeps pages mounted while explore() refetches so their skeletons show.

Also add the missing null guard to NetworkPage so it is safe on its own,
matching the other data pages.
Copilot AI lite review requested due to automatic review settings August 30, 2026 05:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added bug Something isn't working enhancement New feature or request frontend Frontend changes javascript JavaScript/TypeScript changes tests Test changes size/L 201-500 lines changed external-contributor External contributor labels Aug 30, 2026
@bhavik-mangla
bhavik-mangla merged commit d182a64 into AOSSIE-Org:main Aug 30, 2026
4 of 5 checks passed
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9c6120f8-426f-4360-b735-b82c0bd39f0c

📥 Commits

Reviewing files that changed from the base of the PR and between 4ce2822 and 4ab8c0c.

📒 Files selected for processing (6)
  • src/App.jsx
  • src/components/RequireAnalysis.jsx
  • src/components/RequireAnalysis.test.jsx
  • src/context/AppContext.jsx
  • src/pages/NetworkPage.jsx
  • src/services/cache.js

Walkthrough

The app now persists the latest analysis in IndexedDB, restores it during startup, exposes hydration state, and guards analysis routes. Tests cover restoration, loading, missing-model, and rendered-model states.

Changes

Analysis state flow

Layer / File(s) Summary
IndexedDB analysis cache
src/services/cache.js
Adds best-effort IndexedDB storage with a one-hour TTL for the latest analysis.
App state hydration and persistence
src/context/AppContext.jsx
Restores cached analysis during startup, exposes hydrating, and saves later analysis changes without refreshing the cache timestamp during restoration.
Analysis route guard and validation
src/components/RequireAnalysis.jsx, src/components/RequireAnalysis.test.jsx, src/App.jsx, src/pages/NetworkPage.jsx
Guards analysis routes, preserves pages during loading, redirects when analysis is unavailable, tests state combinations, and prevents null model access in NetworkPage.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant AppProvider
  participant IndexedDB
  participant RequireAnalysis
  participant AnalysisRoute
  Browser->>AppProvider: start application
  AppProvider->>IndexedDB: loadAnalysis()
  IndexedDB-->>AppProvider: cached analysis or null
  AppProvider->>RequireAnalysis: expose model, loading, hydrating
  RequireAnalysis->>AnalysisRoute: render when analysis is available
  RequireAnalysis-->>Browser: redirect to / when no model and not loading
Loading

Suggested labels: Typescript Lang

Suggested reviewers: rahul-vyas-dev, ri1tik

Poem

A rabbit watched the cache store bright,
IndexedDB held data tight.
Hydration crossed the startup stream,
Routes waited safely for the model’s gleam.
No null fields caused a fright,
The dashboard hopped back into sight.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size/L 201-500 lines changed and removed size/L 201-500 lines changed labels Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request external-contributor External contributor frontend Frontend changes javascript JavaScript/TypeScript changes size/L 201-500 lines changed tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Data disappears on page refresh (Overview, Contributors, etc.)

2 participants