Add a manual refresh button to the Array section on System
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
Unraid's stats were already fetched live on every page load (no server-side cache), so this doesn't bypass anything — it just lets the section be re-fetched without a full page reload, for confirming it's current without waiting on a reload. Array section moves into its own partial (_array_section.html) so a new /api/array/refresh route can re-render just that fragment and swap it into #array-section, rather than duplicating the table/bar/disk-row markup in JS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LPJxtE9tPURsaWDZ6rC4Dt
This commit is contained in:
parent
106bd16de8
commit
2dedd4e915
4 changed files with 137 additions and 87 deletions
100
templates/_array_section.html
Normal file
100
templates/_array_section.html
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
{% from "_macros.html" import service_error, bar, disk_state, disk_row %}
|
||||
|
||||
{#- ── Array ─────────────────────────────────────────────────────
|
||||
Its own partial (rather than inline in system.html) so the
|
||||
refresh button can re-fetch and swap in just this section via
|
||||
`/api/array/refresh` without a full page reload — Unraid's stats
|
||||
aren't cached (see get_unraid_stats), so a stale reading here
|
||||
only ever means "haven't reloaded the page since", and the button
|
||||
exists purely for the peace-of-mind of confirming that in place. -#}
|
||||
{% if unraid.status != 'ok' %}
|
||||
<div class="tt-field crit">
|
||||
<span>Array</span>
|
||||
<span class="tt-field-meta">unreachable
|
||||
<button class="tt-btn-quiet" type="button" id="array-refresh-btn" onclick="refreshArray(this)" aria-label="Refresh array stats">REFRESH</button>
|
||||
</span>
|
||||
</div>
|
||||
{{ service_error('Unraid', unraid.error) }}
|
||||
{% else %}
|
||||
{%- set apct = unraid.array_used_pct | default(0) | float -%}
|
||||
<div class="tt-field {% if apct >= 90 %}crit{% elif apct >= 75 %}warn{% endif %}">
|
||||
<span>Array</span>
|
||||
<span class="tt-field-meta">
|
||||
{{ unraid.array_state | default('') }}
|
||||
{%- if unraid.parities %} · parity
|
||||
{%- for p in unraid.parities %} {{ p.temp if p.temp is not none else '—' }}°C{% endfor %}
|
||||
{%- endif %}
|
||||
<button class="tt-btn-quiet" type="button" id="array-refresh-btn" onclick="refreshArray(this)" aria-label="Refresh array stats">REFRESH</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tt-figs">
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v {{ 'alert' if apct >= 90 else ('warn' if apct >= 75 else 'ok') }}">{{ apct | round | int }}%</div>
|
||||
<div class="tt-fig-l">Used</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.array_free | default('—') }}</div>
|
||||
<div class="tt-fig-l">Free</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.array_total | default('—') }}</div>
|
||||
<div class="tt-fig-l">Total</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.disk_count | default(0) }}</div>
|
||||
<div class="tt-fig-l">Disks</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if unraid.disks %}
|
||||
{#- Desktop: a real table — columns line up, a new metric is a new
|
||||
column. Hidden below 560px, where six columns stop fitting and
|
||||
a horizontal scroll would hide the bar and the temperature,
|
||||
the two readings that matter most on this page. -#}
|
||||
<div class="tt-table-scroll">
|
||||
<table class="tt-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Disk</th>
|
||||
<th scope="col">Device</th>
|
||||
<th scope="col" class="num">Size</th>
|
||||
<th scope="col" class="num">Free</th>
|
||||
<th scope="col">Usage</th>
|
||||
<th scope="col" class="num">Temp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for dk in unraid.disks %}
|
||||
<tr>
|
||||
<th scope="row">{{ dk.name }}</th>
|
||||
<td>{{ dk.device | default('—') }}</td>
|
||||
<td class="num">{{ dk.total | default('—') }}</td>
|
||||
<td class="num">{{ dk.free | default('—') }}</td>
|
||||
<td>{{ bar(dk.used_pct | default(0)) }} <span class="val">{{ dk.used_pct | default(0) | round | int }}%</span></td>
|
||||
<td class="num">{{ disk_state(dk) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for ck in unraid.caches | default([]) %}
|
||||
<tr>
|
||||
<th scope="row">{{ ck.name }}</th>
|
||||
<td>{{ ck.device | default('—') }}</td>
|
||||
<td class="num">{{ ck.total | default('—') }}</td>
|
||||
<td class="num">{{ ck.free | default('—') }}</td>
|
||||
<td>{{ bar(ck.used_pct | default(0)) }} <span class="val">{{ ck.used_pct | default(0) | round | int }}%</span></td>
|
||||
<td class="num">{{ disk_state(ck) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{#- Phone (≤560px): the .tt-row-derived reflow — name, the shared
|
||||
20-cell bar and the temperature on one line, device/size/free
|
||||
beneath. Hidden above 560px in favour of the table. -#}
|
||||
<div class="tt-disk-rows">
|
||||
{% for dk in unraid.disks %}{{ disk_row(dk) }}{% endfor %}
|
||||
{% for ck in unraid.caches | default([]) %}{{ disk_row(ck) }}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "_shell.html" %}
|
||||
{% from "_macros.html" import service_error, bar, disk_state, disk_row, trend %}
|
||||
{% from "_macros.html" import service_error, bar, trend %}
|
||||
{% block title %}P105 System{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
|
@ -23,92 +23,9 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{#- ── Array ───────────────────────────────────────────────────── -#}
|
||||
{% if unraid.status != 'ok' %}
|
||||
<div class="tt-field crit"><span>Array</span><span class="tt-field-meta">unreachable</span></div>
|
||||
{{ service_error('Unraid', unraid.error) }}
|
||||
{% else %}
|
||||
{%- set apct = unraid.array_used_pct | default(0) | float -%}
|
||||
<div class="tt-field {% if apct >= 90 %}crit{% elif apct >= 75 %}warn{% endif %}">
|
||||
<span>Array</span>
|
||||
<span class="tt-field-meta">
|
||||
{{ unraid.array_state | default('') }}
|
||||
{%- if unraid.parities %} · parity
|
||||
{%- for p in unraid.parities %} {{ p.temp if p.temp is not none else '—' }}°C{% endfor %}
|
||||
{%- endif %}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tt-figs">
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v {{ 'alert' if apct >= 90 else ('warn' if apct >= 75 else 'ok') }}">{{ apct | round | int }}%</div>
|
||||
<div class="tt-fig-l">Used</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.array_free | default('—') }}</div>
|
||||
<div class="tt-fig-l">Free</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.array_total | default('—') }}</div>
|
||||
<div class="tt-fig-l">Total</div>
|
||||
</div>
|
||||
<div class="tt-fig">
|
||||
<div class="tt-dh tt-fig-v">{{ unraid.disk_count | default(0) }}</div>
|
||||
<div class="tt-fig-l">Disks</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if unraid.disks %}
|
||||
{#- Desktop: a real table — columns line up, a new metric is a new
|
||||
column. Hidden below 560px, where six columns stop fitting and
|
||||
a horizontal scroll would hide the bar and the temperature,
|
||||
the two readings that matter most on this page. -#}
|
||||
<div class="tt-table-scroll">
|
||||
<table class="tt-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Disk</th>
|
||||
<th scope="col">Device</th>
|
||||
<th scope="col" class="num">Size</th>
|
||||
<th scope="col" class="num">Free</th>
|
||||
<th scope="col">Usage</th>
|
||||
<th scope="col" class="num">Temp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for dk in unraid.disks %}
|
||||
<tr>
|
||||
<th scope="row">{{ dk.name }}</th>
|
||||
<td>{{ dk.device | default('—') }}</td>
|
||||
<td class="num">{{ dk.total | default('—') }}</td>
|
||||
<td class="num">{{ dk.free | default('—') }}</td>
|
||||
<td>{{ bar(dk.used_pct | default(0)) }} <span class="val">{{ dk.used_pct | default(0) | round | int }}%</span></td>
|
||||
<td class="num">{{ disk_state(dk) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for ck in unraid.caches | default([]) %}
|
||||
<tr>
|
||||
<th scope="row">{{ ck.name }}</th>
|
||||
<td>{{ ck.device | default('—') }}</td>
|
||||
<td class="num">{{ ck.total | default('—') }}</td>
|
||||
<td class="num">{{ ck.free | default('—') }}</td>
|
||||
<td>{{ bar(ck.used_pct | default(0)) }} <span class="val">{{ ck.used_pct | default(0) | round | int }}%</span></td>
|
||||
<td class="num">{{ disk_state(ck) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{#- Phone (≤560px): the .tt-row-derived reflow — name, the shared
|
||||
20-cell bar and the temperature on one line, device/size/free
|
||||
beneath. Hidden above 560px in favour of the table. -#}
|
||||
<div class="tt-disk-rows">
|
||||
{% for dk in unraid.disks %}{{ disk_row(dk) }}{% endfor %}
|
||||
{% for ck in unraid.caches | default([]) %}{{ disk_row(ck) }}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div id="array-section">
|
||||
{% include "_array_section.html" %}
|
||||
</div>
|
||||
|
||||
{#- ── Downloads ─────────────────────────────────────────────────
|
||||
The one place the service holds real history, so the one place a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue