v0.12.2: restore section simplification — snapshot filtering, auto-stop/restart, UI cleanup
- StackDataProvider interface extended with StopStack/StartStack
- backup.Manager.GetStackHDDMounts() delegates to stackProvider
- RestoreApp() auto-stops app before restic restore, restarts after (even on failure)
- stackAdapter in main.go wires StopStack/StartStack through to stacks.Manager
- GET /api/backup/snapshots?stack={name} filters snapshots by app HDD paths via filterSnapshotsByPaths()
- Restore section simplified: no path list, per-app filtered snapshots, human-friendly timestamp format, single calm warning, empty-result inline message
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -451,31 +451,28 @@
|
||||
<option value="">— Válasszon —</option>
|
||||
{{range .Backup.AppDataInfo}}
|
||||
{{if and .HasHDDData .BackupEnabled}}
|
||||
<option value="{{.StackName}}" data-paths="{{range $i, $p := .HDDPaths}}{{if $i}},{{end}}{{$p.HostPath}}{{end}}">{{.DisplayName}}</option>
|
||||
<option value="{{.StackName}}">{{.DisplayName}}</option>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="restore-form-row">
|
||||
<label class="restore-label">Pillanatkép:</label>
|
||||
<select id="restore-snapshot" class="restore-select">
|
||||
<option value="">— Betöltés... —</option>
|
||||
<select id="restore-snapshot" class="restore-select" onchange="onRestoreConfirmChange()">
|
||||
<option value="">— Válasszon alkalmazást —</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="restore-paths" class="restore-paths" style="display:none;">
|
||||
<span class="restore-label">Visszaállítandó útvonalak:</span>
|
||||
<ul id="restore-paths-list" class="repo-path-list"></ul>
|
||||
<div id="restore-no-snapshots" class="restore-warning" style="display:none;">
|
||||
Még nincs mentés felhasználói adattal.
|
||||
</div>
|
||||
<div class="restore-warning">
|
||||
<strong>FIGYELMEZTETÉS</strong><br>
|
||||
A visszaállítás FELÜLÍRJA a kiválasztott alkalmazás jelenlegi adatait a mentés pillanatának állapotával.
|
||||
Ez a művelet NEM vonható vissza!<br>
|
||||
Javasoljuk az alkalmazás leállítását a visszaállítás előtt.
|
||||
⚠ A visszaállítás felülírja az alkalmazás jelenlegi adatait a kiválasztott mentés állapotával.
|
||||
Az alkalmazás a folyamat során automatikusan leáll és újraindul.
|
||||
</div>
|
||||
<div class="restore-confirm">
|
||||
<label>
|
||||
<input type="checkbox" id="restore-confirm-cb" onchange="onRestoreConfirmChange()">
|
||||
Megértettem, visszaállítás saját felelősségre.
|
||||
Megértettem, visszaállítás indítása.
|
||||
</label>
|
||||
</div>
|
||||
<div class="restore-actions">
|
||||
@@ -595,46 +592,48 @@ function copyResticPw() {
|
||||
}
|
||||
|
||||
// Restore section
|
||||
var huDays = ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'];
|
||||
function formatSnapshot(s) {
|
||||
var t = new Date(s.time);
|
||||
var pad = function(n) { return n < 10 ? '0' + n : '' + n; };
|
||||
return t.getFullYear() + '-' + pad(t.getMonth()+1) + '-' + pad(t.getDate()) +
|
||||
' ' + huDays[t.getDay()] + ' ' + pad(t.getHours()) + ':' + pad(t.getMinutes()) +
|
||||
' (' + s.short_id + ')';
|
||||
}
|
||||
|
||||
function onRestoreAppChange() {
|
||||
var sel = document.getElementById('restore-app');
|
||||
var opt = sel.options[sel.selectedIndex];
|
||||
var pathsDiv = document.getElementById('restore-paths');
|
||||
var pathsList = document.getElementById('restore-paths-list');
|
||||
|
||||
if (!opt.value) {
|
||||
pathsDiv.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
var paths = (opt.getAttribute('data-paths') || '').split(',').filter(Boolean);
|
||||
pathsList.innerHTML = '';
|
||||
paths.forEach(function(p) {
|
||||
var li = document.createElement('li');
|
||||
li.className = 'mono';
|
||||
li.textContent = p;
|
||||
pathsList.appendChild(li);
|
||||
});
|
||||
pathsDiv.style.display = 'block';
|
||||
|
||||
// Load snapshots
|
||||
fetch('/api/backup/snapshots')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
var snapSel = document.getElementById('restore-snapshot');
|
||||
snapSel.innerHTML = '<option value="">— Válasszon —</option>';
|
||||
if (data.ok && data.data) {
|
||||
data.data.forEach(function(s) {
|
||||
var o = document.createElement('option');
|
||||
o.value = s.short_id;
|
||||
var t = new Date(s.time);
|
||||
o.textContent = s.short_id + ' — ' + t.toLocaleString('hu-HU');
|
||||
snapSel.appendChild(o);
|
||||
});
|
||||
}
|
||||
});
|
||||
var appName = sel.value;
|
||||
var snapSel = document.getElementById('restore-snapshot');
|
||||
var noSnaps = document.getElementById('restore-no-snapshots');
|
||||
|
||||
document.getElementById('restore-confirm-cb').checked = false;
|
||||
document.getElementById('restore-btn').disabled = true;
|
||||
noSnaps.style.display = 'none';
|
||||
|
||||
if (!appName) {
|
||||
snapSel.innerHTML = '<option value="">— Válasszon alkalmazást —</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
snapSel.innerHTML = '<option value="">— Betöltés... —</option>';
|
||||
|
||||
fetch('/api/backup/snapshots?stack=' + encodeURIComponent(appName))
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
snapSel.innerHTML = '<option value="">— Válasszon —</option>';
|
||||
if (data.ok && data.data && data.data.length > 0) {
|
||||
data.data.forEach(function(s) {
|
||||
var o = document.createElement('option');
|
||||
o.value = s.short_id;
|
||||
o.textContent = formatSnapshot(s);
|
||||
snapSel.appendChild(o);
|
||||
});
|
||||
} else {
|
||||
snapSel.innerHTML = '<option value="">— Nincs elérhető mentés —</option>';
|
||||
noSnaps.style.display = 'block';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onRestoreConfirmChange() {
|
||||
@@ -674,11 +673,7 @@ function submitRestore() {
|
||||
startBackupPolling();
|
||||
{{end}}{{end}}
|
||||
|
||||
// Wire up snapshot selection change for restore confirm
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var snapSel = document.getElementById('restore-snapshot');
|
||||
if (snapSel) snapSel.addEventListener('change', onRestoreConfirmChange);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{{template "layout_end" .}}
|
||||
|
||||
Reference in New Issue
Block a user