Files
fusion/packages/dashboard/app/components/BackendConnectionErrorPage.tsx
gsxdsm 1e49494bac feat(i18n): full-sweep string migration — 5,930 keys across 5 locales (#1352)
Migration (multi-agent sweep over 216 files, 60 batches):
- Every user-visible dashboard + TUI string moved to t() with the exact
  English inline default (en rendering byte-identical)
- Catalogs merged from per-batch fragments: en/zh-CN/zh-TW/fr/es now
  carry ~5,930 keys each across common/app/errors/cli namespaces;
  CLI bundles regenerated (6 locales incl. ko)

Integration fixes:
- 18 type errors: reserved {{count}} interpolations renamed, malformed
  plural call, hand-rolled t-param types replaced with TFunction<"app">
- 23 lint errors: superseded label constants/helpers removed
- ExecutorStatusBar hook-order violation (keyboard-open early return
  moved below hooks)
- TUI tests wrapped in I18nextProvider (uninitialized fallback renders
  literal {{placeholders}}); dashboard vitest.setup boots a minimal en
  i18next instance for the same reason

Known WIP (next commits): ~457 residual strings across 50 batches,
Korean drafts for swept keys, and a dashboard test-suite pass that is
still being stabilized (~283 failures under investigation — fake-timer
waitFor interaction, likely stale node_modules vs merged lockfile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 19:06:53 -07:00

62 lines
2.2 KiB
TypeScript

import "./BackendConnectionErrorPage.css";
import { useTranslation } from "react-i18next";
interface BackendConnectionErrorPageProps {
errorMessage: string;
isRetrying: boolean;
onRetry: () => void;
onManageConnection?: () => void;
}
function isDesktopShell(): boolean {
if (typeof window === "undefined") return false;
return typeof window.fusionShell?.resetDesktopMode === "function";
}
async function changeLaunchMode(): Promise<void> {
const shell = typeof window !== "undefined" ? window.fusionShell : undefined;
try {
await shell?.resetDesktopMode?.();
} catch {
// Best-effort; still strip query params and reload.
}
const url = new URL(window.location.href);
url.searchParams.delete("serverBaseUrl");
url.searchParams.delete("shellMode");
window.location.replace(url.toString());
}
export function BackendConnectionErrorPage({
errorMessage,
isRetrying,
onRetry,
onManageConnection,
}: BackendConnectionErrorPageProps) {
const { t } = useTranslation("app");
const showChangeLaunchMode = isDesktopShell();
return (
<div className="project-overview-empty" role="alert" aria-live="polite">
<h2>{t("backend.connectionError", "Can't reach the Fusion backend")}</h2>
<p className="settings-muted">
{t("backend.couldNotLoad", "Fusion couldn't load your projects right now. Please make sure the backend is running and try again.")}
</p>
<p className="settings-muted">{t("backend.error", "Error: {{error}}", { error: errorMessage })}</p>
<div className="modal-actions">
<button type="button" className="btn btn-primary" onClick={onRetry} disabled={isRetrying}>
{isRetrying ? t("backend.retrying", "Retrying…") : t("backend.retryConnection", "Retry Connection")}
</button>
{showChangeLaunchMode && (
<button type="button" className="btn" onClick={() => void changeLaunchMode()}>
{t("backend.changeLaunchMode", "Change Launch Mode…")}
</button>
)}
{onManageConnection && (
<button type="button" className="btn" onClick={onManageConnection}>
{t("backend.manageConnection", "Manage Connection")}
</button>
)}
</div>
</div>
);
}