feat: 0.11.7 — Stale data cleanup + FileBrowser sync after migration + deploy title fix
- Detect stale data on non-active storage paths after migration; show on deploy/settings page with size info and two-step delete confirmation - Add POST /api/storage/stale-cleanup handler with safety checks (active path protection, registered-path validation, ProtectedHDDPaths guard) - Export ProtectedHDDPaths() from stacks package for reuse in web handlers - Sync FileBrowser mounts after successful app data migration - Deploy page title/h2 now shows "Beállítások" for already-deployed apps instead of always showing "Telepítés" - Also add delete-old-data button on migration-done card in migrate.html Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<div class="page-header">
|
||||
<div style="display:flex;align-items:center;gap:.5rem">
|
||||
<a href="/stacks" class="btn btn-sm btn-outline">← Vissza</a>
|
||||
<h2>{{.Meta.DisplayName}} — Telepítés</h2>
|
||||
<h2>{{.Meta.DisplayName}} — {{if .AlreadyDeployed}}Beállítások{{else}}Telepítés{{end}}</h2>
|
||||
</div>
|
||||
<a href="/apps/{{.Meta.Slug}}" class="btn btn-sm btn-outline">ℹ️ Részletek</a>
|
||||
</div>
|
||||
@@ -58,6 +58,36 @@
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .StaleData}}
|
||||
<div class="deploy-stale-data">
|
||||
<h4>🗑️ Korábbi adatok</h4>
|
||||
<p class="form-hint" style="margin-bottom:1rem">
|
||||
Az alkalmazás adatainak másolata megtalálható egy másik tárolón is.
|
||||
Ez általában áthelyezés után marad hátra.
|
||||
</p>
|
||||
{{range .StaleData}}
|
||||
<div class="stale-data-item">
|
||||
<div class="settings-grid" style="margin-bottom:.75rem">
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Tárhely</span>
|
||||
<span class="settings-value">{{.Label}} <span class="mono" style="color:var(--text-secondary)">({{.Path}})</span></span>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Méret</span>
|
||||
<span class="settings-value mono">{{.SizeHuman}}</span>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Mappák</span>
|
||||
<span class="settings-value mono" style="font-size:.85rem">{{range .Mounts}}{{.}}<br>{{end}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-danger" onclick="deleteStaleData('{{$.Meta.Slug}}', '{{.Path}}', this)">
|
||||
🗑️ Korábbi adatok törlése
|
||||
</button>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if and (not .AlreadyDeployed) .MemoryInfo}}
|
||||
@@ -236,6 +266,52 @@ function generatePassword(fieldId) {
|
||||
document.getElementById(fieldId).value = pass;
|
||||
}
|
||||
|
||||
function deleteStaleData(stackName, stalePath, btn) {
|
||||
if (!confirm('Biztosan törölni szeretnéd a korábbi adatokat?\n\nTárhely: ' + stalePath + '\n\n⚠️ Ez a művelet visszavonhatatlan!\nElőtte győződj meg róla, hogy az alkalmazás az új tárolóról megfelelően működik.')) {
|
||||
return;
|
||||
}
|
||||
// Second confirmation
|
||||
if (!confirm('UTOLSÓ FIGYELMEZTETÉS!\n\nA törlés visszavonhatatlan. Biztosan folytatod?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Törlés folyamatban...';
|
||||
|
||||
fetch('/api/storage/stale-cleanup', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({stack_name: stackName, stale_path: stalePath})
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (!data.ok) {
|
||||
alert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🗑️ Korábbi adatok törlése';
|
||||
return;
|
||||
}
|
||||
var msg = '✅ Korábbi adatok törölve!\n\nFelszabadított hely: ' + (data.freed_human || '?');
|
||||
if (data.errors && data.errors.length > 0) {
|
||||
msg += '\n\n⚠️ Néhány hiba történt:\n' + data.errors.join('\n');
|
||||
}
|
||||
alert(msg);
|
||||
// Remove the stale data card from DOM
|
||||
var item = btn.closest('.stale-data-item');
|
||||
if (item) item.remove();
|
||||
// If no more stale items, remove the whole section
|
||||
var container = document.querySelector('.deploy-stale-data');
|
||||
if (container && container.querySelectorAll('.stale-data-item').length === 0) {
|
||||
container.remove();
|
||||
}
|
||||
})
|
||||
.catch(function(e) {
|
||||
alert('Hálózati hiba: ' + e.message);
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🗑️ Korábbi adatok törlése';
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('deploy-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
@@ -79,8 +79,19 @@
|
||||
Az alkalmazás az új tárolóról fut.<br>
|
||||
A régi adatok a korábbi helyen megmaradtak biztonsági másolatként.
|
||||
</p>
|
||||
<div style="margin-top:1.5rem;display:flex;gap:.75rem">
|
||||
<a href="/stacks" class="btn btn-primary">Alkalmazások megtekintése</a>
|
||||
<div class="alert alert-warning" style="margin-top:1rem">
|
||||
<strong>Javasolt lépések:</strong>
|
||||
<ol style="margin:.5rem 0 0 1rem;padding:0">
|
||||
<li>Ellenőrizd, hogy az alkalmazás megfelelően működik</li>
|
||||
<li>Győződj meg róla, hogy minden adat megtalálható</li>
|
||||
<li>Ha minden rendben, törölheted a korábbi adatokat</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div style="margin-top:1.5rem;display:flex;gap:.75rem;flex-wrap:wrap">
|
||||
<a href="/stacks/{{.Meta.Slug}}/deploy" class="btn btn-primary">Alkalmazások megtekintése</a>
|
||||
<button id="migrate-delete-old-btn" class="btn btn-outline btn-danger" onclick="deleteOldMigrationData()" style="display:none">
|
||||
🗑️ Korábbi adatok törlése
|
||||
</button>
|
||||
<a href="/settings" class="btn btn-outline">Beállítások</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,6 +194,46 @@ function showMigDone() {
|
||||
document.getElementById('migrate-progress-card').style.display = 'none';
|
||||
document.getElementById('migrate-done-card').style.display = 'block';
|
||||
document.getElementById('migrate-done-card').scrollIntoView({behavior:'smooth'});
|
||||
// Show the delete button (old data is at the source path)
|
||||
document.getElementById('migrate-delete-old-btn').style.display = '';
|
||||
}
|
||||
|
||||
function deleteOldMigrationData() {
|
||||
var oldPath = '{{.CurrentHDDPath}}';
|
||||
if (!confirm('Biztosan törölni szeretnéd a korábbi adatokat?\n\nTárhely: ' + oldPath + '\n\n⚠️ Ez a művelet visszavonhatatlan!\nElőtte győződj meg róla, hogy az alkalmazás az új tárolóról megfelelően működik.')) {
|
||||
return;
|
||||
}
|
||||
if (!confirm('UTOLSÓ FIGYELMEZTETÉS!\n\nA törlés visszavonhatatlan. Biztosan folytatod?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var btn = document.getElementById('migrate-delete-old-btn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Törlés folyamatban...';
|
||||
|
||||
fetch('/api/storage/stale-cleanup', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({stack_name: stackName, stale_path: oldPath})
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (!data.ok) {
|
||||
alert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🗑️ Korábbi adatok törlése';
|
||||
return;
|
||||
}
|
||||
btn.textContent = '✅ Korábbi adatok törölve (' + (data.freed_human || '') + ')';
|
||||
btn.classList.remove('btn-danger');
|
||||
btn.classList.add('btn-outline');
|
||||
btn.onclick = null;
|
||||
})
|
||||
.catch(function(e) {
|
||||
alert('Hálózati hiba: ' + e.message);
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🗑️ Korábbi adatok törlése';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2231,3 +2231,37 @@ a.stat-card:hover {
|
||||
.storage-app-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
/* Stale data cleanup */
|
||||
.deploy-stale-data {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--orange);
|
||||
border-radius: var(--radius);
|
||||
padding: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.deploy-stale-data h4 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.stale-data-item {
|
||||
padding: 1rem;
|
||||
background: rgba(255, 165, 0, 0.05);
|
||||
border-radius: var(--radius);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.stale-data-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: var(--red);
|
||||
color: white;
|
||||
border-color: var(--red);
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user