+ {snapLoading &&
}
+ {!snapLoading && snapshots.length === 0 && (
+
+ Aucun snapshot disponible
+
+ )}
+ {!snapLoading && snapshots.length > 0 && (
+
+
+ {snapshots.length} snapshot(s) — 20 derniers conservés
+
+ {snapshots.map((snap, i) => {
+ const isDiffOpen = snapDiff?.snapshot === snap;
+ // Parse timestamp from filename: db.zone.YYYYMMDD-HHMMSS
+ const ts = snap.match(/(\d{8}-\d{6})$/)?.[1];
+ const date = ts
+ ? new Date(
+ ts.slice(0,4)+"-"+ts.slice(4,6)+"-"+ts.slice(6,8)+"T"+
+ ts.slice(9,11)+":"+ts.slice(11,13)+":"+ts.slice(13,15)
+ ).toLocaleString("fr-FR")
+ : snap;
+ return (
+
+
+
{i===0?"🕐":"○"}
+
+ {rollbackConf === snap ? (
+
+
+
+
+ ) : (
+
+
+
+
+ )}
+
+ {isDiffOpen && (
+
+ {!snapDiff.lines ? (
+
+ ) : snapDiff.error ? (
+
+ ⚠ {snapDiff.error}
+
+ ) : snapDiff.lines.filter(l=>l.type!=="eq").length === 0 ? (
+
+ Aucune différence avec la version actuelle
+
+ ) : (
+
+ {snapDiff.lines.map((line, li) => line.type === "eq" ? null : (
+
+ {line.type==="add" ? "+" : "−"} {line.text}
+
+ ))}
+
+ )}
+
+ )}
+
+ );
+ })}
+
+ )}
+
+ ⚠ La restauration remplace le fichier de zone actuel et recharge BIND.
+ Le snapshot est validé avec named-checkzone avant application.
+
+