Skip to content

fix(i18n): localize the integration card status pills - #12208

Closed
smwbev wants to merge 2 commits into
stablyai:mainfrom
smwbev:fix/localize-integration-card-statuses
Closed

smwbev wants to merge 2 commits into
stablyai:mainfrom
smwbev:fix/localize-integration-card-statuses

Conversation

@smwbev

@smwbev smwbev commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Every card under Settings → Integrations builds its status pill from bare string literals inside the JSX call, so the pill stays English with a language pack active while the description right beside it is translated.

#11826 fixed the CLI source-control cards. These are the ones it did not reach:

Card Literals
Task trackers (Linear and friends) Connected, Not connected
Jira Connected, Not connected
Bitbucket, Azure DevOps, Gitea Connected, Configured, Unavailable, Not configured, Optional setup, Auth failed

Same blind spot as before: audit-localization-coverage.mjs inspects JSX attributes and object properties, not conditional expressions handed to a prop, so pnpm verify:localization-coverage stays green while the strings ship untranslated.

Shared helper for the token providers

The three token-configured cards carried near-identical ternaries. Their copy moved into tokenProviderStatusLabel():

statusLabel={tokenProviderStatusLabel({ configured, hasAccount: Boolean(statuses.giteaAccount), status, optional: true })}

One source for states they share, and it keeps token-source-control-integration-cards.tsx under the 400-line gate. Gitea passes optional: true because it works read-only without a token — that is why its unconfigured state reads Optional setup rather than Not configured, and the distinction is now explicit instead of duplicated.

10 keys added by sync:localization-catalog; no existing key was removed or reworded.

Screenshots

No visual change in English — every string keeps its exact wording.

With a Russian language pack on current main, the pills read Not connected, Not configured and Optional setup while everything around them is translated:

Task providers Review providers
Task providers Review providers

Note the second screenshot: GitHub already reads Подключено and GitLab reads Не установлено — those came from #11826 — while Bitbucket, Azure DevOps and Gitea below them are still English. This PR closes that gap.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added src/renderer/src/i18n/integration-card-status-localization.test.ts — 10 assertions pinning the catalog contract, so a card that goes back to a bare literal drops its key from en.json and fails here.

pnpm test: 44 085 passed, 79 skipped. Three files fail on this machine — ssh-posix-command-wrapper (3), agent-exec-handler (2) and updater (1). All three fail identically on a clean main with this branch stashed, so they are pre-existing environment failures.

Note on CI: this PR comes from a fork, so PR Checks sits at action_required until a maintainer approves the workflow run — nothing has failed. The checks above were run locally.

AI Review Report

Reviewed with Claude Opus 5.

  • Cross-platform. No platform branching, no shortcuts, labels, or path handling touched. The helper is pure string selection.
  • SSH / remote / local. The cards already render per-provider status from existing state; no process, credential, or network path changed. The Account scope details block below each pill is untouched.
  • Agents / integrations / git providers. Behaviour-neutral per provider: each card passes the same conditions it evaluated inline. Gitea's softer unconfigured wording is preserved through the explicit optional flag rather than being flattened into the shared path — worth a look during review, since that is the one place where the three cards genuinely differ.
  • Performance. Same number of string lookups as before, on a settings pane that is not a hot path.
  • UI quality. English wording is byte-identical, so pill widths and tones are unchanged.
  • Catalog integrity. 10 keys added, 0 removed, 0 existing values modified; verify:localization-catalog and verify:localization-extraction pass.

Security Audit

Reviewed with Claude Opus 5. No new input handling, command execution, path handling, auth, secrets, dependency, or IPC surface. The diff converts literals into catalog lookups; no credential or token value reaches the changed code — the cards receive only booleans and a status string. No follow-up needed.

Notes

Found while maintaining a full Russian language pack — smwbev/orca-russian, 11 721 strings, 98.2 % of en.json. Translating the whole catalog is what surfaces strings that never reach it.

Related: #11826 (merged, same class of defect), #12105 (open, date formatting), #12106 (open, plural forms).

X: @silentmegawatt · GitHub: @smwbev

The status pill on every Settings → Integrations card is built from bare string
literals inside the JSX call, so it stays English with a language pack active
while the description right beside it is translated. stablyai#11826 fixed the CLI
source-control cards; these are the ones it did not reach.

