Add a production i18n lint baseline while replacing dashboard copy with translation keys. - Localize task, board, mailbox, report, graph, settings, and shared dashboard surfaces. - Regenerate locale catalogs and resource types for the migration keys. - Add the i18n lint-baseline regression test and contributor guidance. Files changed: .changeset/fn-013-i18n-lint-baseline.md | 7 + docs/i18n-contributing.md | 11 + .../dashboard/app/components/ActiveAgentsPanel.tsx | 2 +- .../dashboard/app/components/AgentDetailView.tsx | 2 +- packages/dashboard/app/components/Board.tsx | 19 +- packages/dashboard/app/components/ChatView.tsx | 2 +- .../dashboard/app/components/ComposeChatPanel.tsx | 14 +- packages/dashboard/app/components/DockTaskList.tsx | 16 +- .../dashboard/app/components/FloatingWindow.tsx | 6 +- .../dashboard/app/components/GitHubImportModal.tsx | 4 +- .../dashboard/app/components/KnowledgeGraphPanel.tsx | 21 +- packages/dashboard/app/components/ListView.tsx | 2 +- .../app/components/MailboxArtifactAttachment.tsx | 16 +- packages/dashboard/app/components/MailboxModal.tsx | 12 +- .../app/components/MailboxStructuralItem.tsx | 13 +- .../app/components/MailboxTaskProposal.tsx | 10 +- .../app/components/MailboxTaskRecommendations.tsx | 12 +- packages/dashboard/app/components/MailboxView.tsx | 14 +- packages/dashboard/app/components/MermaidDiagram.tsx | 4 +- packages/dashboard/app/components/MeshTopology.tsx | 6 +- .../dashboard/app/components/MessageComposer.tsx | 24 +- .../app/components/NativeStructurePreview.tsx | 14 +- packages/dashboard/app/components/ProviderLoginDialog.tsx | 24 +- packages/dashboard/app/components/ReportActionMenu.tsx | 6 +- packages/dashboard/app/components/ReportModal.tsx | 26 +- packages/dashboard/app/components/TaskChatTab.tsx | 10 +- packages/dashboard/app/components/TaskDetailModal.tsx | 28 +- .../app/components/TaskVerificationStatus.tsx | 10 +- .../dashboard/app/components/WhatsAppChatPairingPanel.tsx | 38 +- .../components/command-center/CommandCenter.tsx | 4 +- .../components/command-center/IdeationPanel.tsx | 12 +- .../components/settings/sections/McpServersCard.tsx | 2 +- .../components/settings/sections/MemorySection.tsx | 4 +- .../app/task-modal-touch-resize-e2e-fixture.tsx | 28 +- packages/i18n/locales/en/app.json | 247 +++++++- packages/i18n/locales/es/app.json | 256 +++++++- packages/i18n/locales/fr/app.json | 256 +++++++- packages/i18n/locales/ko/app.json | 256 +++++++- packages/i18n/locales/pt-BR/app.json | 705 ++++++++++++++++++++ packages/i18n/locales/zh-CN/app.json | 256 +++++++- packages/i18n/locales/zh-TW/app.json | 256 +++++++- .../i18n/src/__tests__/i18n-lint-baseline.test.ts | 31 + packages/i18n/src/resources.d.ts | 229 ++++++- 43 files changed, 2627 insertions(+), 288 deletions(-) Fusion-Task-Id: FN-013 Fusion-Task-Lineage: 846ac221-c7c3-4ff0-a30d-69479b614765 Co-authored-by: Fusion <noreply@runfusion.ai>
36 lines
2.2 KiB
TypeScript
36 lines
2.2 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import type { MessageMetadata } from "@fusion/core";
|
|
import { createProposedTask } from "../api";
|
|
import "./MailboxTaskProposal.css";
|
|
|
|
export function MailboxTaskProposal({ messageId, metadata, projectId, onOpenTask, onCreated }: { messageId: string; metadata?: MessageMetadata; projectId?: string; onOpenTask?: (id: string) => void; onCreated?: () => void }) {
|
|
const { t } = useTranslation("app");
|
|
const [creating, setCreating] = useState(false);
|
|
const [currentMetadata, setCurrentMetadata] = useState(metadata);
|
|
useEffect(() => setCurrentMetadata(metadata), [metadata]);
|
|
if (currentMetadata?.kind !== "task-proposal" || !currentMetadata.proposedTask) return null;
|
|
const proposal = currentMetadata.proposedTask;
|
|
const status = currentMetadata.proposalStatus ?? "pending";
|
|
|
|
const create = async () => {
|
|
setCreating(true);
|
|
try {
|
|
const response = await createProposedTask(messageId, projectId);
|
|
// FNXC:EphemeralAgentTaskCreation 2026-07-30-13:00: apply the finalized response immediately so a stale mailbox list cannot offer a duplicate create click before SSE refreshes it.
|
|
setCurrentMetadata(response.proposal.metadata);
|
|
onCreated?.();
|
|
} finally {
|
|
setCreating(false);
|
|
}
|
|
};
|
|
|
|
return <section className="mailbox-task-proposal" data-testid="mailbox-task-proposal">
|
|
<strong>{proposal.title}</strong><p>{proposal.description}</p>
|
|
{status === "pending" && <button type="button" className="btn" disabled={creating} onClick={() => void create()}>{creating ? t("mailbox.creatingTask", "Creating task…") : t("mailbox.createTask", "Create task")}</button>}
|
|
{status === "creating" && <button type="button" className="btn" disabled>{t("mailbox.creatingTask", "Creating task…")}</button>}
|
|
{status === "created" && currentMetadata.createdTaskId && <button type="button" className="btn" onClick={() => onOpenTask?.(currentMetadata.createdTaskId!)}>{t("mailbox.taskCreatedView", "Task {{id}} created — View task", { id: currentMetadata.createdTaskId })}</button>}
|
|
{status === "dismissed" && <span>{t("mailbox.taskProposalDismissed", "Task proposal dismissed")}</span>}
|
|
</section>;
|
|
}
|