feat: maintenance windows, reports, uptime widget, alert improvements
- Add maintenance window scheduling to suppress alerts during planned downtime (model, routes, templates) - Add weekly email/webhook reports with host summary (core/reports.py, Settings → Reports tab) - Add host uptime history widget with per-check sparkline view - Expand alert rules: dynamic metric catalog for plugin sources, per-rule HTMX field loading, maintenance window awareness - Register additional dashboard widgets (uptime, SNMP, UniFi, UPS) - Add Settings → Reports tab configuration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
{% set tabs = [
|
||||
("general", "General", "/settings/general/"),
|
||||
("notifications", "Notifications", "/settings/notifications/"),
|
||||
("reports", "Reports", "/settings/reports/"),
|
||||
("auth", "Auth", "/settings/auth/"),
|
||||
("ansible", "Ansible", "/settings/ansible/"),
|
||||
("plugins", "Plugins", "/settings/plugins/"),
|
||||
] %}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
{# fabledscryer/templates/settings/reports.html #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Settings — Reports — Fabled Scryer{% endblock %}
|
||||
{% block content %}
|
||||
{% set active_tab = "reports" %}
|
||||
{% include "settings/_tabs.html" %}
|
||||
|
||||
{% if flash %}
|
||||
<div style="padding:0.75rem 1rem;border-radius:6px;margin-bottom:1.25rem;
|
||||
background:{% if flash.ok %}var(--green-dim){% else %}var(--red-dim){% endif %};
|
||||
border:1px solid {% if flash.ok %}var(--green){% else %}var(--red){% endif %};
|
||||
color:{% if flash.ok %}var(--green){% else %}var(--red){% endif %};
|
||||
font-size:0.88rem;">
|
||||
{{ flash.message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div style="max-width:560px;">
|
||||
|
||||
{# ── Schedule ─────────────────────────────────────────────────────────────── #}
|
||||
<form method="post" action="/settings/reports/">
|
||||
<div class="card" style="margin-bottom:1.25rem;">
|
||||
<h2 class="section-title" style="margin-bottom:1.25rem;">Weekly Digest</h2>
|
||||
|
||||
<div class="form-group" style="display:flex;align-items:center;gap:0.75rem;">
|
||||
<input type="checkbox" name="reports.enabled" id="reports-enabled"
|
||||
{% if settings['reports.enabled'] %}checked{% endif %}>
|
||||
<label for="reports-enabled" style="margin:0;">Enable weekly email digest</label>
|
||||
</div>
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-top:0.5rem;">
|
||||
<div class="form-group">
|
||||
<label>Send on day</label>
|
||||
<select name="reports.schedule_day">
|
||||
{% for i, day in [(0,"Monday"),(1,"Tuesday"),(2,"Wednesday"),(3,"Thursday"),(4,"Friday"),(5,"Saturday"),(6,"Sunday")] %}
|
||||
<option value="{{ i }}" {% if settings['reports.schedule_day'] == i %}selected{% endif %}>
|
||||
{{ day }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>At hour (UTC)</label>
|
||||
<select name="reports.schedule_hour">
|
||||
{% for h in range(24) %}
|
||||
<option value="{{ h }}" {% if settings['reports.schedule_hour'] == h %}selected{% endif %}>
|
||||
{{ "%02d:00"|format(h) }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="font-size:0.78rem;color:var(--text-muted);margin-top:0.25rem;">
|
||||
Requires SMTP configured in <a href="/settings/notifications/">Notifications</a>.
|
||||
{% if settings['reports.last_sent_at'] %}
|
||||
Last sent: {{ settings['reports.last_sent_at'][:16] }} UTC.
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<div style="margin-top:1rem;">
|
||||
<button type="submit" class="btn">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# ── Report contents ─────────────────────────────────────────────────────── #}
|
||||
<div class="card" style="margin-bottom:1.25rem;">
|
||||
<h2 class="section-title" style="margin-bottom:0.75rem;">Report contents</h2>
|
||||
<div style="display:grid;gap:0.35rem;font-size:0.85rem;color:var(--text-muted);">
|
||||
<div>• <strong style="color:var(--text);">Uptime summary</strong> — 7-day % per ping-enabled host</div>
|
||||
<div>• <strong style="color:var(--text);">Hosts currently down</strong> — highlighted at top if any</div>
|
||||
<div>• <strong style="color:var(--text);">Active alerts</strong> — firing, acknowledged, pending rules</div>
|
||||
<div>• <strong style="color:var(--text);">Alert events (7d)</strong> — fired and resolved counts</div>
|
||||
<div>• <strong style="color:var(--text);">Top Traefik routers</strong> — avg req/s over last 24h (if plugin enabled)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── Send now ─────────────────────────────────────────────────────────────── #}
|
||||
<div class="card">
|
||||
<h2 class="section-title" style="margin-bottom:0.75rem;">Send Now</h2>
|
||||
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">
|
||||
Send a report immediately regardless of schedule. Useful for testing.
|
||||
</p>
|
||||
<form method="post" action="/settings/reports/send-now/">
|
||||
<button type="submit" class="btn btn-ghost">Send report now</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user