- task trackers (Linear and friends): Connected, Not connected
- Jira: Connected, Not connected
- token-configured hosts (Bitbucket, Azure DevOps, Gitea): Connected,
  Configured, Unavailable, Not configured, Optional setup, Auth failed

The three token-provider cards carried near-identical ternaries, so their copy
moved into `tokenProviderStatusLabel()` — one source for states they share,
and it keeps the file under the 400-line gate. Gitea passes `optional: true`
because it works read-only without a token, which is why its unconfigured state
reads "Optional setup" rather than "Not configured".

Same blind spot as before: the coverage audit inspects JSX attributes and object
properties, not conditional expressions handed to a prop, so
`verify:localization-coverage` stays green while the strings ship untranslated.
@smwbev
smwbev requested a review from brennanb2025 as a code owner August 3, 2026 05:00
@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 197d876a-769d-4ede-9ea9-eba0bf08fb51

📥 Commits

Reviewing files that changed from the base of the PR and between fb7cd03 and 5681b76.

📒 Files selected for processing (1)
  • src/renderer/src/components/settings/token-source-control-status.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/components/settings/token-source-control-status.ts

📝 Walkthrough

Walkthrough

Integration cards now localize connection-status labels. Token-based source-control cards use a shared helper for configured, unavailable, optional, required, and authentication-failure states. English locale entries were added for Jira and Bitbucket, and the Jira credential description was updated. Vitest coverage verifies the required English labels.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: localizing integration card status pills.
Description check ✅ Passed The description follows the template and documents the change, screenshots, testing results, AI review, security audit, and notes.
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.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/renderer/src/components/settings/token-source-control-status.ts (1)

9-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a stricter type for status instead of string.

The status field accepts any string. Each of the three callers (Bitbucket, Azure DevOps, Gitea) supplies a status value from its own preflight-status hook. A stricter union type here would let the compiler catch a mismatched or misspelled status literal at any call site, instead of silently falling through to the "Auth failed" default.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a9ae4dce-c4ef-48cb-9ab9-d94a2cf7fb33

📥 Commits

Reviewing files that changed from the base of the PR and between c9a37f5 and fb7cd03.

📒 Files selected for processing (6)
  • src/renderer/src/components/settings/jira-integration-card.tsx
  • src/renderer/src/components/settings/task-tracker-integration-cards.tsx
  • src/renderer/src/components/settings/token-source-control-integration-cards.tsx
  • src/renderer/src/components/settings/token-source-control-status.ts
  • src/renderer/src/i18n/integration-card-status-localization.test.ts
  • src/renderer/src/i18n/locales/en.json

Comment thread src/renderer/src/components/settings/token-source-control-status.ts
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR localizes the status pill labels (Connected, Not connected, Configured, Unavailable, Not configured, Optional setup, Auth failed) on the Jira, Linear, Bitbucket, Azure DevOps, and Gitea integration cards, which were shipping as bare English string literals while the surrounding card text was already translated. It also extracts a shared tokenProviderStatusLabel() helper to remove the near-identical ternaries duplicated across the three token-based source-control cards.

  • 10 new i18n keys added to en.json under the correct namespace paths; no existing keys removed or reworded.
  • tokenProviderStatusLabel() consolidates Bitbucket / Azure DevOps / Gitea status logic; Gitea's softer "Optional setup" wording is preserved via the explicit optional flag rather than being flattened into the shared path.
  • Catalog-integrity test added to pin all 10 keys so a regression back to a bare literal causes a test failure.

Confidence Score: 5/5

Safe to merge — purely a string-localization fix with no behavioural changes to card logic, credentials, or network paths.

