Skip to content

feat: network loading spinner for pyvis graphs (shared shell)#11

Merged
razinkele merged 7 commits into
mainfrom
feat/network-loading-spinner
Jul 5, 2026
Merged

feat: network loading spinner for pyvis graphs (shared shell)#11
razinkele merged 7 commits into
mainfrom
feat/network-loading-spinner

Conversation

@razinkele

Copy link
Copy Markdown
Owner

What

Adds a loading spinner over every pyvis network view (Topology, CLD, Leverage, Metrics, Intervention, Loops, Simplify) in both the SESPy and MosaicSES apps, while the graph builds — auto-hidden the moment it's drawn.

How

  • Pseudo-elements, not an injected node. The spinner is .pyvis-network-output.is-loading::before/::after (veil + "Rendering network…" label + ring) in the shell skin. The pyvis fork runs el.innerHTML='' on every render, which would wipe an injected child — pseudo-elements and the is-loading class survive it.
  • Shell JS (sespy/dashboard.py, injected in head_content): adds is-loading on shiny:recalculating, removes it on the fork's always-sent <id>_ready input (NOT _stabilized, which never fires for the physics-off hierarchical CLD), with an 8s fallback. Sticky data-sespy-net-shown / data-sespy-net-hidden markers make the behavior testable non-racily.
  • CSS mirrored into both skins. MosaicSES serves its own www/sespy-skin.css copy, so the shared JS reaches it but the CSS must be duplicated (mirror commit lives in the MosaicSES repo). z-index stays below the fork's modal (1000); pointer-events:none; rgba() fallback before color-mix; prefers-reduced-motion disables the spin.

Testing

  • New CLD e2e (tests/test_cld_e2e.py) asserts the show→hide cycle happened via _ready (data-sespy-net-hidden == "ready"), so the 8s fallback can't mask a broken hide. 5/5 green locally.
  • Unit suite: 474 passed, 1 skipped. Full e2e: 30/31 (sole failure = pre-existing report_e2e WeasyPrint/PDF local-env issue, passes in CI's conda env).
  • Verified visually + geometrically in both apps (spinner paints over the canvas, outputCoversCanvas: True).

Review

Design went through two multi-agent review rounds (7 agents) — caught 1 blocker (innerHTML='' wipe → pseudo-elements) + 4 majors (physics-off _ready hide; vacuous e2e → provenance marker; cross-app CSS). A code review of the implementation returned Ready-to-merge with only non-reachable minors. Spec + plan: docs/superpowers/{specs,plans}/2026-07-02-network-loading-spinner*.md.

Companion change

MosaicSES CSS mirror: razinkele/MosaicSES (separate PR).

🤖 Generated with Claude Code

razinkele and others added 7 commits July 2, 2026 21:44
Design for a centered spinner overlay over every pyvis network output, shown
during server build AND client vis-network stabilization, auto-hidden on the
fork's already-emitted _stabilized signal (8s fallback). Lives entirely in the
SESPy shell (dashboard.py + sespy-skin.css); no pyvis fork changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task 1: shell CSS + injected JS (show on shiny:recalculating, hide on
<id>_stabilized + 8s fallback) with a CLD end-state e2e. Task 2: cross-app
manual smoke checklist. No pyvis fork changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round-1 review (4 orthogonal agents) found: (1) BLOCKER — fork's el.innerHTML=''
wipes any injected overlay; (2) MAJOR — default CLD is physics-off so _stabilized
never fires; (3) MAJOR — e2e was near-vacuous; (4) MAJOR — MosaicSES serves a
separate skin copy, so shared CSS wouldn't reach it. Revisions: pseudo-element
spinner (survives innerHTML=''); hide on the always-sent <id>_ready (not
_stabilized); sticky data-sespy-net-shown marker for a non-racy e2e; mirror the
CSS into both apps' skins; bind handlers at parse time (no first-load race).
Dropped the MutationObserver entirely.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round-2 review (3 agents) confirmed the pseudo-element mechanism paints above the
canvas, _ready fires every render, and $ is available at parse (cross-app safe).
Two fixes folded in: (1) HIGH — add data-sespy-net-hidden provenance ('ready' vs
'fallback') and assert 'ready' in the e2e, so the 8s fallback can't mask a broken
_ready hide; (2) nit — rgba() background fallback before color-mix for older
engines. Confirmed SESPy + MosaicSES are the only two sespy.dashboard consumers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds is-loading (+ sticky data-sespy-net-shown) on shiny:recalculating and
removes it on the fork's always-sent <id>_ready input, with an 8s fallback and
data-sespy-net-hidden provenance ('ready' vs 'fallback'). CLD e2e asserts the
show->hide cycle happened via _ready (not the fallback), non-racy. 5/5 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@razinkele, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a17f80b8-a54d-4624-95c1-0bc9f561bdc6

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd15d7 and 6609624.

📒 Files selected for processing (6)
  • docs/2026-07-02-network-spinner-smoke-checklist.md
  • docs/superpowers/plans/2026-07-02-network-loading-spinner.md
  • docs/superpowers/specs/2026-07-02-network-loading-spinner-design.md
  • sespy/dashboard.py
  • tests/test_cld_e2e.py
  • www/sespy-skin.css
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/network-loading-spinner

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.

@razinkele razinkele merged commit c958a88 into main Jul 5, 2026
6 checks passed
@razinkele razinkele deleted the feat/network-loading-spinner branch July 5, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant