From 2577493225e6233b6344b2a815500f069a7497bb Mon Sep 17 00:00:00 2001 From: marvin Date: Fri, 18 Sep 2026 17:58:54 -0400 Subject: [PATCH] Give System/API Access tabs static shells to fix reload blink, restyle Scheduled Jobs with last-run data (v0.16.7) --- README.md | 2 +- ROADMAP.md | 2 ++ package.json | 2 +- src/public/features.js | 8 ++++++-- src/public/index.html | 8 ++++---- src/server.js | 9 ++++++++- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ebb62e1..b047a44 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Docker Architectures Caddy - Version + Version

Why Site Gateway · diff --git a/ROADMAP.md b/ROADMAP.md index 274ef32..2014e23 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -140,3 +140,5 @@ Roughly in priority order: `v0.16.5` gives the Docker container-selection status its own `.health-tile` card (matching `BACKUP_PASSWORD` directly above it) instead of a plain paragraph — the two Environment/Integrations rows now look consistent whether Docker's socket is mounted or not. Also adds breathing room between the Reload & Restart buttons and the status line beneath them, which was sitting flush against the button row. `v0.16.6` fixes the real cause of the System tab's Scheduled jobs section always showing "No scheduled jobs reported.": the dashboard API nests job data under `dashboard.system.jobs`, but the System tab was reading `dashboard.jobs` — one level too shallow, so it was always undefined regardless of what the server returned. Also fixes the Docker socket status tile rendering wider than the `BACKUP_PASSWORD` tile above it — it wasn't wrapped in the same `.health-grid` container, so it spanned the full panel width instead of matching the two-column tile layout used everywhere else on the System tab. + +`v0.16.7` fixes the real cause of the System tab visibly blinking in and out on every page reload: unlike every other Administration tab (Users, Groups, Gateway defaults, Audit log, Backup & restore, Logs & Retention, Danger Zone — all static HTML present from the first paint), System and API Access were built entirely by JavaScript after the initial data fetch completed, so there was a real window on every reload where every other tab was already visible and these two genuinely were not there yet. Confirmed via a screenshot taken mid-reload showing exactly that. Fix: gave System and API Access the same static tab-button-and-panel shell every other tab already has, so they're present immediately; their content still fills in a moment later via JavaScript, same as every other tab already does. Also reworked the Scheduled Jobs section to match the Storage section's card styling (health-tile grid instead of a plain list) and added last-run timestamps where the server tracks them (scheduled backups, log pruning, public IP checks, configuration drift checks). diff --git a/package.json b/package.json index 757540e..5492f29 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "site-gateway", - "version": "0.16.6", + "version": "0.16.7", "private": true, "description": "Site Gateway: simple self-hosted website publishing, reverse proxying, and automatic HTTPS.", "type": "module", diff --git a/src/public/features.js b/src/public/features.js index ca8b3f7..61fc3b1 100644 --- a/src/public/features.js +++ b/src/public/features.js @@ -541,7 +541,7 @@ function renderSystemPanel() { '

Environment

Integrations

', '

Environment

Security status

', '

Gateway

Sync

', - '

Operations

Scheduled jobs

', + '

Operations

Scheduled jobs

', '

Storage

Disk usage

', '

Build

Version

', '

Gateway

Reload & restart

Reloading re-applies the current configuration to Caddy with no downtime. Restarting stops and restarts the whole application \u2014 only available when a restart policy is set on the container.

', @@ -574,7 +574,11 @@ async function renderSystemStatus(panel) { version = document.querySelector("#system-version"), jobs = document.querySelector("#system-jobs"), syncStatus = document.querySelector("#system-sync-status"), restartButton = document.querySelector("#system-restart"), restartStatus = document.querySelector("#system-restart-status"); - if (jobs) jobs.innerHTML = (state.dashboard?.system?.jobs || []).map(job => `
${extendedEscape(job.name)}${job.enabled ? `Active \u00b7 ${extendedEscape(job.schedule)}` : "Disabled"}
`).join("") || '

No scheduled jobs reported.

'; + if (jobs) jobs.innerHTML = (state.dashboard?.system?.jobs || []).map(job => { + const status = job.enabled ? `Active \u00b7 ${extendedEscape(job.schedule)}` : "Disabled"; + const lastRun = job.lastRunAt ? `Last run ${extendedEscape(formatTime(job.lastRunAt))}${job.lastStatus && job.lastStatus !== "ok" ? ` \u00b7 ${extendedEscape(job.lastStatus)}` : ""}` : "No run recorded yet"; + return `
${extendedEscape(job.name)}${status} \u00b7 ${lastRun}
`; + }).join("") || '

No scheduled jobs reported.

'; const envStatus = document.querySelector("#system-env-status"); if (envStatus) { const encryptionAvailable = Boolean(state.config?.backup?.encryptionAvailable); diff --git a/src/public/index.html b/src/public/index.html index 664ee10..d8056fc 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -8,7 +8,7 @@ Site Gateway - +