From 395638aaf29176648dce895abe9408ddfe46e7bf Mon Sep 17 00:00:00 2001 From: Barely Removable Date: Thu, 27 Aug 2026 13:19:17 -0700 Subject: [PATCH 1/2] Surface parity temp in the Storage header, enlarge the settings cog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parity went back into the GraphQL query, but for its temperature only — it still gets no table row, since it has no filesystem to measure. The temp rides in the card header next to the array summary, which was the one genuinely useful thing the old parity row carried: a parity drive cooking away is worth seeing. Multiple parity drives each get a badge, and .meta-parity keeps the label and badge from wrapping apart. The settings cog was a speck. The button was always a full 44px --tap target, but the glyph inside it was set at --fs-sm (13px), so the affordance read as far smaller than the hit area actually was. Now --fs-xl (24px) with line-height 1 — roughly 55% of the button, which is the usual proportion for an icon button. .icon-btn has exactly one user (the cog), so nothing else shifts. Verified at 1400px and 375px: no page overflow, the cog still measures 44x44, and the parity badge stays visible and intact on both. Co-Authored-By: Claude Opus 5 --- app.py | 18 +++++++++++++++--- static/css/dashboard.css | 14 +++++++++++++- templates/dashboard.html | 5 +++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app.py b/app.py index a84700a..76c0195 100644 --- a/app.py +++ b/app.py @@ -888,15 +888,17 @@ def get_unraid_stats(): # HTTPS on 443 with SSL verification disabled (Unraid uses a self-signed cert) url = f"https://{UNRAID_HOST}:443/graphql" headers = {"x-api-key": UNRAID_API_KEY, "Content-Type": "application/json"} - # Parity is deliberately not requested: it mirrors the array rather - # than holding a filesystem, so it has no size or usage to report and - # only ever rendered as a name and a temperature. + # Parity is fetched for its temperature only — it mirrors the array + # rather than holding a filesystem, so the schema notes fsSize/fsFree + # are "Not present on Parity type drive". It gets no table row; the + # card header carries the temp so a hot parity is still visible. query = """{ vars { version } array { state disks { name device fsSize fsFree type temp isSpinning } caches { name device fsSize fsFree type temp isSpinning } + parities { name device temp isSpinning } } }""" try: @@ -940,6 +942,16 @@ def get_unraid_stats(): "array_used_pct": used_pct, "disks": [disk_row(dk) for dk in data_disks], "caches": [disk_row(dk) for dk in arr.get("caches", [])], + # Temperature only — no size fields exist on parity. + "parities": [ + { + "name": dk.get("name") or dk.get("device") or "parity", + "device": dk.get("device", ""), + "temp": dk.get("temp"), + "spinning": dk.get("isSpinning"), + } + for dk in arr.get("parities", []) + ], } except Exception: pass diff --git a/static/css/dashboard.css b/static/css/dashboard.css index 4478a90..f4ce7ed 100644 --- a/static/css/dashboard.css +++ b/static/css/dashboard.css @@ -135,7 +135,11 @@ header { border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-2); - font-size: var(--fs-sm); + /* The button was always a full --tap target, but the cog glyph inside it + was set at --fs-sm (13px) and read as a speck in a 44px box. The glyph + is the affordance, so size it to the button. */ + font-size: var(--fs-xl); + line-height: 1; font-family: inherit; text-decoration: none; white-space: nowrap; @@ -632,6 +636,14 @@ dd.is-accent { color: var(--accent); } } /* Still used by the disk_state() macro when a disk reports no temperature. */ .disk-null { color: var(--text-3); } +/* Parity temp in the Storage header — keep the label and its badge together + so they never wrap apart from each other. */ +.meta-parity { + display: inline-flex; + align-items: center; + gap: 0.35rem; + white-space: nowrap; +} @media (max-width: 720px) { /* Below this the six columns stop fitting; the table scrolls in its own container rather than squeezing the sizes into unreadable wraps. */ diff --git a/templates/dashboard.html b/templates/dashboard.html index e62702c..4e2caf8 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -181,6 +181,11 @@ {{ unraid.array_used_pct }}% used · {{ unraid.array_free }} free of {{ unraid.array_total }} {%- if unraid.disk_count %} · {{ unraid.disk_count }} disk{{ 's' if unraid.disk_count != 1 }}{% endif %} {%- if unraid.array_state %} · {{ unraid.array_state | capitalize }}{% endif %} + {#- Parity has no table row of its own (no filesystem to measure), + so its temperature rides here — the one thing worth watching. -#} + {%- if unraid.parities %} · Parity + {%- for dk in unraid.parities %} {{ disk_state(dk) }}{% endfor %} + {%- endif %} {% endif %} From 9a277b9031397d109edeb1867a3051303361aaa4 Mon Sep 17 00:00:00 2001 From: Barely Removable Date: Thu, 27 Aug 2026 13:19:17 -0700 Subject: [PATCH 2/2] Bump to v1.6.3 for deploy Co-Authored-By: Claude Opus 5 --- app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.py b/app.py index 76c0195..7b1954a 100644 --- a/app.py +++ b/app.py @@ -22,7 +22,7 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Docker tab caches stale container IDs, so the footer is the reliable way # to confirm a `docker compose up -d --build` actually took effect. # Both are env-overridable if the deploy pipeline ever injects them. -APP_VERSION = os.environ.get("APP_VERSION", "1.6.2") +APP_VERSION = os.environ.get("APP_VERSION", "1.6.3") APP_VERSION_DATE = os.environ.get("APP_VERSION_DATE", "2026-08-27") # Must point at a path that survives `docker compose up --build` — the