Skip to content

fix(meshcore): show Connecting… instead of Disconnected while status loads#3380

Merged
Yeraze merged 1 commit into
mainfrom
claude/great-dijkstra-vHLB5
Jun 8, 2026
Merged

fix(meshcore): show Connecting… instead of Disconnected while status loads#3380
Yeraze merged 1 commit into
mainfrom
claude/great-dijkstra-vHLB5

Conversation

@Yeraze

@Yeraze Yeraze commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Summary

When a user navigates to the MeshCore source page, the header connection chip was immediately showing "Disconnected" for the entire duration of the initial snapshot fetch — even when the device was fully connected. This created a confusing discrepancy where the dashboard sidebar showed "Connected" (from its polled cache) while the source page showed "Disconnected" (the default null → false state before the snapshot resolved).

The root cause is that mcStatus starts as null, and mcStatus?.connected ?? false evaluates to false, causing "Disconnected" to render prematurely. The fix treats mcStatus === null as a loading state and shows "Connecting…" until the snapshot completes.

Changes

  • src/pages/MeshCoreSourcePage.tsx: Derive statusLoading = mcStatus === null; render .status-indicator.connecting + source.status_connecting ("Connecting") while loading, then switch to "Connected" / "Disconnected" once the snapshot resolves
  • src/pages/MeshCoreSourcePage.test.tsx: Add two new test cases — one verifying "Disconnected" renders after a connected: false snapshot, and one verifying "Connected" renders after a connected: true snapshot

Reuses the existing .status-indicator.connecting CSS class and the source.status_connecting i18n key — no new styles or translations needed.

Issues Resolved

Fixes #3379

Documentation Updates

No documentation changes needed.

Testing

  • Unit tests pass (4 tests in MeshCoreSourcePage.test.tsx, full suite green)
  • TypeScript compiles cleanly
  • Open a MeshCore source page — the header should show "Connecting…" briefly on load, then update to "Connected" (if device is up) or "Disconnected" (if device is down)
  • Verify the chip no longer shows "Disconnected" during the snapshot load window when the device is actually connected

🤖 Generated with Claude Code


Generated by Claude Code

…loads

The MeshCoreSourcePage header chip derives connected state from mcStatus,
which starts null until the snapshot fetch completes. This caused the header
to always show "Disconnected" for the duration of the initial load — even
when the device was fully connected — because `null?.connected ?? false`
evaluates to false.

Fix: treat mcStatus === null as a loading state and render the existing
.status-indicator.connecting CSS class with "Connecting…" text, matching
the same idiom used by the DashboardSidebar. Once the snapshot resolves,
the chip correctly shows "Connected" or "Disconnected" based on the actual
device state.

Closes #3379

https://claude.ai/code/session_019ReNykYcCcqLfYRTEqAWYY
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Claude finished @Yeraze's task —— View job


PR Review: MeshCore Status Loading State Fix

Review Tasks:

  • Analyze main implementation in MeshCoreSourcePage.tsx
  • Review test changes and coverage
  • Check for potential bugs or edge cases
  • Assess code quality and best practices
  • Evaluate performance and security considerations
  • Provide comprehensive feedback

✅ Overall Assessment: APPROVED

This is a well-implemented fix that addresses a clear UX issue. The solution is elegant, well-tested, and follows project conventions.

Code Quality & Implementation

Excellent Implementation

  • Clean logic: The statusLoading = mcStatus === null approach is simple and correct
  • Proper state handling: Treating null as a distinct loading state rather than defaulting to false
  • Reuses existing infrastructure: Leverages .status-indicator.connecting CSS class and source.status_connecting i18n key
  • Maintains type safety: Good use of TypeScript with proper nullable types

📍 Key Implementation Details (src/pages/MeshCoreSourcePage.tsx:63-111)

// Clear separation of concerns
const statusLoading = mcStatus === null;
const connected = mcStatus?.connected ?? false;

// Conditional rendering with proper fallback chain
className={`status-indicator ${statusLoading ? 'connecting' : connected ? 'connected' : 'disconnected'}`}

Test Coverage

Comprehensive Test Suite

The new tests properly validate the fix:

  1. Disconnected state test (MeshCoreSourcePage.test.tsx:160-166): Verifies "Disconnected" appears after connected: false snapshot
  2. Connected state test (MeshCoreSourcePage.test.tsx:168-214): Validates "Connected" appears after connected: true snapshot
  3. Existing tests preserved: Permission gating and API routing tests remain intact

🔍 Test Quality Notes

  • Tests use proper waitFor() to handle async state changes
  • Mock responses are realistic and comprehensive
  • Good separation between happy path and edge cases

Performance Considerations

Minimal Performance Impact

  • Zero overhead: Simple boolean check mcStatus === null
  • No additional renders: Uses existing state management patterns
  • Efficient conditional rendering: Single ternary operator chain

Security Considerations

No Security Concerns

  • UI-only change: No new API calls or data handling
  • Maintains permission model: Still respects canReadConnection gating
  • No exposure of sensitive data: Status display is already public info

Best Practices Adherence

Follows Project Standards

  • Consistent with codebase patterns: Similar loading state handling seen elsewhere
  • Proper TypeScript usage: Nullable types and optional chaining
  • I18n compliance: Uses existing translation keys
  • CSS reuse: Leverages existing .status-indicator.connecting class

Edge Cases & Potential Issues

Well Handled

  1. Permission denied scenarios: Properly tested and unchanged
  2. Network failures: Will maintain loading state until retry succeeds
  3. Rapid state changes: State transitions are atomic and predictable

🤔 Minor Consideration

The loading state persists indefinitely if the snapshot request fails completely. However, this is actually desirable behavior - showing "Connecting..." is better than prematurely showing "Disconnected" on network errors.

Suggested Improvements

📝 Documentation Enhancement (Optional)

Consider adding a brief comment explaining the loading state logic:

// mcStatus is null until the snapshot loads — show "Connecting…" instead of
// "Disconnected" so the header doesn't mislead the user during the initial fetch.
const statusLoading = mcStatus === null;

(Note: This comment already exists at line 63-64!)

Summary

This PR effectively solves the described UX issue with a minimal, well-tested implementation. The fix is:

  • Correct: Properly handles the loading state
  • Complete: Includes appropriate test coverage
  • Consistent: Follows established patterns
  • Clean: No unnecessary complexity

Recommendation: Merge when ready


@Yeraze Yeraze merged commit 48740f7 into main Jun 8, 2026
18 of 19 checks passed
Yeraze added a commit that referenced this pull request Jun 10, 2026
The [4.9.4] section captured only the entries present in [Unreleased] when
the release branch was cut. Add the remaining changes that shipped in
v4.9.4 but merged without their own CHANGELOG entries: {DATE}/{TIME}
tokens (#3382), MeshCore JSONL export (#3391), system theme (#3344),
Map Pin Style fix (#3364), MeshCore connecting state (#3380), the Map
Analysis security gate (#3365/#3366), and the 11 dependency bumps.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

[BUG] 4.9.3 - Main dashboard shows node is Connected but Node dashboard is always disconnected

2 participants