diff --git a/app.py b/app.py index a84700a..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 @@ -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 %}