feat(ui): Disk, Traefik, UniFi and Settings say things plainly (#5212)
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 53s
CI / unit (push) Successful in 1m14s
CI / publish (push) Successful in 1m10s

#5212 "Plain labels: no raw ids, scopes, metric keys or unexplained jargon",
batch 3:

- Disk page: each tile says what it holds. "Writable layers" becomes
  "Container files" and Build cache says it is safe to clear. Shared is
  "Shared with other images" with a tooltip, and "dangling" is gone.
  Untagged images show by id instead of "<none>", a capped list says
  "The 50 largest of N images", and each host shows "as of" its report.
- Traefik: an expired certificate reads "expired 12 days ago", not "-12
  days" (cert_left). The Traffic empty state knows whether the access log
  is on: off points to Settings → Plugins → Traefik; on says to check the
  mounted log path.
- Moments use |ago with an exact UTC tooltip: UniFi last seen, alarms,
  events, speed test and DPI; AI token last used.
- Settings: the Auth tab is "Authentication" like its breadcrumb, plugin
  fields read "Metrics URL" not metrics_url (field_label), a source's pull
  interval is "every 1h", and the last report time drops the ISO "T".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 00:29:30 -04:00
co-authored by Claude Opus 5.5
parent e780932673
commit 5ec930bf76
21 changed files with 164 additions and 38 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<div class="card" style="break-inside:avoid;margin-bottom:1rem;">
<div class="section-title" style="margin-bottom:0.75rem;">
Traffic by Category
<span style="float:right;font-weight:normal;font-size:0.78rem;color:var(--text-dim);">{{ snapshot.scraped_at.strftime("%H:%M") }}</span>
<span style="float:right;font-weight:normal;font-size:0.78rem;color:var(--text-dim);">as of {{ snapshot.scraped_at|ago }}</span>
</div>
{% set total_bytes = categories | sum(attribute='rx_bytes') + categories | sum(attribute='tx_bytes') %}
<table class="table" style="width:100%;font-size:0.82rem;">
+1 -1
View File
@@ -25,7 +25,7 @@
{% for ev in events %}
<tr style="{% if loop.index is divisibleby 2 %}background:var(--fs-table-stripe);{% endif %}">
<td style="padding:0.25rem 0.5rem 0.25rem 0;color:var(--text-dim);font-size:0.77rem;white-space:nowrap;">
{{ ev.event_time.strftime("%Y-%m-%d %H:%M:%S") }}
{{ ev.event_time|ago }}
</td>
<td style="padding:0.25rem 0.5rem;">
<span class="badge badge-{{ {'wlan': 'info', 'wan': 'ok', 'ids': 'crit'}.get(ev.category, 'dim') }}">{{ ev.category }}</span>
+1 -1
View File
@@ -117,7 +117,7 @@
{{ kc.ip or "—" }}
</td>
<td style="padding:0.2rem 0;text-align:right;color:var(--text-dim);font-size:0.75rem;white-space:nowrap;">
{% if kc.last_seen %}{{ kc.last_seen.strftime("%m-%d %H:%M") }}{% else %}—{% endif %}
{% if kc.last_seen %}{{ kc.last_seen|ago }}{% else %}—{% endif %}
</td>
</tr>
{% endfor %}
+1 -1
View File
@@ -146,7 +146,7 @@
{% if speedtest.server_name %}
<div style="margin-top:0.4rem;color:var(--text-dim);font-size:0.78rem;">via {{ speedtest.server_name }}</div>
{% endif %}
<div style="margin-top:0.25rem;color:var(--text-dim);font-size:0.75rem;">{{ speedtest.run_at.strftime("%Y-%m-%d %H:%M") }} UTC</div>
<div style="margin-top:0.25rem;color:var(--text-dim);font-size:0.75rem;">{{ speedtest.run_at|ago }}</div>
</div>
{% endif %}
+2 -2
View File
@@ -21,7 +21,7 @@
</div>
<div>{{ al.message }}</div>
<div style="color:var(--text-dim);font-size:0.75rem;margin-top:0.1rem;">
{{ al.alarm_time.strftime("%Y-%m-%d %H:%M") }} UTC
{{ al.alarm_time|ago }}
</div>
</td>
</tr>
@@ -45,7 +45,7 @@
<div style="color:var(--text-dim);font-size:0.8rem;">{{ al.message }}</div>
</td>
<td style="padding:0.25rem 0;text-align:right;color:var(--text-dim);font-size:0.75rem;white-space:nowrap;">
{{ al.alarm_time.strftime("%m-%d %H:%M") }}
{{ al.alarm_time|ago }}
</td>
</tr>
{% endfor %}