All conditional branches in tokenProviderStatusLabel map exactly to the prior inline ternaries for each card, including the hasAccount === false strict-equality guard that correctly distinguishes an explicit false from an absent hasAccount (Bitbucket's case). The 10 new i18n keys land at the correct JSON paths, verified by both the new catalog test and manual inspection. English fallback strings are byte-identical to the removed literals, so no visual regression is possible in untranslated locales.

Files Needing Attention: No files require special attention. The most complex file is token-source-control-status.ts, and its logic has been verified against the original ternaries for all three callers.

Important Files Changed

Filename Overview
src/renderer/src/components/settings/token-source-control-status.ts New helper that consolidates Bitbucket/Azure DevOps/Gitea status label logic; correctly preserves all prior conditional branches including Gitea's optional-setup path via the explicit optional flag.
src/renderer/src/components/settings/token-source-control-integration-cards.tsx Replaces three inline ternary chains with calls to tokenProviderStatusLabel(); behavioral parity is preserved for all three cards including hasAccount/Boolean() wrapping for Azure DevOps and Gitea.
src/renderer/src/components/settings/jira-integration-card.tsx Wraps the two-branch connected ternary with catalog-keyed translate() calls; no logic changes.
src/renderer/src/components/settings/task-tracker-integration-cards.tsx Same two-branch connected ternary localized with catalog keys under the task.tracker.integration.cards namespace; no logic changes.
src/renderer/src/i18n/integration-card-status-localization.test.ts New catalog-integrity test covering all 10 added keys; the dot-split lookup() traversal is correct for the nested JSON structure used by the i18n catalog.
src/renderer/src/i18n/locales/en.json Adds 10 semantic keys (statusConnected, statusNotConnected, etc.) at the correct JSON paths matching the namespaces used in code; no existing keys modified.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[tokenProviderStatusLabel] --> B{configured?}
    B -- yes --> C{hasAccount === false?}
    C -- yes --> D["translate(statusConfigured) → 'Configured'"]
    C -- no/undefined --> E["translate(statusConnected) → 'Connected'"]
    B -- no --> F{status === 'unavailable'?}
    F -- yes --> G["translate(statusUnavailable) → 'Unavailable'"]
    F -- no --> H{status === 'not-configured'?}
    H -- yes --> I{optional?}
    I -- yes --> J["translate(statusOptionalSetup) → 'Optional setup'"]
    I -- no --> K["translate(statusNotConfigured) → 'Not configured'"]
    H -- no --> L["translate(statusAuthFailed) → 'Auth failed'"]

    subgraph Callers
        M[Bitbucket: configured=connected, no hasAccount]
        N[Azure DevOps: configured, hasAccount=Boolean-account]
        O[Gitea: configured, hasAccount=Boolean-account, optional=true]
    end

    M --> A
    N --> A
    O --> A
Loading

Reviews (1): Last reviewed commit: "fix(i18n): localize the integration card..." | Re-trigger Greptile

…ring

Review follow-up. The helper accepted `status: string`, which let any value
through and gave no signal when a provider gains a state. It now takes the union
the pane actually produces — each provider's own status plus `'unavailable'`,
which the cards substitute when the runtime cannot report at all.
nwparker pushed a commit that referenced this pull request Aug 4, 2026
Every card under Settings -> Integrations built its status pill from bare
literals inside the JSX call, so the pill stayed English beside a translated
description. audit-localization-coverage.mjs inspects JSX attributes and object
properties, not conditional expressions handed to a prop, so the gate stayed
green while the strings shipped untranslated.

The three token-configured cards share tokenProviderStatusLabel(); Gitea passes
optional: true because it works read-only without a token, which is why its
unconfigured state reads Optional setup rather than Not configured.

Co-authored-by: Evgenii <kumiro@me.com>
@nwparker

nwparker commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Merged into main via #12514, which consolidated the open community translation work into one branch. Your commit is on main with you as its author — I used a rebase merge specifically so every contributor's commit and co-author trailer survived intact rather than being squashed into one.

Closing this in favour of that. Thank you for the fix, and sorry it took as long as it did to get through.

@nwparker nwparker closed this Aug 4, 2026
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
Every card under Settings -> Integrations built its status pill from bare
literals inside the JSX call, so the pill stayed English beside a translated
description. audit-localization-coverage.mjs inspects JSX attributes and object
properties, not conditional expressions handed to a prop, so the gate stayed
green while the strings shipped untranslated.

The three token-configured cards share tokenProviderStatusLabel(); Gitea passes
optional: true because it works read-only without a token, which is why its
unconfigured state reads Optional setup rather than Not configured.

Co-authored-by: Evgenii <kumiro@me.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.

2 participants