diff --git a/.changeset/fn-6987-mission-delete-confirm.md b/.changeset/fn-6987-mission-delete-confirm.md new file mode 100644 index 0000000000..eda6f509d0 --- /dev/null +++ b/.changeset/fn-6987-mission-delete-confirm.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Open Mission Manager mission-delete confirmations in the standard modal dialog. +category: fix +dev: Routes mission list and detail delete affordances through ConfirmDialogProvider with regression coverage. diff --git a/packages/dashboard/app/components/MissionManager.tsx b/packages/dashboard/app/components/MissionManager.tsx index 8da4285fdb..bdc2f78e86 100644 --- a/packages/dashboard/app/components/MissionManager.tsx +++ b/packages/dashboard/app/components/MissionManager.tsx @@ -28,6 +28,7 @@ import { FileText, RefreshCw, } from "lucide-react"; +import { useConfirm } from "../hooks/useConfirm"; import type { ToastType } from "../hooks/useToast"; import { useViewportMode } from "../hooks/useViewportMode"; import { useNavigationHistoryContext } from "../hooks/useNavigationHistory"; @@ -614,6 +615,7 @@ function normalizeMissionHierarchy(mission: MissionWithHierarchy): MissionWithHi export function MissionManager({ isOpen, isInline = false, onClose, addToast, projectId, onSelectTask, availableTasks = [], resumeSessionId, targetMissionId, milestoneSliceResumeSessionId, onMilestoneSliceResumeFetchError, onNavigateToGoal }: MissionManagerProps) { const { t } = useTranslation("app"); + const { confirm } = useConfirm(); const isActive = isInline || isOpen; const cacheSuffix = projectId ?? ""; const missionsCacheKey = `${SWR_CACHE_KEYS.MISSIONS_PREFIX}${cacheSuffix}`; @@ -1712,11 +1714,28 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr setSelectedMission(null); } await loadMissions(); - setDeleteConfirmId(null); } catch (err) { addToast(getErrorMessage(err) || t("missions.deleteFailed", "Failed to delete mission"), "error"); } - }, [addToast, loadMissions, selectedMission, projectId]); + }, [addToast, loadMissions, selectedMission, projectId, t]); + + const requestDeleteMission = useCallback(async (missionId: string) => { + /* + FNXC:MissionManager 2026-06-24-00:00: + Mission deletes are destructive and must use the app-level modal confirmation from both list and detail delete affordances. Keeping this path out of the inline mission-confirm-panel prevents the prompt from landing in the sidebar footer, detail pane, or below mobile scroll content. + */ + const confirmed = await confirm({ + title: t("missions.deleteMission", "Delete mission"), + message: t("missions.deleteConfirm", "Delete this {{type}}? This cannot be undone.", { type: "mission" }), + confirmLabel: t("missions.deleteButton", "Delete"), + cancelLabel: t("missions.cancelButton", "Cancel"), + danger: true, + }); + if (!confirmed) { + return; + } + await handleDeleteMission(missionId); + }, [confirm, handleDeleteMission, t]); // Milestone handlers const handleCreateMilestone = useCallback(() => { @@ -2753,7 +2772,7 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr