From b1cf46775c211ced5ae242f268bd8761a32cc91d Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Wed, 28 Oct 2026 16:20:33 -0700 Subject: [PATCH] fix(i18n): localize remaining plurals, fragments and hardcoded copy in task page, automations and shared components (#35413) * fix(i18n): localize remaining renderer plurals, fragments and hardcoded copy Convert manual one/many keys and value0 counts to CLDR plural families, replace fragment concatenations with whole-sentence keys or Trans, and route hardcoded English labels, errors and compact time units through the UI locale. Refs #32207 * fix(i18n): re-render memoized agent state dots on language change --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- src/renderer/src/components/AgentStateDot.tsx | 25 +- .../components/ClaudeAccountSwitchDialog.tsx | 30 +- .../src/components/JiraIssueRowCopyMenu.tsx | 13 +- .../components/JiraLinkedWorkspaceAction.tsx | 7 +- .../components/JiraPromptTemplatePopover.tsx | 2 +- src/renderer/src/components/Landing.tsx | 33 +- .../LinearIssueMarkdownDescriptionEditor.tsx | 5 +- .../src/components/LinearItemDrawer.tsx | 3 +- .../NativeChatRemoteResumeActions.tsx | 20 +- .../components/NativeChatResumeRunPanel.tsx | 35 +- .../components/NewWorkspaceComposerCard.tsx | 53 +- src/renderer/src/components/QuickOpen.tsx | 10 +- src/renderer/src/components/UpdateCard.tsx | 8 +- src/renderer/src/components/ZoomOverlay.tsx | 7 +- .../automations/AutomationDeleteDialogs.tsx | 61 ++- .../automations/AutomationDetail.tsx | 66 ++- .../automations/AutomationListExternalRow.tsx | 5 +- .../automations/AutomationListLocalRow.tsx | 24 +- .../automations/AutomationProjectCombobox.tsx | 3 +- .../automations/AutomationRunHistory.tsx | 12 +- .../ExternalAutomationManagers.tsx | 11 +- .../automation-capability-probe.ts | 6 +- .../automations/automation-edit-draft.ts | 6 +- .../automation-host-catalog.test.ts | 7 +- .../automations/automation-host-catalog.ts | 10 +- .../automation-host-orphan-entry.test.ts | 7 +- .../automations/automation-list-last-run.ts | 9 +- .../automations/automation-page-parts.tsx | 63 ++- .../automations/automation-run-content.ts | 7 +- .../automations/automation-run-occurrences.ts | 28 +- .../automations/automation-run-view-state.ts | 57 +- .../automation-run-workspace-display.ts | 27 +- .../automations/automation-source-display.ts | 25 +- .../automations/automation-usage-model.ts | 27 +- .../external-automation-display.ts | 12 +- ...nal-automation-source-availability.test.ts | 6 +- ...external-automation-source-availability.ts | 34 +- .../external-automation-unchecked-hosts.ts | 16 +- .../browser-extension-permission-messages.ts | 18 +- .../gitlab/gitlab-rate-limit-display.tsx | 23 +- .../components/issue-copy-target-messages.ts | 40 ++ .../jira-connect-credential-guide.tsx | 35 +- .../jira-issue-workspace-actions.ts | 30 +- .../src/components/jira-list-columns.ts | 12 +- .../components/landing-preflight-issues.ts | 6 +- .../src/components/linear-issue-activity.tsx | 18 +- .../src/components/linear-issue-clipboard.ts | 20 +- .../linear-issue-workspace-header.tsx | 2 +- .../linear-issue-workspace-sidebar.tsx | 9 +- .../linear-item-drawer-edit-chips-layout.tsx | 8 +- .../linear-item-drawer-edit-controls.tsx | 15 +- ...ear-item-drawer-edit-properties-layout.tsx | 6 +- .../src/components/linear-priority-icon.tsx | 23 +- .../linear-project-overview-content.tsx | 22 +- .../components/linear-project-presentation.ts | 17 +- .../linear-project-table-content.tsx | 3 +- .../src/components/linear-scope-selector.tsx | 31 +- ...ative-chat-restart-action-notifications.ts | 45 +- .../native-chat-resume-activity-label.ts | 32 +- .../src/components/pr-check-counts.test.ts | 2 +- .../src/components/pr-check-counts.ts | 44 +- .../components/project-host-count-label.ts | 11 + .../components/quick-open-file-navigation.ts | 19 +- .../components/shared/useDaemonActions.tsx | 11 +- .../sparse/SparseDirectoryPicker.tsx | 18 +- .../components/task-page-jira-board-view.tsx | 16 +- .../task-page-jira-linked-issues.ts | 6 +- .../components/task-page-jira-load-state.ts | 52 +- .../src/components/task-page/Content.tsx | 5 +- .../task-page/github/AssigneesCell.tsx | 7 +- .../task-page/github/IssueDialog.tsx | 16 +- .../src/components/task-page/github/List.tsx | 14 +- .../src/components/task-page/github/Rows.tsx | 18 +- .../task-page/github/StatusCell.tsx | 7 +- .../task-page-github-landing-refresh-run.tsx | 10 +- .../components/task-page/gitlab/Filters.tsx | 7 +- .../components/task-page/gitlab/ItemList.tsx | 21 +- .../src/components/task-page/jira/Content.tsx | 9 +- .../components/task-page/jira/IssueDialog.tsx | 4 +- .../task-page/linear/IssueAttributes.tsx | 5 +- .../task-page/linear/IssueDialog.tsx | 4 +- .../task-page/linear/IssueToolbar.tsx | 8 +- .../task-page/linear/ProjectFields.tsx | 4 +- .../linear/linear-attribute-count-labels.ts | 12 +- .../task-page-linear-jira-list-model.tsx | 4 +- .../use-task-page-linear-list-selection.ts | 9 +- .../task-page/task-page-pr-delta-summary.ts | 11 +- .../use-task-page-resume-restoration.ts | 29 +- .../task-project-source-combobox.tsx | 9 +- .../components/task-source-context-summary.ts | 131 ++--- .../task-source-host-status-labels.ts | 183 +++++++ .../use-jira-issue-comment-submission.ts | 5 +- .../use-jira-issue-remote-details.ts | 17 +- .../worktree-jump-palette-surface.tsx | 41 +- .../src/i18n/en-runtime-required.json | 144 ++++- src/renderer/src/i18n/locales/de.json | 409 ++++++++++---- src/renderer/src/i18n/locales/en.json | 409 ++++++++++---- src/renderer/src/i18n/locales/es.json | 409 ++++++++++---- src/renderer/src/i18n/locales/fr.json | 409 ++++++++++---- src/renderer/src/i18n/locales/ja.json | 366 +++++++++---- src/renderer/src/i18n/locales/ko.json | 366 +++++++++---- src/renderer/src/i18n/locales/pt.json | 409 ++++++++++---- src/renderer/src/i18n/locales/ru.json | 497 ++++++++++++++---- src/renderer/src/i18n/locales/tr.json | 366 +++++++++---- src/renderer/src/i18n/locales/zh-Hant.json | 366 +++++++++---- src/renderer/src/i18n/locales/zh.json | 366 +++++++++---- src/renderer/src/i18n/relative-time-format.ts | 29 + 107 files changed, 4965 insertions(+), 1544 deletions(-) create mode 100644 src/renderer/src/components/issue-copy-target-messages.ts create mode 100644 src/renderer/src/components/project-host-count-label.ts create mode 100644 src/renderer/src/components/task-source-host-status-labels.ts diff --git a/src/renderer/src/components/AgentStateDot.tsx b/src/renderer/src/components/AgentStateDot.tsx index c5ddb91aa4b..1cbc1ca512b 100644 --- a/src/renderer/src/components/AgentStateDot.tsx +++ b/src/renderer/src/components/AgentStateDot.tsx @@ -1,6 +1,8 @@ import React from 'react' import { Activity, CircleCheck, CircleDashed } from 'lucide-react' import { cn } from '@/lib/utils' +import { translate } from '@/i18n/i18n' +import { useUiLanguageRevision } from '@/i18n/use-ui-language-revision' import { AgentQuestionIcon } from '@/components/AgentQuestionIcon' import { AgentWorkingSpinner } from '@/components/AgentWorkingSpinner' import { @@ -36,27 +38,27 @@ export type AgentDotState = export function agentStateLabel(state: AgentDotState): string { switch (state) { case 'working': - return 'Working' + return translate('auto.components.AgentStateDot.working', 'Working') case 'monitoring': - return 'Monitoring background tasks' + return translate('auto.components.AgentStateDot.monitoring', 'Monitoring background tasks') case 'blocked': - return 'Blocked' + return translate('auto.components.AgentStateDot.blocked', 'Blocked') case 'waiting': - return 'Waiting for input' + return translate('auto.components.AgentStateDot.waiting', 'Waiting for input') case 'interrupted': - return 'Interrupted' + return translate('auto.components.AgentStateDot.interrupted', 'Interrupted') case 'failed': - return 'Failed' + return translate('auto.components.AgentStateDot.failed', 'Failed') case 'done': - return 'Done' + return translate('auto.components.AgentStateDot.done', 'Done') case 'idle': - return 'Idle' + return translate('auto.components.AgentStateDot.idle', 'Idle') case 'unverifiable': - return 'No recent update' + return translate('auto.components.AgentStateDot.unverifiable', 'No recent update') case 'unconfirmed': - return 'Couldn’t confirm' + return translate('auto.components.AgentStateDot.unconfirmed', 'Couldn’t confirm') case 'permission': - return 'Needs attention' + return translate('auto.components.AgentStateDot.permission', 'Needs attention') } } @@ -108,6 +110,7 @@ export const AgentStateDot = React.memo(function AgentStateDot({ tooltipSide, progress }: Props): React.JSX.Element { + useUiLanguageRevision() const box = size === 'md' ? 'h-3 w-3' : 'h-2.5 w-2.5' const inner = size === 'md' ? 'size-2' : 'size-1.5' const icon = size === 'md' ? 'size-3' : 'size-2.5' diff --git a/src/renderer/src/components/ClaudeAccountSwitchDialog.tsx b/src/renderer/src/components/ClaudeAccountSwitchDialog.tsx index 722c2cb009f..6fa321798c8 100644 --- a/src/renderer/src/components/ClaudeAccountSwitchDialog.tsx +++ b/src/renderer/src/components/ClaudeAccountSwitchDialog.tsx @@ -127,11 +127,17 @@ function SwitchPromptDialog({ prompt }: { prompt: ClaudeAccountSwitchPrompt }):