Files
FabledSteward/steward/templates/monitors/widget.html
T
bvandeusenandClaude Opus 5.5 b29b160baa
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 1m23s
CI / unit (push) Successful in 1m33s
CI / publish (push) Successful in 1m16s
feat(widgets): Overview verdict, pending monitors' age, fullest filesystems first (#5810)
- Overview: a verdict line when something is wrong ('1 alert firing, 1
  monitor down.'); its picker description now says what it lists (alerts,
  monitors down, anomalies). Host figures have their home in Hosts.
  Comments no longer name the Status page that was folded into Monitors.
- Monitors widget: a monitor not checked yet says when it was added.
- Host page: filesystems fullest first, by the worse of space and inodes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:11:37 -04:00

46 lines
3.1 KiB
HTML

{# monitors/widget.html — the dashboard Monitors widget (#5250): a verdict,
then one row per monitor, problems first with why and since when, under one
header of latency and uptime over 24h / 7d / 30d. It replaced the separate
Uptime / SLA widget, so uptime has one home. #}
{% from "_macros.html" import status_dot %}
{% if not total %}
<div class="w-verdict" style="color:var(--text-muted);">
No monitors configured.{% if session.user_id %} <a href="/monitors/new">Add a monitor →</a>{% endif %}
</div>
{% else %}
<div class="w-verdict {{ 'tone-crit' if counts.down else ('tone-warn' if counts.degraded or counts.pending else 'tone-ok') }}">
{%- if counts.down %}{{ counts.down }} of {{ total }} monitor{{ 's' if total != 1 }} down{% if counts.degraded %}, {{ counts.degraded }} degraded{% endif %}.
{%- elif counts.degraded %}{{ counts.degraded }} of {{ total }} monitor{{ 's' if total != 1 }} degraded, the rest up.
{%- elif counts.pending %}{{ counts.pending }} not checked yet, {{ counts.up }} up.
{%- else %}All {{ counts.up }} monitor{{ 's' if counts.up != 1 }} up{% if counts.paused %}, {{ counts.paused }} paused{% endif %}.{% endif -%}
</div>
{% if problems or rest %}
<table class="w-table">
<colgroup><col><col style="width:4.5rem"><col style="width:4.5rem"><col style="width:4.5rem"><col style="width:4.5rem"></colgroup>
<thead><tr><th>Monitor</th><th>Latency</th><th>24h</th><th>7d</th><th>30d</th></tr></thead>
<tbody>
{% for d in problems + rest %}
{% set m = d.monitor %}{% set latest = d.latest %}
<tr>
<td class="w-name" title="{{ m.name }}">
{{- status_dot(d.state) -}}
{% if session.user_id %}<a href="/monitors/{{ m.id }}">{{ m.name }}</a>{% else %}{{ m.name }}{% endif %}
{%- if d.state == 'down' %}<span class="w-sub tone-crit">went down {{ d.down_since|ago if d.down_since else '' }}{% if d.down_reason %} · {{ d.down_reason }}{% endif %}</span>
{%- elif d.state == 'degraded' %}<span class="w-sub tone-warn">{% if (d.latency or status_class(latest.response_ms, 'latency') if latest else none) == 'crit' %}slow replies{% else %}checks failing now and then{% endif %}</span>
{%- elif d.state == 'pending' %}<span class="w-sub">not checked yet{% if m.created_at %} · added {{ m.created_at|ago }}{% endif %}</span>{% endif %}
</td>
{% set lat = (d.latency or status_class(latest.response_ms, 'latency')) if latest and latest.is_up and latest.response_ms is not none else none %}
<td class="{{ 'tone-' ~ lat if lat in ('warn', 'crit') }}"{% if d.latency_usual %} title="{{ d.latency_usual|capitalize }}"{% endif %}>
{%- if latest and latest.is_up and latest.response_ms is not none %}{{ "%.0f"|format(latest.response_ms) }} ms{% else %}—{% endif -%}
</td>
{% for k in ("24h", "7d", "30d") %}{% set u = d.uptime.get(k) %}
<td style="{{ threshold_style(u, 'uptime') if u is not none }}">{% if u is none %}—{% else %}{{ "%.2f"|format(u) }}%{% endif %}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if more %}<div class="w-more">+{{ more }} more up{% if session.user_id %} · <a href="/monitors/">all monitors</a>{% endif %}</div>{% endif %}
{% endif %}