The 5-second setTimeout fallbacks for plugins and overview were firing
before the htmx:ready event arrived, logging spurious warnings. Each
timer now self-cancels via htmx:ready so the fallback only triggers
when HTMX genuinely fails to load.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
The 500ms fallback setTimeout was calling attachInstallButtonHandler()
unconditionally even when the plugins partial wasn't in the DOM, causing
a spurious console.warn on every page load. Add the same element-existence
check already present on the htmx:afterSettle listener.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In the catch block of all 11 hx-on:htmx:after-request handlers, check
xhr.status >= 400 and downgrade s to 'error' so a failed action that
returns an HTML error page (or other non-JSON body) surfaces as an error
toast instead of the optimistic 'success'/'info' default.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace silent catch(e){} in all 11 hx-on:htmx:after-request handlers with a
pattern that sets default message/status before the try block and calls
showNotification(m,s) unconditionally after it, so a fallback toast is shown
whenever xhr is absent or responseText is not valid JSON.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- base.html: add htmx:afterSettle listener to set data-loaded on tab
containers after HTMX swaps their content, preventing the overview
partial from being re-fetched (and handlers lost) on every tab switch
- base.html: call htmx.process() in loadOverviewDirect/loadPluginsDirect
fallbacks so buttons get HTMX handlers even if HTMX finished its
initial body scan before the fallback fetch completed
- overview.html + index.html (11 buttons): replace event.detail.xhr.responseJSON
(undefined in HTMX 1.9.x) with JSON.parse(event.detail.xhr.responseText)
so quick action toast notifications actually fire
- plugins_manager.js: add guarded htmx:afterSettle listener that only calls
attachInstallButtonHandler when #install-plugin-from-url is in the DOM,
eliminating the spurious console warning on non-plugin tab loads
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>