feat: change backup format to plain SQL, admin-only cron, backup now button, import restore UI

This commit is contained in:
ff
2026-04-11 23:37:43 -04:00
parent 4025ca45e0
commit 66a3d271f1
6 changed files with 329 additions and 269 deletions

View File

@@ -14,7 +14,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { FolderOpen, Trash2 } from "lucide-react";
import { FolderOpen, HardDrive, Trash2 } from "lucide-react";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import { FolderBrowserModal } from "./folder-browser-modal";
@@ -102,6 +102,21 @@ export function BackupDestinationManager() {
},
});
const backupNowMutation = useMutation({
mutationFn: async () => {
const res = await apiRequest("POST", "/api/database-management/backup-path");
if (!res.ok) throw new Error((await res.json()).error || "Backup failed");
return res.json();
},
onSuccess: (data) => {
toast({ title: "Backup complete", description: `Saved: ${data.filename}` });
queryClient.invalidateQueries({ queryKey: ["/db/status"] });
},
onError: (err: any) => {
toast({ title: "Backup failed", description: err.message, variant: "destructive" });
},
});
// ==============================
// Folder browser
// ==============================
@@ -172,13 +187,25 @@ export function BackupDestinationManager() {
className="flex justify-between items-center border rounded p-2"
>
<span className="text-sm text-gray-700">{d.path}</span>
<Button
size="sm"
variant="destructive"
onClick={() => setDeleteId(d.id)}
>
<Trash2 className="h-4 w-4" />
</Button>
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
onClick={() => backupNowMutation.mutate()}
disabled={backupNowMutation.isPending}
title="Backup now to this destination"
>
<HardDrive className="h-4 w-4 mr-1" />
{backupNowMutation.isPending ? "Backing up..." : "Backup Now"}
</Button>
<Button
size="sm"
variant="destructive"
onClick={() => setDeleteId(d.id)}
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
))}
</div>