diff --git a/containers/libreportal/frontend/components/admin/overview/js/overview-page.js b/containers/libreportal/frontend/components/admin/overview/js/overview-page.js index c59901b..ab583a2 100644 --- a/containers/libreportal/frontend/components/admin/overview/js/overview-page.js +++ b/containers/libreportal/frontend/components/admin/overview/js/overview-page.js @@ -14,7 +14,10 @@ class OverviewPage { async init() { const r = this.root(); - if (r) r.innerHTML = '
' + lpLoadingBox() + '
'; + // Paint the header immediately and confine the spinner to the content + // panel below it, rather than blanking the whole pane to a headerless + // loader while the board's data loads. + if (r) r.innerHTML = `
${this._headerHtml()}
${lpLoadingBox()}
`; this.bindEvents(); const [upd, verify, backup, ssh, disk, mem, info] = await Promise.all([ this.fetchJson('/data/system/update_status.json'), @@ -156,6 +159,22 @@ class OverviewPage { return ``; } + // The page header (breadcrumb + title + description) — rendered up front on + // the loading state AND by render(), so navigating here paints the header + // immediately and the spinner is confined to the content panel below it, + // instead of the whole pane blanking to a headerless loader. + _headerHtml() { + return ` + `; + } + render() { const root = this.root(); if (!root) return; @@ -235,14 +254,7 @@ class OverviewPage { root.innerHTML = `
- + ${this._headerHtml()}
${updCard} diff --git a/containers/libreportal/frontend/components/admin/system/js/system-page.js b/containers/libreportal/frontend/components/admin/system/js/system-page.js index 93acb91..95b93ea 100644 --- a/containers/libreportal/frontend/components/admin/system/js/system-page.js +++ b/containers/libreportal/frontend/components/admin/system/js/system-page.js @@ -83,8 +83,10 @@ class SystemPage { return; } - // Default: index view. - r.innerHTML = '
' + lpLoadingBox('Loading system stats…') + '
'; + // Default: index view. Paint the header immediately and keep the spinner + // inside the content panel, so the page reads as "System, loading its + // stats" rather than a blank headerless loader. + r.innerHTML = `
${this._headerHtml('—')}
${lpLoadingBox('Loading system stats…')}
`; await this.refresh(); this.bind(); if (window.LiveSystem) { @@ -257,6 +259,22 @@ class SystemPage { if (subEl) subEl.textContent = `Live host and per-app statistics. Updated ${new Date(s.t || Date.now()).toLocaleTimeString()}.`; } + // The page header (breadcrumb + title + description) — rendered up front on + // the loading state AND by render(), so navigating here paints the header + // immediately and the spinner is confined to the content panel below it, + // instead of the whole pane blanking to a headerless loader. + _headerHtml(updated = '—') { + return ` + `; + } + render() { const root = this.root(); if (!root) return; @@ -328,14 +346,7 @@ class SystemPage { root.innerHTML = `
- + ${this._headerHtml(updated)}
${gauges} ${charts}