import { useState, useEffect, useCallback, useRef } from "react"; import { FileSearch, Upload } from "lucide-react"; import { open } from "@tauri-apps/plugin-dialog"; import { Button } from "../ui/Button"; import { BackupProgress } from "./BackupProgress"; import { useBackupStore } from "../../stores/backupStore"; import { useNotificationStore } from "../../stores/notificationStore"; import { detectPgTools, pgRestore, getSchemas } from "../../lib/commands"; import type { PgToolStatus } from "../../lib/types"; interface RestorePageProps { connectionId: string; } const PLATFORM_INSTALL_INSTRUCTIONS: Record = { darwin: "brew install libpq", linux: "sudo apt install postgresql-client # Debian/Ubuntu\nsudo dnf install postgresql # Fedora\nsudo pacman -S postgresql # Arch", win32: "Download PostgreSQL installer from https://www.postgresql.org/download/windows/ and ensure pg_restore is in your PATH.", }; function getPlatformInstructions(): string { const platform = typeof navigator !== "undefined" ? navigator.platform.toLowerCase() : ""; if (platform.includes("mac") || platform.includes("darwin")) return PLATFORM_INSTALL_INSTRUCTIONS.darwin; if (platform.includes("linux")) return PLATFORM_INSTALL_INSTRUCTIONS.linux; if (platform.includes("win")) return PLATFORM_INSTALL_INSTRUCTIONS.win32; return PLATFORM_INSTALL_INSTRUCTIONS.linux; } export function RestorePage({ connectionId }: RestorePageProps) { const [filePath, setFilePath] = useState(""); const [format, setFormat] = useState("custom"); const [clean, setClean] = useState(true); const [schema, setSchema] = useState(""); const [confirmed, setConfirmed] = useState(false); const [toolStatus, setToolStatus] = useState(null); const [checkingTools, setCheckingTools] = useState(true); const [availableSchemas, setAvailableSchemas] = useState([]); const activeJobId = useBackupStore((s) => s.activeJobId); const jobs = useBackupStore((s) => s.jobs); const startJob = useBackupStore((s) => s.startJob); const notify = useNotificationStore((s) => s.notify); const activeJob = jobs.find((j) => j.id === activeJobId); const isRunning = activeJob?.status === "running"; const pendingJobRef = useRef(null); useEffect(() => { if (!pendingJobRef.current || !activeJob) return; if (activeJob.id !== pendingJobRef.current) return; if (activeJob.status === "completed") { notify("Restore completed successfully", "success"); pendingJobRef.current = null; } else if (activeJob.status === "failed") { notify( `Restore failed: ${activeJob.error_message || "Unknown error"}`, "error", ); pendingJobRef.current = null; } }, [activeJob, notify]); useEffect(() => { setCheckingTools(true); setConfirmed(false); detectPgTools() .then((status) => setToolStatus(status)) .catch(() => setToolStatus({ pg_dump_found: false, pg_restore_found: false, pg_dump_version: null, pg_restore_version: null, }), ) .finally(() => setCheckingTools(false)); getSchemas(connectionId) .then((schemas) => setAvailableSchemas(schemas)) .catch(() => setAvailableSchemas([])); }, [connectionId]); const handlePickFile = useCallback(async () => { const picked = await open({ multiple: false, filters: [ { name: "Backup Files", extensions: ["dump", "sql", "tar", "custom", "gz"], }, ], }); if (picked && typeof picked === "string") setFilePath(picked); }, []); const handleStartRestore = useCallback(async () => { if (!filePath) { notify("Please select a file path", "error"); return; } const jobId = `restore-${Date.now()}`; startJob(jobId, "restore"); pendingJobRef.current = jobId; try { await pgRestore(connectionId, { format, filePath, clean, schema: schema || undefined, }); } catch (e) { const msg = e instanceof Error ? e.message : String(e); useBackupStore.getState().failJob(jobId, msg); } }, [filePath, format, clean, schema, connectionId, startJob, notify]); const toolsMissing = toolStatus && !toolStatus.pg_restore_found; const canStart = filePath && confirmed && !isRunning; return (
{/* Toolbar header */}
Restore Restore a database from a backup file
{/* Content */}
{/* Tool check */} {checkingTools && (

Checking for pg_restore...

)} {toolsMissing && (

pg_restore not found

The PostgreSQL client tools are required for backup/restore operations. Install them using:

                                {getPlatformInstructions()}
                            
)} {!checkingTools && !toolsMissing && ( <> {/* Configuration card */}
{/* Format */}
{/* Backup file */}
setFilePath(e.target.value) } placeholder="/path/to/backup.dump" className="flex-1 px-4 py-2 text-sm text-text placeholder-text-muted/50 border-b border-border focus:border-accent focus:outline-none transition-colors" />
{/* Schema (optional) */}
{/* Clean toggle */}
{/* Destructive confirmation */}
{/* Progress */} {activeJob && (
)} {/* Actions */}
)}
); }