Skip to content

feat(canvas): WebSocket connection status indicator in Toolbar - #37

Merged
HongmingWang-Rabbit merged 2 commits into
mainfrom
fix/audit-run9
Apr 14, 2026
Merged

HongmingWang-Rabbit merged 2 commits into
mainfrom
fix/audit-run9

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Summary

  • Adds a live/reconnecting/offline status pill to the canvas Toolbar so users can see at a glance whether real-time updates are flowing
  • wsStatus Zustand field added to the canvas store; ReconnectingSocket lifecycle hooks (onopen, onclose, disconnect) drive it
  • WsStatusPill component renders: green dot "Live" when connected, amber pulsing "Reconnecting" when the socket is in exponential-backoff retry, red dot "Offline" when explicitly disconnected

Files changed

File Change
canvas/src/store/canvas.ts Added wsStatus: 'connected'|'connecting'|'disconnected' + setWsStatus action (initial: 'connecting')
canvas/src/store/socket.ts Wire setWsStatus into ReconnectingSocket.connect(), onopen, onclose, disconnect()
canvas/src/components/Toolbar.tsx Subscribe to wsStatus; render WsStatusPill after workspace count section
canvas/src/store/__tests__/socket.test.ts Add setWsStatus: vi.fn() to all three canvas store mock sites

Test plan

  • cd canvas && npm test — 369/369 passing (was 369 before, unchanged count)
  • cd canvas && npm run build — production build clean, no TypeScript errors
  • Manual: load canvas — pill should show amber "Reconnecting" briefly, then green "Live" once WS connects
  • Manual: kill platform container — pill should flip to amber "Reconnecting" within 3s (first reconnect delay)
  • Manual: restart platform — pill should return to green "Live" after socket re-establishes

🤖 Generated with Claude Code

Dev Lead Agent and others added 2 commits April 14, 2026 08:21
Adds a live/reconnecting/offline pill to the Toolbar so users can see
at a glance whether the canvas is receiving real-time updates.

Changes:
- canvas/src/store/canvas.ts: add wsStatus ('connected'|'connecting'|
  'disconnected') field + setWsStatus action to CanvasState (initial:
  'connecting')
- canvas/src/store/socket.ts: wire setWsStatus into ReconnectingSocket —
  'connecting' on connect() call, 'connected' in onopen, 'connecting'
  in onclose (will reconnect), 'disconnected' in disconnect()
- canvas/src/components/Toolbar.tsx: subscribe to wsStatus; render
  WsStatusPill (green "Live" / amber pulsing "Reconnecting" / red
  "Offline") after the workspace count section
- canvas/src/store/__tests__/socket.test.ts: add setWsStatus: vi.fn()
  to the canvas store mock (global factory, beforeEach reset, and the
  mid-test override in the onmessage test)

369/369 canvas tests passing, production build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gap 1 — WS_URL now derives from NEXT_PUBLIC_PLATFORM_URL when
NEXT_PUBLIC_WS_URL is not set (http→ws, appends /ws; https→wss).
Operators need only one env var. NEXT_PUBLIC_WS_URL remains an explicit
override escape hatch.

Gap 2 — Add canvas/.env.example documenting NEXT_PUBLIC_PLATFORM_URL
(required) and NEXT_PUBLIC_WS_URL (optional override, commented out).

Gap 3 — Toolbar fires showToast("Live updates restored", "success")
when wsStatus transitions connecting→connected. mountedRef (set after
2 s) suppresses the toast on the very first page-load connection so
only genuine reconnects notify the user.

Gap 4 — New canvas/src/store/__tests__/socket.url.test.ts (6 tests):
  · fallback to ws://localhost:8080/ws when no env set
  · http→ws derivation from NEXT_PUBLIC_PLATFORM_URL
  · https→wss derivation
  · NEXT_PUBLIC_WS_URL override takes precedence
  · api.ts PLATFORM_URL fallback
  · api.ts reads NEXT_PUBLIC_PLATFORM_URL

375/375 tests passing, production build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor Author

7-gate verification PASS.

  • Gate 1: CI 6/6 green
  • Gate 2: canvas build OK
  • Gate 3: 375/375 vitest passing
  • Gate 4: diff clean — no secrets, documented NEXT_PUBLIC_* env vars, no raw URL exposure, no XSS
  • Gate 5: no confirm/alert/prompt; dark theme tokens (emerald-400 / amber-400 / red-400 on zinc); 'use client' present; reuses Zustand wsStatus (single source of truth)
  • Gate 6: hooks top-level, clearTimeout cleanup, consistent connected/connecting/disconnected transitions, dedicated URL-derivation tests added
  • Gate 7: Playwright smoke passes

UI polish / status display — merging.

@HongmingWang-Rabbit
HongmingWang-Rabbit merged commit ea6fdd5 into main Apr 14, 2026
6 checks passed
@HongmingWang-Rabbit
HongmingWang-Rabbit deleted the fix/audit-run9 branch April 14, 2026 09:21
molecule-ai Bot pushed a commit that referenced this pull request Apr 21, 2026
feat(canvas): WebSocket connection status indicator in Toolbar
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