"use client" import { useState } from "react" import useSWR from "swr" import { HardDrive, Loader2, Pencil, RefreshCw } from "lucide-react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Badge } from "./ui/badge" import { Button } from "./ui/button" import { Checkbox } from "./ui/checkbox" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog" import { Input } from "./ui/input" import { Label } from "./ui/label" import { fetchApi } from "../lib/api-config" import { buildRetention, parseRetention, RETENTION } from "../lib/backup-retention" import { useT } from "../lib/i18n/provider" interface StorageRetention { id: string; type: string; prune_backups: string; digest: string } const fetcher = (url: string) => fetchApi<{ storages: StorageRetention[] }>(url) export function BackupStorageRetention() { const t = useT() const { data, error, mutate, isValidating } = useSWR("/api/vm-backup-storages", fetcher) const [editing, setEditing] = useState(null) const [fields, setFields] = useState>({}) const [keepAll, setKeepAll] = useState(false) const [useDefault, setUseDefault] = useState(false) const [busy, setBusy] = useState(false) const [message, setMessage] = useState("") const [saveError, setSaveError] = useState("") function edit(storage: StorageRetention) { const policy = parseRetention(storage.prune_backups) setFields(policy.fields) setKeepAll(policy.keepAll) setUseDefault(!storage.prune_backups) setSaveError("") setMessage("") setEditing(storage) } async function save() { if (!editing || busy) return const prune = useDefault ? "" : buildRetention(fields, keepAll) if (!useDefault && !prune) return setSaveError(t("backup.storageRetention.choosePolicy")) setBusy(true) setSaveError("") try { await fetchApi(`/api/vm-backup-storages/${encodeURIComponent(editing.id)}`, { method: "PUT", body: JSON.stringify({ digest: editing.digest, prune_backups: prune }), }) setMessage(t("backup.storageRetention.saved")) setEditing(null) await mutate() } catch (error) { setSaveError(`${t("backup.storageRetention.saveFailed")} ${error instanceof Error ? error.message : ""}`) } finally { setBusy(false) } } return {t("backup.storageRetention.title")}

{t("backup.storageRetention.description")}

{message &&

{message}

} {error ?

{t("backup.storageRetention.loadFailed")}

: !data ? : !data.storages.length ?

{t("backup.storageRetention.empty")}

: data.storages.map(storage =>
{storage.id}{storage.type} {storage.prune_backups || t("backup.storageRetention.default")}
)}
{ if (!open && !busy) setEditing(null) }}> {t("backup.storageRetention.editTitle", { storage: editing?.id ?? "" })} {t("backup.storageRetention.effect")}
{RETENTION.map(key =>
setFields(previous => ({ ...previous, [key]: event.target.value }))} />
)}
{saveError &&

{saveError}

}
}