feat: UI redesign (CSS system, DNS widget, Traefik dashboard widget)

- Replace base.html style block with full CSS design system using custom properties (dark theme, cards, tables, badges, dots, widgets)
- Add DNS blueprint (fablednetmon/dns/) with /dns/ and /dns/rows routes + templates
- Add Traefik /widget route and widget.html fragment for dashboard
- Update dashboard: DNS + Traefik widgets, traefik_enabled config detection
- Update all templates to use new CSS classes (page-title, section-title, card-flush, table, badge-*, dot-*, btn-*)
- Register dns_bp in app.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 23:37:46 -04:00
parent d29c5b3eab
commit 165a202ba4
22 changed files with 495 additions and 236 deletions
+18 -18
View File
@@ -2,37 +2,37 @@
{% block title %}Ansible Runs — FabledNetMon{% endblock %}
{% block content %}
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;">
<h1 style="color:#c0c0ff;">Ansible Runs</h1>
<h1 class="page-title" style="margin-bottom:0;">Ansible Runs</h1>
<a href="/ansible/browse" class="btn">Browse Playbooks</a>
</div>
{% if not runs %}
<div class="card">
<p style="color:#606080;">No runs yet. <a href="/ansible/browse" style="color:#a0a0ff;">Browse playbooks</a> to trigger a run.</p>
<p style="color:var(--text-muted);">No runs yet. <a href="/ansible/browse">Browse playbooks</a> to trigger a run.</p>
</div>
{% else %}
<div class="card" style="padding:0;overflow:hidden;">
<table style="width:100%;border-collapse:collapse;">
<div class="card-flush">
<table class="table">
<thead>
<tr style="background:#12122a;">
<th style="padding:0.75rem 1rem;text-align:left;color:#a0a0c0;font-weight:normal;font-size:0.85rem;">Playbook</th>
<th style="padding:0.75rem 1rem;text-align:left;color:#a0a0c0;font-weight:normal;font-size:0.85rem;">Source</th>
<th style="padding:0.75rem 1rem;text-align:left;color:#a0a0c0;font-weight:normal;font-size:0.85rem;">Status</th>
<th style="padding:0.75rem 1rem;text-align:left;color:#a0a0c0;font-weight:normal;font-size:0.85rem;">Started</th>
<th style="padding:0.75rem 1rem;text-align:left;color:#a0a0c0;font-weight:normal;font-size:0.85rem;"></th>
<tr>
<th>Playbook</th>
<th>Source</th>
<th>Status</th>
<th>Started</th>
<th></th>
</tr>
</thead>
<tbody>
{% for run in runs %}
{% set status_color = {"running": "#a0a000", "success": "#40a040", "failed": "#a04040", "interrupted": "#806040"}.get(run.status.value, "#808080") %}
<tr style="border-top:1px solid #2a2a4a;">
<td style="padding:0.75rem 1rem;color:#e0e0e0;font-size:0.9rem;">{{ run.playbook_path }}</td>
<td style="padding:0.75rem 1rem;color:#8080a0;font-size:0.9rem;">{{ run.source_name }}</td>
<td style="padding:0.75rem 1rem;">
{% set status_color = {"running": "var(--yellow)", "success": "var(--green)", "failed": "var(--red)", "interrupted": "var(--orange)"}.get(run.status.value, "var(--text-muted)") %}
<tr>
<td style="font-size:0.9rem;">{{ run.playbook_path }}</td>
<td style="color:var(--text-muted);font-size:0.9rem;">{{ run.source_name }}</td>
<td>
<span style="color:{{ status_color }};font-size:0.85rem;font-weight:bold;">{{ run.status.value.upper() }}</span>
</td>
<td style="padding:0.75rem 1rem;color:#606080;font-size:0.85rem;">{{ run.started_at.strftime("%Y-%m-%d %H:%M") }}</td>
<td style="padding:0.75rem 1rem;">
<a href="/ansible/runs/{{ run.id }}" style="color:#a0a0ff;font-size:0.85rem;">View</a>
<td style="color:var(--text-muted);font-size:0.85rem;">{{ run.started_at.strftime("%Y-%m-%d %H:%M") }}</td>
<td class="td-actions">
<a href="/ansible/runs/{{ run.id }}" class="btn btn-sm btn-ghost">View</a>
</td>
</tr>
{% endfor %}