import { useCallback, useEffect, useState } from "react"; import type { ProjectInfo } from "../api"; import type { ColorTheme, Column, MergeResult, Task, TaskCreateInput, ThemeMode } from "@fusion/core"; import type { UseProjectActionsResult } from "../hooks/useProjectActions"; import type { ModalManager } from "../hooks/useModalManager"; import type { UseTaskHandlersResult } from "../hooks/useTaskHandlers"; import type { Toast, ToastType } from "../hooks/useToast"; import { ModalErrorBoundary } from "./ErrorBoundary"; import { TaskDetailModal } from "./TaskDetailModal"; import { SettingsModal } from "./SettingsModal"; import { GitHubImportModal } from "./GitHubImportModal"; import { PlanningModeModal } from "./PlanningModeModal"; import { SubtaskBreakdownModal } from "./SubtaskBreakdownModal"; import { TerminalModal } from "./TerminalModal"; import { ScriptsModal } from "./ScriptsModal"; import { FileBrowserModal } from "./FileBrowserModal"; import { UsageIndicator } from "./UsageIndicator"; import { ScheduledTasksModal } from "./ScheduledTasksModal"; import { NewTaskModal } from "./NewTaskModal"; import { ActivityLogModal } from "./ActivityLogModal"; import { GitManagerModal } from "./GitManagerModal"; import { WorkflowStepManager } from "./WorkflowStepManager"; import { AgentListModal } from "./AgentListModal"; import { SetupWizardModal } from "./SetupWizardModal"; import { ModelOnboardingModal } from "./ModelOnboardingModal"; import { ToastContainer } from "./ToastContainer"; interface AppModalsProps { projectId?: string; tasks: Task[]; projects: ProjectInfo[]; currentProject: ProjectInfo | null; addToast: (message: string, type?: ToastType) => void; toasts: Toast[]; removeToast: (id: number) => void; modalManager: ModalManager; projectActions: Pick; taskHandlers: Pick; taskOperations: { moveTask: (taskId: string, column: Column, position?: number) => Promise; deleteTask: (taskId: string) => Promise; mergeTask: (taskId: string) => Promise; retryTask: (taskId: string) => Promise; duplicateTask: (taskId: string) => Promise; }; deepLink: { handleDetailClose: () => void; }; settings: { prAuthAvailable: boolean; themeMode: ThemeMode; colorTheme: ColorTheme; setThemeMode: (mode: ThemeMode) => void; setColorTheme: (theme: ColorTheme) => void; }; /** Optional override for the settings modal close handler. When provided, this is called instead of modalManager.closeSettings. */ onSettingsClose?: () => void; /** Optional callback to reopen the onboarding guide from Settings. Closes Settings and opens ModelOnboardingModal. */ onReopenOnboarding?: () => void; } export function AppModals({ projectId, tasks, projects, currentProject, addToast, toasts, removeToast, modalManager, projectActions, taskHandlers, taskOperations, deepLink, settings, onSettingsClose, onReopenOnboarding, }: AppModalsProps) { const [firstCreatedTask, setFirstCreatedTask] = useState(null); // Use the override handler if provided, otherwise fall back to modalManager.closeSettings const handleSettingsClose = onSettingsClose ?? modalManager.closeSettings; const handleOpenNewTask = useCallback(() => { modalManager.openNewTask(); }, [modalManager]); const handleOpenGitHubImport = useCallback(() => { modalManager.openGitHubImport(); }, [modalManager]); const handleOnboardingViewTask = useCallback((task: Task) => { setFirstCreatedTask(null); modalManager.closeModelOnboarding(); modalManager.openDetailTask(task); }, [modalManager]); const handleModalCreateWithOnboardingTracking = useCallback( async (input: TaskCreateInput): Promise => { const task = await taskHandlers.handleModalCreate(input); if (modalManager.modelOnboardingOpen) { setFirstCreatedTask(task); } return task; }, [taskHandlers.handleModalCreate, modalManager.modelOnboardingOpen], ); useEffect(() => { if (!modalManager.modelOnboardingOpen && firstCreatedTask) { setFirstCreatedTask(null); } }, [modalManager.modelOnboardingOpen, firstCreatedTask]); return ( <> {modalManager.detailTask && ( )} {modalManager.settingsOpen && ( )} {modalManager.filesOpen && ( )} {modalManager.schedulesOpen && ( )} { const task = tasks.find((candidate) => candidate.id === taskId); if (task) { modalManager.openDetailTask(task); } }} /> {modalManager.setupWizardOpen && ( )} {modalManager.modelOnboardingOpen && ( )} ); }