Skip to content

feat(mcp): i18n + a11y McpStatusBadge status labels#2635

Open
aashir-athar wants to merge 1 commit into
tinyhumansai:mainfrom
aashir-athar:feat/mcp-servers-ui-panel
Open

feat(mcp): i18n + a11y McpStatusBadge status labels#2635
aashir-athar wants to merge 1 commit into
tinyhumansai:mainfrom
aashir-athar:feat/mcp-servers-ui-panel

Conversation

@aashir-athar
Copy link
Copy Markdown

@aashir-athar aashir-athar commented May 25, 2026

Summary

  • Route the 4 hardcoded status labels in McpStatusBadge.tsx ('Connected' / 'Connecting' / 'Disconnected' / 'Error') through useT() using the existing channels.status.* keys. The badge's own docstring says it "Mirrors ChannelStatusBadge"; the labels are identical English; reusing the shared key set avoids redundant translation work.
  • Add role="status" and aria-live="polite" so screen readers announce state changes — matches the alpha-banner pattern already used in McpServersTab.
  • Add a 7-test McpStatusBadge.test.tsx covering each ServerStatus variant, the a11y attributes, the disconnected fallback for unknown statuses, and className passthrough.

Problem

McpStatusBadge.tsx slipped past the #2577 React i18n sweep because it's an isolated leaf component without a co-located test. Lines 7–25 hardcoded English labels (label: 'Connected', etc.) directly in a STATUS_STYLES object, violating the CLAUDE.md rule that every user-visible string in app/src/** must go through useT(). Non-EN users saw English labels on every MCP server connection state.

The same <span> had no role or aria-live, so screen readers wouldn't announce state changes — important for a long-running connection that can transition between connectingconnectederror while the user is on a different part of the page.

Solution

  • Reuse the existing channels.status.{connected,connecting,disconnected,error} i18n keys rather than introducing mcp.status.* duplicates. The labels are character-identical to the channel status set; the badge's docstring already calls it a "mirror" of ChannelStatusBadge. If the MCP vocabulary ever diverges (e.g. adds "spawning" / "handshaking"), the keys can be split then.
  • Add role="status" + aria-live="polite" (matches McpServersTab's alpha banner).
  • Co-locate McpStatusBadge.test.tsx covering: every status variant renders the right label, a11y attributes present, fallback to "Disconnected" for unknown status values, className passthrough preserves built-in classes.

Submission Checklist

  • Tests added or updated — 7 tests added in new McpStatusBadge.test.tsx.
  • Diff coverage ≥ 80% — All changed lines in McpStatusBadge.tsx are exercised by the new test file (it.each over all 4 status variants + a11y + fallback + className).
  • Coverage matrix updated — N/A: behaviour-only change (no new feature; same component, just i18n + a11y).
  • All affected feature IDs listed under ## RelatedN/A: leaf-component fix.
  • No new external network dependencies introduced — N/A.
  • Manual smoke checklist updated if release-cut surfaces touched — N/A: no release-cut surface touched.
  • Linked issue closed via Closes #NNN in ## RelatedN/A: no linked issue.

Impact

  • Runtime/platform impact: none (drop-in component change).
  • Performance/security/migration/compatibility: none.
  • Localized users will now see translated status labels in their locale; screen reader users will hear connection state changes announced.

Related

  • Closes:
  • Follow-up PR(s)/TODOs: none.

AI Authored PR Metadata

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/mcp-servers-ui-panel
  • Commit SHA: (filled by GitHub after push)

Validation Run

  • pnpm --filter openhuman-app format:checkMcpStatusBadge.test.tsx clean; McpStatusBadge.tsx inherits CRLF from Windows checkout (CI on Linux passes)
  • pnpm typecheck — clean
  • Focused tests: pnpm vitest run src/components/channels/mcp/ — 82/82 pass (includes the new file + the pinned Skills.mcp-coming-soon.test.tsx confirming no regression)
  • Rust fmt/check (if changed): N/A (no Rust touched)
  • Tauri fmt/check (if changed): N/A (no Tauri touched)

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Localized status labels + screen-reader announcement of state changes
  • User-visible effect: Non-EN users see translated labels; screen readers announce connection state transitions

Parity Contract

  • Legacy behavior preserved: Yes — labels render identically in English; the fallback for unknown statuses still resolves to "Disconnected" style + label
  • Guard/fallback/dispatch parity checks: Test covers unknown status fallback to "Disconnected" label + style

Duplicate / Superseded PR Handling

  • Duplicate PR(s): None known
  • Canonical PR: This one
  • Resolution: N/A

Summary by CodeRabbit

  • Tests

    • Added comprehensive test suite for the status badge component, verifying proper label rendering across all status types, accessibility attributes, fallback behavior for unknown statuses, and CSS class preservation.
  • Refactor

    • Status badge component refactored to use internationalization for status labels, replacing hardcoded label mappings with language-aware metadata.

Review Change Stack

@aashir-athar aashir-athar requested a review from a team May 25, 2026 13:16
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99b055a8-938d-4ffc-bca5-09e1ba3d5cad

📥 Commits

Reviewing files that changed from the base of the PR and between d997394 and 0e4866d.

📒 Files selected for processing (2)
  • app/src/components/channels/mcp/McpStatusBadge.test.tsx
  • app/src/components/channels/mcp/McpStatusBadge.tsx

📝 Walkthrough

Walkthrough

McpStatusBadge component refactored to use i18n-based status metadata instead of hardcoded labels. The STATUS_META structure maps each ServerStatus to translation keys and CSS classes. Component now uses the useT() hook for translation. Comprehensive test suite added covering label rendering, accessibility, fallback behavior, and className handling.

Changes

McpStatusBadge i18n refactoring

Layer / File(s) Summary
Status metadata and i18n integration
app/src/components/channels/mcp/McpStatusBadge.tsx
STATUS_META replaces the previous hardcoded STATUS_STYLES map, storing i18nKey and className for each ServerStatus. Component uses useT() hook to translate and render the current status metadata, removing static label output.
Test coverage
app/src/components/channels/mcp/McpStatusBadge.test.tsx
Vitest suite verifies label rendering per ServerStatus value, accessibility attributes (role="status" and aria-live="polite"), runtime fallback to "Disconnected" for unknown status, and preservation of built-in classes when custom className is appended.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

working

Suggested reviewers

  • graycyrus

Poem

A badge shifts status with grace and care,
i18n keys floating through the air, 🐰
Tests ensure it speaks and lives,
Accessible labels, good vibes it gives.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding i18n (internationalization) support and a11y (accessibility) improvements to McpStatusBadge status labels, which directly matches the core objectives of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant