FN-7341: replan tasks after execution mode changes

Execution-mode changes now confirm and rebuild task plans when active task state would be invalidated.

- Require confirmation before changing Standard/Fast mode on todo and in-progress tasks.
- Route confirmed execution-mode edits through the task spec rebuild path and close the modal with replanning feedback.
- Cover inline and edit-mode execution-mode changes with dashboard tests and localized copy.

Files changed:
 .changeset/fn-7341-execution-mode-replan.md        |   7 +
 .../dashboard/app/components/TaskDetailModal.tsx   |  70 +++++++-
 ...lModal.inline-editing-and-integrations.test.tsx | 181 ++++++++++++++++++---
 .../__tests__/TaskDetailModal.test-helpers.ts      |   1 +
 packages/i18n/locales/en/app.json                  |   3 +
 packages/i18n/locales/es/app.json                  |   5 +-
 packages/i18n/locales/fr/app.json                  |   5 +-
 packages/i18n/locales/ko/app.json                  |   5 +-
 packages/i18n/locales/zh-CN/app.json               |   5 +-
 packages/i18n/locales/zh-TW/app.json               |   5 +-
 packages/i18n/src/resources.d.ts                   |   3 +
 11 files changed, 257 insertions(+), 33 deletions(-)

Fusion-Task-Id: FN-7341
Fusion-Task-Lineage: 2b1e7ac9-81b4-438a-84d1-965da5ed84fb
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-06-30 22:39:31 -07:00
parent ae1ca5cf16
commit 45b1ee6f9c
11 changed files with 259 additions and 35 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Replan active tasks after confirming execution-mode changes.
category: fix
dev: Dashboard inline execution-mode changes on todo/in-progress tasks now confirm and call the spec rebuild path.

View File

