fix(ui): add a content-shaped loading skeleton to the analytics dashboard#6949
Conversation
…oard app.analytics.tsx's StateBoundary had no loadingSkeleton, falling through to the generic centered spinner -- the same gap JSONbored#6816 fixed for app.operator.tsx, relative to app.runs.tsx/miner-panel.tsx/ maintainer-panel.tsx/dead-letter-queue-panel.tsx. Adds AnalyticsDashboardSkeleton mirroring the real layout (header + window toggle, stat grid, card sections) and wires it via loadingSkeleton on the existing StateBoundary. Closes JSONbored#6817
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-17 15:04:43 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk 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.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Visual previewClick 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.
|




Summary
app.analytics.tsx'sStateBoundary(lines ~164-176) had noloadingSkeletonprop, falling through to the generic centered spinner — the same gap #6816 just fixed forapp.operator.tsx, relative to the same set of siblings (app.runs.tsx,miner-panel.tsx,maintainer-panel.tsx,dead-letter-queue-panel.tsx) that already provide a content-shaped skeleton.Added
AnalyticsDashboardSkeleton, mirroring the real dashboard's layout:data.metricssection)Wired via
loadingSkeleton={<AnalyticsDashboardSkeleton />}on the existingStateBoundary, following the exact same pattern as #6816 and its other siblings.Test plan
apps/loopover-ui/src/routes/app.analytics.test.tsx(2 tests,ProductAnalyticsexported for direct testing, matching this repo's established pattern):.animate-pulseblocks) renders duringstatus: "loading", and neither the genericLoadingStatetitle nor its spinner (.animate-spin) appearsstatus: "ready") datanpm run ui:lint,npm run ui:typecheck— clean (0 errors)git diff --check,npm run actionlint— cleanapps/**is outside Codecov'scoverage.include— no patch-coverage obligation for this UI-only change; added the regression tests regardless per the issue's own Test Coverage Requirements note/app/analyticssits behind the same app-shell session-restoration gate documented in Operator dashboard loading state falls back to a generic spinner instead of a content-shaped skeleton #6816's PR (fix(ui): add a content-shaped loading skeleton to the operator dashboard #6945), which this sandbox can't get past without a real session. The skeleton reuses the sameSkeletonprimitive and layout shape already shipped (and visually verified) inMaintainerDashboardSkeleton/OperatorDashboardSkeleton— no new visual design to verify. The automated tests directly assert the actual DOM swap, which is the change's real surface area.Closes #6817