Localize dashboard settings section text and restore i18n lint coverage for those files. - Replace hardcoded settings section labels, help text, placeholders, and status copy with i18n lookups. - Add settings translation keys across supported app and common locale catalogs and refresh generated resource types. - Remove the settings sections from the i18n lint deferral list and document that coverage requirement. - Add a patch changeset for the published Fusion package. Files changed: .changeset/fn-6771-localize-settings-sections.md | 5 + docs/i18n-contributing.md | 3 +- i18next.config.ts | 26 +- .../settings/sections/AgentPermissionsSection.tsx | 55 +- .../settings/sections/AppearanceSection.tsx | 91 +- .../settings/sections/AuthenticationSection.tsx | 457 +++------- .../settings/sections/BackupsSection.tsx | 229 ++--- .../settings/sections/CommandsSection.tsx | 49 +- .../settings/sections/ExperimentalSection.tsx | 109 +-- .../settings/sections/GeneralSection.tsx | 487 ++++------- .../settings/sections/GlobalGeneralSection.tsx | 183 +--- .../settings/sections/GlobalModelsSection.tsx | 525 ++++------- .../components/settings/sections/MemorySection.tsx | 458 +++------- .../components/settings/sections/MergeSection.tsx | 863 ++++++------------ .../settings/sections/NodeRoutingSection.tsx | 108 +-- .../settings/sections/NodeSyncSection.tsx | 105 +-- .../settings/sections/NotificationsSection.tsx | 484 ++++------ .../settings/sections/PluginsSection.tsx | 105 +-- .../settings/sections/ProjectModelsSection.tsx | 971 ++++++++------------- .../components/settings/sections/RemoteSection.tsx | 560 +++++------- .../settings/sections/ResearchGlobalSection.tsx | 314 ++----- .../settings/sections/ResearchProjectSection.tsx | 226 ++--- .../settings/sections/RuntimesSections.tsx | 40 +- .../settings/sections/ScheduledEvalsSection.tsx | 169 ++-- .../settings/sections/SchedulingSection.tsx | 381 ++------ .../settings/sections/WorktreesSection.tsx | 330 ++----- packages/i18n/locales/en/app.json | 698 ++++++++++++++- packages/i18n/locales/en/common.json | 8 + packages/i18n/locales/es/app.json | 698 ++++++++++++++- packages/i18n/locales/es/common.json | 8 + packages/i18n/locales/fr/app.json | 698 ++++++++++++++- packages/i18n/locales/fr/common.json | 8 + packages/i18n/locales/ko/app.json | 698 ++++++++++++++- packages/i18n/locales/ko/common.json | 8 + packages/i18n/locales/zh-CN/app.json | 698 ++++++++++++++- packages/i18n/locales/zh-CN/common.json | 8 + packages/i18n/locales/zh-TW/app.json | 698 ++++++++++++++- packages/i18n/locales/zh-TW/common.json | 8 + packages/i18n/src/resources.d.ts | 706 ++++++++++++++- 39 files changed, 7178 insertions(+), 5097 deletions(-) Fusion-Task-Id: FN-6771 Fusion-Task-Lineage: cdf9b36f-414e-4084-b661-b578a4c27314
63 lines
3.6 KiB
TypeScript
63 lines
3.6 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import type { NodeInfo } from "../../../api";
|
|
import { NodeHealthDot } from "../../NodeHealthDot";
|
|
import type { SettingsFormState, SetSettingsForm } from "./context";
|
|
import { useTranslation } from "react-i18next";
|
|
function getNodeStatusLabel(status: "online" | "offline" | "connecting" | "error", t: ReturnType<typeof useTranslation<"app">>["t"]): string {
|
|
if (status === "online")
|
|
return t("settings.nodeRouting.statusOnline", "Online");
|
|
if (status === "connecting")
|
|
return t("settings.nodeRouting.statusConnecting", "Connecting");
|
|
if (status === "error")
|
|
return t("settings.nodeRouting.statusError", "Error");
|
|
return t("settings.nodeRouting.statusOffline", "Offline");
|
|
}
|
|
export interface NodeRoutingSectionProps {
|
|
scopeBanner: ReactNode;
|
|
form: SettingsFormState;
|
|
setForm: SetSettingsForm;
|
|
nodes: NodeInfo[];
|
|
}
|
|
export function NodeRoutingSection({ scopeBanner, form, setForm, nodes }: NodeRoutingSectionProps) {
|
|
const { t } = useTranslation("app");
|
|
return (<>
|
|
{scopeBanner}
|
|
<h4 className="settings-section-heading">{t("settings.nodeRouting.nodeRouting", "Node Routing")}</h4>
|
|
<p className="settings-section-description">{t("settings.nodeRouting.configureHowTasksAreRoutedToExecutionNodes", "Configure how tasks are routed to execution nodes.")}</p>
|
|
<p className="settings-node-routing-note">{t("settings.nodeRouting.theseSettingsApplyAtTheProjectLevel", "These settings apply at the project level.")}</p>
|
|
<div className="form-group">
|
|
<label htmlFor="defaultNodeId">{t("settings.nodeRouting.defaultExecutionNode", "Default Execution Node")}</label>
|
|
<select id="defaultNodeId" className="select" value={typeof form.defaultNodeId === "string" ? form.defaultNodeId : ""} onChange={(e) => {
|
|
const val = e.target.value;
|
|
setForm((f) => ({ ...f, defaultNodeId: val || undefined } as SettingsFormState));
|
|
}}>
|
|
<option value="">{t("settings.nodeRouting.localExecutionNoDefaultNode", "Local execution (no default node)")}</option>
|
|
{nodes.map((node) => (<option key={node.id} value={node.id}>
|
|
{node.name} ({getNodeStatusLabel(node.status, t)})
|
|
</option>))}
|
|
</select>
|
|
{(() => {
|
|
const selectedNode = nodes.find((node) => node.id === form.defaultNodeId);
|
|
if (!selectedNode)
|
|
return null;
|
|
return (<div className="settings-node-status">
|
|
<span>{t("settings.nodeRouting.selectedNode", "Selected node:")}</span>
|
|
<NodeHealthDot status={selectedNode.status} showLabel/>
|
|
</div>);
|
|
})()}
|
|
<small>{t("settings.nodeRouting.usedWhenATaskHasNoNodeOverride", "Used when a task has no node override. Node status is shown for safer routing selection.")}</small>
|
|
</div>
|
|
<div className="form-group">
|
|
<label htmlFor="unavailableNodePolicy">{t("settings.nodeRouting.unavailableNodePolicy", "Unavailable Node Policy")}</label>
|
|
<select id="unavailableNodePolicy" className="select" value={form.unavailableNodePolicy === "fallback-local" ? "fallback-local" : "block"} onChange={(e) => setForm((f) => ({
|
|
...f,
|
|
unavailableNodePolicy: e.target.value as "block" | "fallback-local",
|
|
} as SettingsFormState))}>
|
|
<option value="block">{t("settings.nodeRouting.blockExecution", "Block execution")}</option>
|
|
<option value="fallback-local">{t("settings.nodeRouting.fallBackToLocal", "Fall back to local")}</option>
|
|
</select>
|
|
</div>
|
|
</>);
|
|
}
|
|
export default NodeRoutingSection;
|