From 17c059e215a713200ca8ff29630b325801581e21 Mon Sep 17 00:00:00 2001 From: marvin Date: Fri, 18 Sep 2026 16:00:42 -0400 Subject: [PATCH] Fix nested dashboard-panel double-border and show actual access address instead of internal admin port (v0.16.2) --- README.md | 2 +- ROADMAP.md | 2 ++ package.json | 2 +- src/public/features.js | 6 +++--- src/public/index.html | 4 ++-- src/public/styles.css | 4 ++++ 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8a628c1..789f97a 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 fabecba..50026ee 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -51,6 +51,8 @@ `v0.16.1` is a fix for a gap in `v0.16.0`'s own System tab: the Environment & Integrations section never actually rendered a `BACKUP_PASSWORD` status row (only the Docker socket status was there), despite the backend already exposing that data via `/api/config`. Fixed. +`v0.16.2` fixes two more issues found live-testing the System tab: the Docker container-selection sub-section was wrapped in its own `.dashboard-panel` styling while already nested inside the Integrations panel's own `.dashboard-panel`, producing a visibly doubled border/corner-radius/padding โ€” de-chromed it into a plain sub-section instead. Also, the Version section's "Admin port" line showed the container's *internal* listening port, which isn't necessarily the port you actually reach the dashboard on through Docker's port mapping โ€” replaced with the browser's own current address (`location.origin`), which is always correct regardless of how the port is mapped. + ## Product direction Site Gateway stays simpler than a general-purpose proxy manager: one dashboard, clear health reporting, and guided setup instead of exposing raw server configuration. **Caddy** remains the managed gateway โ€” Site Gateway stores a small route model and generates/validates Caddy configuration rather than reimplementing certificate and proxy behavior itself. diff --git a/package.json b/package.json index 79482f0..7d23424 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "site-gateway", - "version": "0.16.1", + "version": "0.16.2", "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 71e9e48..89703ed 100644 --- a/src/public/features.js +++ b/src/public/features.js @@ -452,8 +452,8 @@ function renderDockerPanel() { let section = panel.querySelector(".docker-integration-section"); if (!section) { section = document.createElement("div"); - section.className = "dashboard-panel docker-integration-section"; - section.innerHTML = '

Integrations

Docker container selection

'; + section.className = "docker-integration-section"; + section.innerHTML = '

Docker container selection

'; panel.append(section); section.querySelector("#docker-integration-toggle").addEventListener("change", async event => { const checkbox = event.currentTarget; @@ -580,7 +580,7 @@ async function renderSystemStatus(panel) { envStatus.innerHTML = `
BACKUP_PASSWORD${encryptionAvailable ? "Configured \u2014 scheduled backups can be encrypted." : "Not set \u2014 configure it in the container\u2019s environment to enable encrypted scheduled backups."}
`; } if (syncStatus) { const drift = (state.dashboard?.attention || []).some(item => item.kind === "drift"); syncStatus.textContent = drift ? "Configuration drift detected \u2014 the running gateway no longer matches the last known-good configuration." : `Gateway configuration is in sync. Last reload: ${state.dashboard?.gateway?.lastReload ? formatTime(state.dashboard.gateway.lastReload) : "unknown"}.`; syncStatus.className = drift ? "muted status-warning" : "muted"; } - if (version) version.innerHTML = `Site Gateway v${extendedEscape(state.config?.version || "unknown")}
Data directory: ${extendedEscape(state.config?.storage?.databasePath ? state.config.storage.databasePath.replace(/\/database\/.*/, "") : "/data")} · Admin port: ${extendedEscape(String(state.config?.adminPort ?? ""))} · Site ports: ${extendedEscape(String(state.config?.minPort ?? ""))}\u2013${extendedEscape(String(state.config?.maxPort ?? ""))}`; + if (version) version.innerHTML = `Site Gateway v${extendedEscape(state.config?.version || "unknown")}
Access this dashboard at: ${extendedEscape(location.origin)}
Data directory: ${extendedEscape(state.config?.storage?.databasePath ? state.config.storage.databasePath.replace(/\/database\/.*/, "") : "/data")} · Site ports: ${extendedEscape(String(state.config?.minPort ?? ""))}\u2013${extendedEscape(String(state.config?.maxPort ?? ""))}`; try { const [sec, store, policy] = await Promise.all([ api("/api/system/security"), diff --git a/src/public/index.html b/src/public/index.html index 70433c1..dbe8b28 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -8,7 +8,7 @@ Site Gateway - + - + diff --git a/src/public/styles.css b/src/public/styles.css index 03a815c..bd3bea0 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -772,6 +772,10 @@ label.check-control:has(input[name="upstreamTlsInsecure"]){position:relative;hei label.check-control:has(input[name="upstreamTlsInsecure"]) span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis} label.check-control:has(input[name="upstreamTlsInsecure"]) small{position:absolute;left:0;top:calc(100% + 7px);width:100%;padding:0!important;white-space:normal} +.docker-integration-section{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)} +.docker-integration-heading{font-weight:600;margin:0 0 var(--space-2)} +.docker-integration-section .check-control{margin-top:var(--space-3)} + /* Custom-drawn select (Task #20): native