Fix backup status dots disappearing after page load
/api/backups returned plain filename strings while pages/backups.html's server-rendered dots came from get_local_backups_with_status()/ get_vm_backups_with_status(). platform.js's DOMContentLoaded handler always calls refreshBackupsList() (backups.html has #backup-history-list, which triggers it unconditionally), which re-fetches /api/backups and rebuilds #local-backup-list/#vm-backup-list via renderBackupList() — a version with zero knowledge of status, wiping out the dots seconds after initial paint. Switch /api/backups to the *_with_status() variants and have renderBackupList() render the same status-dot markup as the Jinja template, so the dot is sourced from persisted backup metadata on every render path, not just the first one.
This commit is contained in:
@@ -377,8 +377,8 @@ async function refreshBackupsList() {
|
||||
renderBackupList(d.vm, 'vm-backup-list', 'vm');
|
||||
if (el('stat-local-bk')) el('stat-local-bk').textContent = d.local.length;
|
||||
if (el('stat-vm-bk')) el('stat-vm-bk').textContent = d.vm.length;
|
||||
if (el('local-options')) el('local-options').innerHTML = d.local.length ? d.local.map((b) => `<option value="${b}" data-source="local">${b}</option>`).join('') : '<option disabled>No local backups</option>';
|
||||
if (el('vm-options')) el('vm-options').innerHTML = d.vm.length ? d.vm.map((b) => `<option value="${b}" data-source="vm">${b}</option>`).join('') : '<option disabled>No VM backups</option>';
|
||||
if (el('local-options')) el('local-options').innerHTML = d.local.length ? d.local.map((b) => `<option value="${b.name}" data-source="local">${b.name}</option>`).join('') : '<option disabled>No local backups</option>';
|
||||
if (el('vm-options')) el('vm-options').innerHTML = d.vm.length ? d.vm.map((b) => `<option value="${b.name}" data-source="vm">${b.name}</option>`).join('') : '<option disabled>No VM backups</option>';
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@@ -394,7 +394,13 @@ function renderBackupList(items, id, source) {
|
||||
return;
|
||||
}
|
||||
node.innerHTML = items.map((b) => {
|
||||
const safe = jsStr(b);
|
||||
const name = b.name;
|
||||
const safe = jsStr(name);
|
||||
const status = b.status || 'unknown';
|
||||
const titleParts = [status];
|
||||
if (b.apps && b.apps.length) titleParts.push(`apps: ${b.apps.join(', ')}`);
|
||||
if (b.size_human) titleParts.push(b.size_human);
|
||||
const title = escapeHtml(titleParts.join(' · '));
|
||||
const uploadBtn = source === 'local' && typeof quickUploadR2 === 'function'
|
||||
? `<button class="btn btn-ghost btn-sm" onclick="quickUploadR2('${safe}',this)" title="Upload to R2"><i class="fas fa-cloud-upload-alt"></i></button>`
|
||||
: '';
|
||||
@@ -402,9 +408,10 @@ function renderBackupList(items, id, source) {
|
||||
? `<button class="btn btn-ghost btn-sm" style="color:var(--text3);" onclick="showBackupDetails('${source}','${safe}',this)" title="Quick details"><i class="fas fa-circle-info"></i></button>`
|
||||
: '';
|
||||
return `
|
||||
<div class="backup-item" id="bk-item-${source}-${b.replace(/[^a-z0-9]/gi, '_')}">
|
||||
<div class="backup-item" id="bk-item-${source}-${name.replace(/[^a-z0-9]/gi, '_')}">
|
||||
<div class="backup-item-main">
|
||||
<span class="backup-name">${escapeHtml(b)}</span>
|
||||
<span class="status-dot status-dot-${status}" title="${title}"></span>
|
||||
<span class="backup-name">${escapeHtml(name)}</span>
|
||||
</div>
|
||||
<div class="backup-actions">
|
||||
${detailsBtn}
|
||||
|
||||
Reference in New Issue
Block a user