arr-summary/templates/system.html
Barely Removable 2dedd4e915
Some checks failed
Deploy / deploy (push) Has been cancelled
Add a manual refresh button to the Array section on System
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
2026-09-05 10:01:51 -07:00

120 lines
6.2 KiB
HTML

{% extends "_shell.html" %}
{% from "_macros.html" import service_error, bar, trend %}
{% block title %}P105 System{% endblock %}
{% block content %}
<h1 class="tt-dh bloom tt-masthead">SYSTEM</h1>
{#- ── Service transmission status ───────────────────────────────
Six services, one row each, colour carrying up or down. This is
what the old header pills were, given room to say something. Each
row opens that service's own instance, via the reverse proxy. -#}
<div class="tt-field"><span>Transmission</span></div>
<div class="tt-rows">
{% for name, key, svc in [('Sonarr', 'sonarr', sonarr), ('Radarr', 'radarr', radarr), ('SABnzbd', 'sabnzbd', sabnzbd),
('Tautulli', 'tautulli', tautulli), ('Prowlarr', 'prowlarr', prowlarr), ('Ombi', 'ombi', ombi)] %}
<a class="tt-row" href="{{ service_urls[key] }}" target="_blank" rel="noopener">
<span class="tt-row-name">{{ name }} <span class="tt-row-ext" aria-hidden="true">&#8599;</span></span>
<span class="tt-row-body"></span>
<span class="tt-row-val {{ 'ok' if svc.status == 'ok' else 'alert' }}">
{{- 'ON AIR' if svc.status == 'ok' else 'OFF AIR' -}}
</span>
</a>
{% endfor %}
</div>
<div id="array-section">
{% include "_array_section.html" %}
</div>
{#- ── Downloads ─────────────────────────────────────────────────
The one place the service holds real history, so the one place a
trend arrow is honest: current speed against the 7-day average. -#}
{% if sabnzbd.status == 'ok' %}
<div class="tt-field"><span>Downloads</span><span class="tt-field-meta">{{ sabnzbd.sab_status | default('') }}</span></div>
<div class="tt-figs">
<div class="tt-fig">
<div class="tt-dh tt-fig-v"><span id="sab-queue">{{ sabnzbd.queue_count }}</span></div>
<div class="tt-fig-l">In queue</div>
</div>
<div class="tt-fig">
<div class="tt-dh tt-fig-v"><span id="sab-speed">{{ sabnzbd.speed | default('0') }}</span> {{ trend(sabnzbd.speed_kbps, sabnzbd.avg_speed_kbps) }}</div>
<div class="tt-fig-l">Speed vs 7-day avg</div>
</div>
<div class="tt-fig">
<div class="tt-dh tt-fig-v"><span id="sab-remaining">{{ sabnzbd.sizeleft | default('—') }}</span></div>
<div class="tt-fig-l">Remaining</div>
</div>
<div class="tt-fig">
<div class="tt-dh tt-fig-v">{{ sabnzbd.week_size | default('—') }}</div>
<div class="tt-fig-l">This week</div>
</div>
</div>
{% else %}
<div class="tt-field crit"><span>Downloads</span><span class="tt-field-meta">off air</span></div>
{{ service_error('SABnzbd', sabnzbd.error) }}
{% endif %}
{#- ── Indexers ────────────────────────────────────────────────── -#}
{% if prowlarr.status == 'ok' %}
<div class="tt-field">
<span>Indexers</span>
<span class="tt-field-meta">{{ prowlarr.up_count }} of {{ prowlarr.total }} up</span>
</div>
<div class="tt-rows">
{% for idx in prowlarr.indexers %}
<div class="tt-row">
<span class="tt-row-name">{{ idx.protocol | default('') }}</span>
<span class="tt-row-body">
<span class="tt-row-title">{{ idx.name }}</span>
{% if prowlarr.has_stats %}<span class="tt-row-sub">{{ idx.grabs | default(0) }} grabs &middot; {{ idx.queries | default(0) }} queries</span>{% endif %}
</span>
{% if prowlarr.has_stats %}{{ bar(idx.grab_share | default(0), 'ok' if idx.up else 'alert') }}{% endif %}
<span class="tt-row-val {{ 'ok' if idx.up else 'alert' }}">{{ 'UP' if idx.up else 'DOWN' }}</span>
</div>
{% endfor %}
</div>
{% else %}
<div class="tt-field crit"><span>Indexers</span><span class="tt-field-meta">off air</span></div>
{{ service_error('Prowlarr', prowlarr.error) }}
{% endif %}
{#- ── Admin ─────────────────────────────────────────────────────
Shows Sonarr is holding, sized, that nobody has ever played in
Tautulli and that have sat untouched for longer than the
neglect window — largest first, since the point is reclaiming
space. Delete removes the series from Sonarr with its episode
files and folder; that's permanent, so it shares the site's
two-tap arming rather than a native confirm(). -#}
{% if admin_unwatched.status != 'ok' %}
<div class="tt-field crit"><span>Admin</span><span class="tt-field-meta">off air</span></div>
{{ service_error('Sonarr/Tautulli', admin_unwatched.error) }}
{% else %}
<div class="tt-field">
<span>Admin</span>
<span class="tt-field-meta" id="admin-meta">
{{ admin_unwatched.shows | length }} unwatched &middot; {{ admin_unwatched.total_display }} reclaimable
</span>
</div>
{% if admin_unwatched.shows %}
<div class="tt-rows" id="admin-rows">
{% for show in admin_unwatched.shows %}
<div class="tt-row" data-bytes="{{ show.size }}">
<span class="tt-row-name">{{ show.ep_count }} EP</span>
<span class="tt-row-body">
<span class="tt-row-title">{{ show.title }}</span>
<span class="tt-row-sub">{% if show.year %}{{ show.year }} &middot; {% endif %}Downloaded {{ show.added[:10] if show.added else 'unknown' }} &middot; {% if show.requested_by %}Requested by {{ show.requested_by }}{% else %}Requester unknown{% endif %} &middot; Never watched</span>
</span>
<span class="tt-row-val">{{ show.size_display }}</span>
<span class="tt-row-acts">
<button class="tt-btn tt-btn-no tt-btn-sm" data-id="{{ show.sonarr_id }}"
onclick="armDelete(this)" aria-label="Delete {{ show.title }}">Delete</button>
</span>
</div>
{% endfor %}
</div>
{% else %}
<p class="tt-empty" id="admin-empty">Nothing unwatched and older than {{ admin_unwatched.months }} months is taking up meaningful space.</p>
{% endif %}
{% endif %}
{% endblock %}