Fix backup API 404s, hardware status 500, and HTMX loading race

- Add all backup API routes to api_v3.py: preview, list, export,
  validate, restore (with plugin reinstall), download, delete
- Fix PermissionError on /hardware/status: return graceful 200 instead
  of 500 when the status file is owned by a different user; also fix
  root cause by writing the file world-readable (0o644) in display_manager
- Fix HTMX race: dispatch htmx:ready window event from HTMX onload
  callback; loadTabContent now waits for that event instead of
  immediately falling back to direct fetch (eliminating the
  "HTMX not available" console warning on initial load)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-05-23 16:16:31 -04:00
parent ddc53ff1e0
commit 745ba8101e
3 changed files with 188 additions and 12 deletions

View File

@@ -152,6 +152,7 @@
}
} else {
console.log('HTMX loaded successfully');
window.dispatchEvent(new Event('htmx:ready'));
// Load extensions after core loads
loadScript(sseSrc, isAPMode ? 'https://unpkg.com/htmx.org/dist/ext/sse.js' : '/static/v3/js/htmx-sse.js');
loadScript(jsonEncSrc, isAPMode ? 'https://unpkg.com/htmx.org/dist/ext/json-enc.js' : '/static/v3/js/htmx-json-enc.js');
@@ -1836,13 +1837,11 @@
htmx.trigger(contentEl, 'revealed');
}
} else {
// HTMX not available, use direct fetch
console.warn('HTMX not available, using direct fetch for tab:', tab);
if (tab === 'overview' && typeof loadOverviewDirect === 'function') {
loadOverviewDirect();
} else if (tab === 'wifi' && typeof loadWifiDirect === 'function') {
loadWifiDirect();
}
// HTMX is still loading asynchronously — retry once it signals ready
const self = this;
window.addEventListener('htmx:ready', function retry() {
self.loadTabContent(tab);
}, { once: true });
}
},