From bdf95f8d6548777bf9240293f91899b813c51c98 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 20 Jun 2026 10:35:40 -0700 Subject: [PATCH] FN-6770: localize dashboard workflow and task UI strings Localize dashboard workflow, task, setup, and pull request UI copy through the shared i18n resources. - Replace hardcoded dashboard strings in workflow, task detail/chat/comment, setup wizard, PR, and related modal components with translation lookups. - Add app/common namespace keys across English and secondary locale catalogs, plus regenerated i18n resource types. - Add the published package changeset and clear the now-localized component files from the i18n lint deferral list. Files changed: .changeset/fn-6770-localize-workflow-task-pr.md | 5 + i18next.config.ts | 17 +- packages/dashboard/app/components/Board.tsx | 10 +- .../dashboard/app/components/PrCreateModal.tsx | 38 +-- packages/dashboard/app/components/PrPanel.tsx | 2 +- .../dashboard/app/components/PullRequestView.tsx | 51 ++-- .../dashboard/app/components/SettingsModal.tsx | 92 +++---- .../dashboard/app/components/SetupWizardModal.tsx | 8 +- packages/dashboard/app/components/TaskChatTab.tsx | 107 ++++---- packages/dashboard/app/components/TaskComments.tsx | 2 +- .../dashboard/app/components/TaskDetailModal.tsx | 54 ++-- .../app/components/WorkflowNodeEditor.tsx | 109 +++++---- .../app/components/WorkflowResultsTab.tsx | 190 +++++++------- .../dashboard/app/components/WorkflowSelector.tsx | 20 +- packages/i18n/locales/en/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/en/common.json | 28 +-- packages/i18n/locales/es/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/es/common.json | 28 +-- packages/i18n/locales/fr/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/fr/common.json | 28 +-- packages/i18n/locales/ko/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/ko/common.json | 28 +-- packages/i18n/locales/zh-CN/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/zh-CN/common.json | 28 +-- packages/i18n/locales/zh-TW/app.json | 268 ++++++++++++++++++-- packages/i18n/locales/zh-TW/common.json | 28 +-- packages/i18n/src/resources.d.ts | 272 ++++++++++++++++++--- 27 files changed, 2144 insertions(+), 609 deletions(-) Fusion-Task-Id: FN-6770 Fusion-Task-Lineage: 393b6b8a-1902-4e46-a53e-b4a0793022ca --- .../fn-6770-localize-workflow-task-pr.md | 5 + i18next.config.ts | 17 +- packages/dashboard/app/components/Board.tsx | 10 +- .../app/components/PrCreateModal.tsx | 38 +-- packages/dashboard/app/components/PrPanel.tsx | 2 +- .../app/components/PullRequestView.tsx | 51 ++-- .../app/components/SettingsModal.tsx | 92 +++--- .../app/components/SetupWizardModal.tsx | 8 +- .../dashboard/app/components/TaskChatTab.tsx | 107 ++++--- .../dashboard/app/components/TaskComments.tsx | 2 +- .../app/components/TaskDetailModal.tsx | 54 ++-- .../app/components/WorkflowNodeEditor.tsx | 109 +++---- .../app/components/WorkflowResultsTab.tsx | 190 ++++++------ .../app/components/WorkflowSelector.tsx | 20 +- packages/i18n/locales/en/app.json | 268 +++++++++++++++-- packages/i18n/locales/en/common.json | 28 +- packages/i18n/locales/es/app.json | 268 +++++++++++++++-- packages/i18n/locales/es/common.json | 28 +- packages/i18n/locales/fr/app.json | 268 +++++++++++++++-- packages/i18n/locales/fr/common.json | 28 +- packages/i18n/locales/ko/app.json | 268 +++++++++++++++-- packages/i18n/locales/ko/common.json | 28 +- packages/i18n/locales/zh-CN/app.json | 268 +++++++++++++++-- packages/i18n/locales/zh-CN/common.json | 28 +- packages/i18n/locales/zh-TW/app.json | 268 +++++++++++++++-- packages/i18n/locales/zh-TW/common.json | 28 +- packages/i18n/src/resources.d.ts | 272 ++++++++++++++++-- 27 files changed, 2144 insertions(+), 609 deletions(-) create mode 100644 .changeset/fn-6770-localize-workflow-task-pr.md diff --git a/.changeset/fn-6770-localize-workflow-task-pr.md b/.changeset/fn-6770-localize-workflow-task-pr.md new file mode 100644 index 0000000000..5a8a7d6413 --- /dev/null +++ b/.changeset/fn-6770-localize-workflow-task-pr.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Localized the dashboard workflow/task/setup/PR component cluster and removed the obsolete i18n lint deferrals for those files so the hardcoded-string guardrail scans them again. diff --git a/i18next.config.ts b/i18next.config.ts index adce4b12ab..031170db6c 100644 --- a/i18next.config.ts +++ b/i18next.config.ts @@ -6,23 +6,8 @@ import { const DEFERRED_I18N_LINT_FILES = [ - // FNXC:i18n-LintBaseline 2026-06-19-00:00: - // These exact files still carry pre-existing user-facing copy debt after FN-6749 restored the guardrail scope and token suppression. - // Keep the deferral file-scoped and remove entries as those follow-ups localize each cluster. // FNXC:i18n-LintBaseline 2026-06-20-00:00: - // FN-6771 localized the settings/sections cluster, so those files are no longer deferred and must stay covered by i18n lint. - "packages/dashboard/app/components/WorkflowSelector.tsx", - "packages/dashboard/app/components/WorkflowResultsTab.tsx", - "packages/dashboard/app/components/WorkflowNodeEditor.tsx", - "packages/dashboard/app/components/TaskDetailModal.tsx", - "packages/dashboard/app/components/TaskComments.tsx", - "packages/dashboard/app/components/TaskChatTab.tsx", - "packages/dashboard/app/components/SetupWizardModal.tsx", - "packages/dashboard/app/components/SettingsModal.tsx", - "packages/dashboard/app/components/PullRequestView.tsx", - "packages/dashboard/app/components/PrPanel.tsx", - "packages/dashboard/app/components/PrCreateModal.tsx", - "packages/dashboard/app/components/Board.tsx", + // FN-6770 and FN-6771 localized the remaining workflow/task/setup/PR and settings/sections clusters, so no dashboard component files remain deferred from hardcoded-string lint. ] as const; /** diff --git a/packages/dashboard/app/components/Board.tsx b/packages/dashboard/app/components/Board.tsx index 0fb9e53099..29fec0adb7 100644 --- a/packages/dashboard/app/components/Board.tsx +++ b/packages/dashboard/app/components/Board.tsx @@ -5,6 +5,7 @@ import { Column } from "./Column"; import "./Lane.css"; import type { ToastType } from "../hooks/useToast"; import { useState, useMemo, useEffect, useCallback, useRef } from "react"; +import { useTranslation } from "react-i18next"; import { Pencil, Plus } from "lucide-react"; import { fetchWorkflowSteps, fetchBoardWorkflows, promoteTask, type ModelInfo, type BoardWorkflowDefinition, type BoardWorkflowsPayload } from "../api"; import { useBlockerFanout } from "../hooks/useBlockerFanout"; @@ -124,6 +125,7 @@ function areWorkflowNameLookupsEqual(previous: ReadonlyMap, next } export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask, onOpenDetail, onOpenGroupModal, addToast, onQuickCreate, onNewTask, autoMerge, onToggleAutoMerge, globalPaused, onUpdateTask, onRetryTask, onArchiveTask, onUnarchiveTask, onDeleteTask, onArchiveAllDone, onLoadArchivedTasks, searchQuery = "", availableModels, onPlanningMode, onSubtaskBreakdown, onOpenDetailWithTab, favoriteProviders, favoriteModels, onToggleFavorite, onToggleModelFavorite, taskStuckTimeoutMs, onOpenMission, staleHighFanoutBlockerAgeThresholdMs, lastFetchTimeMs, prAuthAvailable, onOpenWorkflowEditor, onCreateWorkflow }: BoardProps) { + const { t } = useTranslation("app"); const [archivedCollapsed, setArchivedCollapsed] = useState(true); const archivedLoadedRef = useRef(false); const [workflowStepNameLookup, setWorkflowStepNameLookup] = useState>(EMPTY_WORKFLOW_STEP_NAME_LOOKUP); @@ -527,8 +529,8 @@ export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask type="button" className="btn btn-icon btn-sm board-workflow-edit-btn" onClick={() => onOpenWorkflowEditor(selectedWorkflow.id)} - title="Edit workflows" - aria-label="Edit workflows" + title={t("board.workflow.edit", "Edit workflows")} + aria-label={t("board.workflow.edit", "Edit workflows")} > @@ -538,8 +540,8 @@ export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask type="button" className="btn btn-icon btn-sm board-workflow-create-btn" onClick={onCreateWorkflow} - title="New workflow" - aria-label="New workflow" + title={t("board.workflow.new", "New workflow")} + aria-label={t("board.workflow.new", "New workflow")} > diff --git a/packages/dashboard/app/components/PrCreateModal.tsx b/packages/dashboard/app/components/PrCreateModal.tsx index 8397fa9075..5f7313d8bb 100644 --- a/packages/dashboard/app/components/PrCreateModal.tsx +++ b/packages/dashboard/app/components/PrCreateModal.tsx @@ -488,7 +488,7 @@ export function PrCreateModal({ <>

{t("pr.preflightChecks", "Pre-flight checks")}

- {preflightLoading ?
: null} + {preflightLoading ?
: null} {preflightError ?

{preflightError}

: null} {!preflightLoading && !preflightError ? ( <> @@ -511,8 +511,8 @@ export function PrCreateModal({ {!preflight?.branchOnRemote ? (
-

Push branch to remote

-

Fusion will push this task's branch to origin so the PR can be created.

+

{t("pr.pushBranch.title", "Push branch to remote")}

+

{t("pr.pushBranch.message", "Fusion will push this task's branch to origin so the PR can be created.")}

) : null} {preflight?.conflictsWithBase ? (
-

Resolve conflicts with AI

-

Fusion will use AI to resolve conflicts on this branch and push it.

+

{t("pr.resolveConflicts.title", "Resolve conflicts with AI")}

+

{t("pr.resolveConflicts.message", "Fusion will use AI to resolve conflicts on this branch and push it.")}

) : null} @@ -554,7 +554,7 @@ export function PrCreateModal({ {userEditedTitle && } - {metadataLoading ?
: null} + {metadataLoading ?
: null} {metadataError ?

{metadataError}

: null} { setTitle(event.target.value); setUserEditedTitle(true); }} />
@@ -567,7 +567,7 @@ export function PrCreateModal({ {userEditedBody && } - {metadataLoading ?
: null} + {metadataLoading ?
: null}