@@ -398,6 +398,14 @@ function normalizeExecutionModeValue(executionMode: Task["executionMode"]): "sta
return executionMode === "fast" ? "fast" : "standard";
}
function requiresExecutionModeReplan(column: Task["column"]): boolean {
/*
FNXC:ExecutionModeReplan 2026-06-30-00:00:
Todo and in-progress tasks can already hold a generated plan or active execution context. Changing Standard/Fast mode invalidates that plan, so the dashboard must confirm the change and send the task back through the existing replanning path instead of silently patching executionMode in place.
*/
return column === "todo" || column === "in-progress";
}
interface ProvenanceDisplay {
label: string;
parentTaskId?: string;
@@ -896,6 +904,10 @@ export function TaskDetailContent({
const [isSavingInlineExecutionMode, setIsSavingInlineExecutionMode] = useState(false);
const [inlineNoCommitsExpected, setInlineNoCommitsExpected] = useState<boolean>(task.noCommitsExpected === true);
const [isSavingInlineNoCommitsExpected, setIsSavingInlineNoCommitsExpected] = useState(false);
const { confirm, confirmWithChoice, confirmWithCheckbox } = useConfirm();
const requestClose = useCallback(() => {
onRequestClose?.();
}, [onRequestClose]);
const mountedRef = useRef(false);
const activeTaskIdRef = useRef(task.id);
@@ -1508,6 +1520,7 @@ export function TaskDetailContent({
const [editAutoSaveStatus, setEditAutoSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle");
const editAutoSaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const editAutoSaveRevisionRef = useRef(0);
const editSaveTriggeredReplanRef = useRef(false);
const buildEditUpdates = useCallback((includeDescription: boolean) => {
const updates: Record<string, unknown> = {};
@@ -1601,20 +1614,47 @@ export function TaskDetailContent({
}
return false;
}
const replanAfterExecutionModeChange = Object.prototype.hasOwnProperty.call(updates, "executionMode") && requiresExecutionModeReplan(task.column);
if (replanAfterExecutionModeChange && !includeDescription) {
delete updates.executionMode;
}
if (Object.keys(updates).length === 0) {
return true;
}
if (replanAfterExecutionModeChange && includeDescription) {
const nextMode = normalizeExecutionModeValue(updates.executionMode as Task["executionMode"]);
const shouldChangeMode = await confirm({
title: t("taskDetail.executionMode.replanTitle", "Change execution mode and replan?"),
message: t("taskDetail.executionMode.replanMessage", "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for {{mode}} mode.", { mode: nextMode }),
});
if (!shouldChangeMode) {
setEditExecutionMode(normalizeExecutionModeValue(task.executionMode));
return false;
}
}
const revision = ++editAutoSaveRevisionRef.current;
setIsSaving(true);
setEditAutoSaveStatus("saving");
try {
const updatedTask = await updateTask(task.id, updates as never, projectId);
if (revision !== editAutoSaveRevisionRef.current) return;
if (replanAfterExecutionModeChange && includeDescription) {
const normalizedUpdatedMode = normalizeExecutionModeValue(updatedTask.executionMode);
await rebuildTaskSpec(task.id, projectId);
editSaveTriggeredReplanRef.current = true;
setEditAutoSaveStatus("saved");
requestClose();
addToast(t("taskDetail.executionMode.replanning", "Execution mode updated to {{mode}} — {{id}} returned to Planning for replanning", { mode: normalizedUpdatedMode, id: task.id }), "info");
return true;
}
onTaskUpdated?.(updatedTask);
setEditAutoSaveStatus("saved");
return true;
} catch (err) {
if (revision === editAutoSaveRevisionRef.current) {
if (replanAfterExecutionModeChange) {
setEditExecutionMode(normalizeExecutionModeValue(task.executionMode));
}
setEditAutoSaveStatus("error");
addToast(t("taskDetail.updateFailed", "Failed to update {{id}}: {{error}}", { id: task.id, error: getErrorMessage(err) }), "error");
}
@@ -1624,15 +1664,16 @@ export function TaskDetailContent({
setIsSaving(false);
}
}
}, [addToast, buildEditUpdates, onTaskUpdated, projectId, task.id]);
}, [addToast, buildEditUpdates, confirm, onTaskUpdated, projectId, requestClose, task.column, task.executionMode, task.id]);
const handleAutoSaveDescription = useCallback(async (_description: string) => {
await persistEditChanges(true);
}, [persistEditChanges]);
const handleSave = useCallback(async () => {
editSaveTriggeredReplanRef.current = false;
const didSave = await persistEditChanges(true);
if (!didSave) {
if (!didSave || editSaveTriggeredReplanRef.current) {
return;
}
addToast(t("taskDetail.updateSuccess", "Updated {{id}}", { id: task.id }), "success");
@@ -1710,6 +1751,18 @@ export function TaskDetailContent({
const currentMode = normalizeExecutionModeValue(task.executionMode);
const nextMode = currentMode === "fast" ? "standard" : "fast";
const previousMode = inlineExecutionMode;
const shouldReplan = requiresExecutionModeReplan(task.column);
if (shouldReplan) {
const shouldChangeMode = await confirm({
title: t("taskDetail.executionMode.replanTitle", "Change execution mode and replan?"),
message: t("taskDetail.executionMode.replanMessage", "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for {{mode}} mode.", { mode: nextMode }),
});
if (!shouldChangeMode) {
setInlineExecutionMode(previousMode);
return;
}
}
setInlineExecutionMode(nextMode);
setIsSavingInlineExecutionMode(true);
@@ -1717,6 +1770,12 @@ export function TaskDetailContent({
try {
const updatedTask = await updateTask(task.id, { executionMode: nextMode === "fast" ? "fast" : null }, projectId);
const normalizedUpdatedMode = normalizeExecutionModeValue(updatedTask.executionMode);
if (shouldReplan) {
await rebuildTaskSpec(task.id, projectId);
requestClose();
addToast(t("taskDetail.executionMode.replanning", "Execution mode updated to {{mode}} — {{id}} returned to Planning for replanning", { mode: normalizedUpdatedMode, id: task.id }), "info");
return;
}
setInlineExecutionMode(normalizedUpdatedMode);
onTaskUpdated?.(updatedTask);
addToast(t("taskDetail.executionMode.updated", "Execution mode updated to {{mode}}", { mode: normalizedUpdatedMode }), "success");
@@ -1728,7 +1787,7 @@ export function TaskDetailContent({
setIsSavingInlineExecutionMode(false);
}
}
}, [task.id, task.executionMode, projectId, inlineExecutionMode, onTaskUpdated, addToast]);
}, [task.id, task.column, task.executionMode, projectId, inlineExecutionMode, onTaskUpdated, addToast, confirm, requestClose]);
const handleInlineNoCommitsExpectedToggle = useCallback(async () => {
const nextValue = !inlineNoCommitsExpected;
@@ -1775,7 +1834,6 @@ export function TaskDetailContent({
const fileInputRef = useRef<HTMLInputElement>(null);
const { nodes } = useNodes();
const { confirm, confirmWithChoice, confirmWithCheckbox } = useConfirm();
const handleUnlinkGithubIssue = useCallback(async () => {
if (!canEdit || !githubTrackedIssue || isSavingGithubTracking) return;
@@ -1811,10 +1869,6 @@ export function TaskDetailContent({
activeTab === "chat" && activitySegment === "raw-logs",
projectId,
);
const requestClose = useCallback(() => {
onRequestClose?.();
}, [onRequestClose]);
useEffect(() => {
if (embedded) return;
const handleKey = (e: KeyboardEvent) => {

View File

@@ -892,6 +892,40 @@ describe("TaskDetailModal", () => {
});
});
it("confirms and replans when edit-mode executionMode changes on a todo task", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
mockUpdate.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", title: "Test", description: "Desc", executionMode: null }) as Task);
mockRebuild.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", status: "needs-replan", executionMode: null }) as Task);
const { container } = render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "todo", title: "Test", description: "Desc", executionMode: "fast" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
addToast={noop}
/>,
);
fireEvent.click(container.querySelector(".modal-edit-btn")!);
fireEvent.change(screen.getByTestId("task-form-execution-mode-select"), { target: { value: "standard" } });
fireEvent.click(screen.getByText("Save"));
await waitFor(() => {
expect(mockConfirm).toHaveBeenCalledWith(expect.objectContaining({
title: "Change execution mode and replan?",
}));
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: null }, undefined);
expect(mockRebuild).toHaveBeenCalledWith("FN-001", undefined);
});
expect(mockUpdate.mock.invocationCallOrder[0]).toBeLessThan(mockRebuild.mock.invocationCallOrder[0]);
});
it("omits executionMode from update payload when unchanged", async () => {
const { updateTask } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
@@ -940,13 +974,13 @@ describe("TaskDetailModal", () => {
const { updateTask } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
mockUpdate
.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", priority: "urgent", executionMode: "standard" }) as Task)
.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", priority: "urgent", executionMode: "fast" }) as Task);
.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", priority: "urgent", executionMode: "standard" }) as Task)
.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", priority: "urgent", executionMode: "fast" }) as Task);
render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "todo", priority: "high", executionMode: "standard" })}
task={makeTask({ id: "FN-001", column: "triage", priority: "high", executionMode: "standard" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
@@ -1080,13 +1114,14 @@ describe("TaskDetailModal", () => {
expect(addToast).toHaveBeenCalledWith("Failed to update FN-001: Request failed", "error");
});
it("toggles inline execution mode from standard to fast", async () => {
const { updateTask } = await import("../../api");
it("prompts before replanning a todo task when changing inline execution mode from standard to fast", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
const addToast = vi.fn();
const onTaskUpdated = vi.fn();
const updatedTask = makeTask({ id: "FN-001", column: "todo", executionMode: "fast" });
mockUpdate.mockResolvedValueOnce(updatedTask as Task);
mockUpdate.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", executionMode: "fast" }) as Task);
mockRebuild.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", status: "needs-replan", executionMode: "fast" }) as Task);
render(
<TaskDetailModal
@@ -1102,23 +1137,58 @@ describe("TaskDetailModal", () => {
/>,
);
const toggle = screen.getByRole("button", { name: "Execution mode: standard" });
fireEvent.click(toggle);
fireEvent.click(screen.getByRole("button", { name: "Execution mode: standard" }));
await waitFor(() => {
expect(mockConfirm).toHaveBeenCalledWith(expect.objectContaining({
title: "Change execution mode and replan?",
message: "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for fast mode.",
}));
});
await waitFor(() => {
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: "fast" }, undefined);
expect(mockRebuild).toHaveBeenCalledWith("FN-001", undefined);
});
expect(onTaskUpdated).toHaveBeenCalledWith(updatedTask);
expect(addToast).toHaveBeenCalledWith("Execution mode updated to fast", "success");
await waitFor(() => {
expect(screen.getByRole("button", { name: "Execution mode: fast" })).toHaveAttribute("aria-pressed", "true");
});
expect(mockUpdate.mock.invocationCallOrder[0]).toBeLessThan(mockRebuild.mock.invocationCallOrder[0]);
expect(onTaskUpdated).not.toHaveBeenCalled();
expect(addToast).toHaveBeenCalledWith("Execution mode updated to fast — FN-001 returned to Planning for replanning", "info");
});
it("toggles inline execution mode from fast to standard", async () => {
const { updateTask } = await import("../../api");
it("cancels a todo inline execution mode change before update or replan", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
mockConfirm.mockResolvedValueOnce(false);
render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "todo", executionMode: "standard" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
addToast={noop}
/>,
);
fireEvent.click(screen.getByRole("button", { name: "Execution mode: standard" }));
await waitFor(() => {
expect(mockConfirm).toHaveBeenCalled();
});
expect(mockUpdate).not.toHaveBeenCalled();
expect(mockRebuild).not.toHaveBeenCalled();
expect(screen.getByRole("button", { name: "Execution mode: standard" })).toHaveAttribute("aria-pressed", "false");
});
it("prompts and replans a todo task when changing inline execution mode from fast to standard", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
mockUpdate.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", executionMode: null }) as Task);
mockRebuild.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", status: "needs-replan", executionMode: null }) as Task);
render(
<TaskDetailModal
@@ -1136,18 +1206,88 @@ describe("TaskDetailModal", () => {
fireEvent.click(screen.getByRole("button", { name: "Execution mode: fast" }));
await waitFor(() => {
expect(mockConfirm).toHaveBeenCalledWith(expect.objectContaining({
message: "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for standard mode.",
}));
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: null }, undefined);
expect(mockRebuild).toHaveBeenCalledWith("FN-001", undefined);
});
expect(mockUpdate.mock.invocationCallOrder[0]).toBeLessThan(mockRebuild.mock.invocationCallOrder[0]);
});
it("prompts and replans an in-progress task when changing inline execution mode", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
mockUpdate.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "in-progress", executionMode: "fast" }) as Task);
mockRebuild.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "triage", status: "needs-replan", executionMode: "fast" }) as Task);
render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "in-progress", executionMode: "standard" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
addToast={noop}
/>,
);
fireEvent.click(screen.getByRole("button", { name: "Execution mode: standard" }));
await waitFor(() => {
expect(screen.getByRole("button", { name: "Execution mode: standard" })).toHaveAttribute("aria-pressed", "false");
expect(mockConfirm).toHaveBeenCalled();
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: "fast" }, undefined);
expect(mockRebuild).toHaveBeenCalledWith("FN-001", undefined);
});
});
it("reverts inline execution mode when save fails", async () => {
const { updateTask } = await import("../../api");
it("updates triage inline execution mode without prompting or replanning", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
const addToast = vi.fn();
mockUpdate.mockRejectedValueOnce(new Error("Request failed"));
const onTaskUpdated = vi.fn();
const updatedTask = makeTask({ id: "FN-001", column: "triage", executionMode: "fast" });
mockUpdate.mockResolvedValueOnce(updatedTask as Task);
render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "triage", executionMode: "standard" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
onTaskUpdated={onTaskUpdated}
addToast={addToast}
/>,
);
fireEvent.click(screen.getByRole("button", { name: "Execution mode: standard" }));
await waitFor(() => {
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: "fast" }, undefined);
});
expect(mockConfirm).not.toHaveBeenCalled();
expect(mockRebuild).not.toHaveBeenCalled();
expect(onTaskUpdated).toHaveBeenCalledWith(updatedTask);
expect(addToast).toHaveBeenCalledWith("Execution mode updated to fast", "success");
await waitFor(() => {
expect(screen.getByRole("button", { name: "Execution mode: fast" })).toHaveAttribute("aria-pressed", "true");
});
});
it("reverts inline execution mode when active-task replan fails after update", async () => {
const { updateTask, rebuildTaskSpec } = await import("../../api");
const mockUpdate = vi.mocked(updateTask);
const mockRebuild = vi.mocked(rebuildTaskSpec);
const addToast = vi.fn();
mockUpdate.mockResolvedValueOnce(makeTask({ id: "FN-001", column: "todo", executionMode: "fast" }) as Task);
mockRebuild.mockRejectedValueOnce(new Error("Replan failed"));
render(
<TaskDetailModal
@@ -1166,11 +1306,12 @@ describe("TaskDetailModal", () => {
await waitFor(() => {
expect(mockUpdate).toHaveBeenCalledWith("FN-001", { executionMode: "fast" }, undefined);
expect(mockRebuild).toHaveBeenCalledWith("FN-001", undefined);
});
await waitFor(() => {
expect(screen.getByRole("button", { name: "Execution mode: standard" })).toHaveAttribute("aria-pressed", "false");
});
expect(addToast).toHaveBeenCalledWith("Failed to update FN-001: Request failed", "error");
expect(addToast).toHaveBeenCalledWith("Failed to update FN-001: Replan failed", "error");
});
it("disables inline execution mode toggle while save is in-flight", async () => {
@@ -1183,7 +1324,7 @@ describe("TaskDetailModal", () => {
render(
<TaskDetailModal
initialTab="definition"
task={makeTask({ id: "FN-001", column: "todo", executionMode: "standard" })}
task={makeTask({ id: "FN-001", column: "triage", executionMode: "standard" })}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}

View File

@@ -34,6 +34,7 @@ vi.mock("../../api", async (importOriginal) => {
fetchTaskDetail: vi.fn().mockResolvedValue(makeTask()),
fetchAgentLogs: vi.fn().mockResolvedValue([]),
requestSpecRevision: vi.fn().mockResolvedValue({}),
rebuildTaskSpec: vi.fn().mockResolvedValue(makeTask({ column: "triage", status: "needs-replan" })),
approvePlan: vi.fn().mockResolvedValue({}),
rejectPlan: vi.fn().mockResolvedValue({}),
duplicateTask: vi.fn().mockResolvedValue({}),

View File

@@ -7306,6 +7306,9 @@
"executionMode": {
"ariaLabel": "Execution mode: {{mode}}",
"fast": "Fast",
"replanMessage": "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for {{mode}} mode.",
"replanTitle": "Change execution mode and replan?",
"replanning": "Execution mode updated to {{mode}} — {{id}} returned to Planning for replanning",
"standard": "Standard",
"updated": "Execution mode updated to {{mode}}"
},

View File

@@ -7297,7 +7297,10 @@
"ariaLabel": "Modo de ejecución: {{mode}}",
"fast": "Rápido",
"standard": "Estándar",
"updated": "Modo de ejecución actualizado a {{mode}}"
"updated": "Modo de ejecución actualizado a {{mode}}",
"replanMessage": "Cambiar el modo de ejecución de esta tarea la devolverá a Planificación para que Fusion reconstruya el plan para el modo {{mode}}.",
"replanTitle": "¿Cambiar el modo de ejecución y replanificar?",
"replanning": "Modo de ejecución actualizado a {{mode}} — {{id}} volvió a Planificación para replanificación"
},
"executionModeFast": "Rápido",
"executionModeStandard": "Estándar",

View File

@@ -7297,7 +7297,10 @@
"ariaLabel": "Mode d'exécution : {{mode}}",
"fast": "Rapide",
"standard": "Standard",
"updated": "Mode d'exécution mis à jour : {{mode}}"
"updated": "Mode d'exécution mis à jour : {{mode}}",
"replanMessage": "Changer le mode d'exécution de cette tâche la renverra en planification afin que Fusion reconstruise le plan pour le mode {{mode}}.",
"replanTitle": "Changer le mode d'exécution et replanifier ?",
"replanning": "Mode d'exécution mis à jour vers {{mode}} — {{id}} est revenue en planification pour replanification"
},
"executionModeFast": "Rapide",
"executionModeStandard": "Standard",

View File

@@ -7297,7 +7297,10 @@
"ariaLabel": "실행 모드: {{mode}}",
"fast": "빠름",
"standard": "표준",
"updated": "실행 모드가 {{mode}}로 업데이트되었습니다"
"updated": "실행 모드가 {{mode}}로 업데이트되었습니다",
"replanMessage": "이 작업의 실행 모드를 변경하면 Fusion이 {{mode}} 모드용 계획을 다시 만들 수 있도록 작업이 계획으로 돌아갑니다.",
"replanTitle": "실행 모드를 변경하고 다시 계획할까요?",
"replanning": "실행 모드가 {{mode}}로 업데이트되었습니다 — {{id}}가 재계획을 위해 계획으로 돌아갔습니다"
},
"executionModeFast": "빠름",
"executionModeStandard": "표준",

View File

@@ -7297,7 +7297,10 @@
"ariaLabel": "执行模式:{{mode}}",
"fast": "快速",
"standard": "标准",
"updated": "执行模式已更新为 {{mode}}"
"updated": "执行模式已更新为 {{mode}}",
"replanMessage": "更改此任务的执行模式会将其移回规划,以便 Fusion 可以为 {{mode}} 模式重新生成计划。",
"replanTitle": "更改执行模式并重新规划?",
"replanning": "执行模式已更新为 {{mode}} — {{id}} 已返回规划以重新规划"
},
"executionModeFast": "快速",
"executionModeStandard": "标准",

View File

@@ -7297,7 +7297,10 @@
"ariaLabel": "執行模式:{{mode}}",
"fast": "快速",
"standard": "標準",
"updated": "執行模式已更新為 {{mode}}"
"updated": "執行模式已更新為 {{mode}}",
"replanMessage": "變更此任務的執行模式會將其移回規劃,讓 Fusion 可以為 {{mode}} 模式重新產生計畫。",
"replanTitle": "變更執行模式並重新規劃?",
"replanning": "執行模式已更新為 {{mode}} — {{id}} 已返回規劃以重新規劃"
},
"executionModeFast": "快速",
"executionModeStandard": "標準",

View File

@@ -7345,6 +7345,9 @@ export default interface Resources {
"executionMode": {
"ariaLabel": "Execution mode: {{mode}}",
"fast": "Fast",
"replanMessage": "Changing execution mode for this task will move it back to Planning so Fusion can rebuild the plan for {{mode}} mode.",
"replanTitle": "Change execution mode and replan?",
"replanning": "Execution mode updated to {{mode}} — {{id}} returned to Planning for replanning",
"standard": "Standard",
"updated": "Execution mode updated to {{mode}}"
},