Redesign: alerts above fold, fix nav, globalise suppress modal
Lint / Python (flake8) (push) Successful in 37s
Lint / JS (eslint) (push) Successful in 7s
Security / Python Security (bandit) (push) Successful in 40s
Test / Python Tests (pytest) (push) Successful in 53s
Lint / Notify on failure (push) Has been skipped
Lint / Deploy (push) Successful in 2s

- Dashboard: reorder sections so Active Alerts appear immediately below
  stat cards rather than after 200+ lines of topology — primary content
  is now above the fold on all screen sizes
- Network Hosts section gains a collapse toggle (persisted to localStorage)
  so the topology diagram can be hidden when not needed
- Admin nav corrected: admin now gets a direct Suppressions link;
  non-admin no longer sees the page at all (it was always admin-only)
- Suppress modal moved from index.html into base.html so [S] keyboard
  shortcut works on every page, not just the dashboard; form listeners
  wired in app.js accordingly
- Settings modal KV grid: replaced lt-kv-row/lt-kv-label/lt-kv-value
  (light-mode only) with lt-kv-key/lt-kv-val (dark-mode defined)
- style.css: add lt-btn-secondary dark-mode definition, lt-cmd-hint-btn
  class for ⌘K button, topology collapse styles; remove dead .g-page-header,
  .g-page-title, .empty-state classes; strip redundant inline styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 23:07:53 -04:00
parent 7b4c263a40
commit ed19838a4e
4 changed files with 228 additions and 197 deletions
+59 -34
View File
@@ -73,7 +73,6 @@
<a href="{{ url_for('index') }}"
class="lt-brand-title lt-glitch"
data-text="GANDALF"
style="text-decoration:none"
aria-label="GANDALF home">GANDALF</a>
<span class="lt-brand-subtitle">Network Monitor // LotusGuild</span>
</div>
@@ -96,28 +95,6 @@
Inspector
</a>
{% if user.groups and 'admin' in user.groups %}
<div class="lt-nav-dropdown" data-action="toggle-nav-dropdown">
<a href="#"
class="lt-nav-link{% if request.endpoint == 'suppressions_page' %} active{% endif %}"
role="button"
aria-haspopup="true"
aria-expanded="false"
aria-controls="lt-admin-dropdown-menu">
Admin &#x25BE;
</a>
<ul class="lt-nav-dropdown-menu"
id="lt-admin-dropdown-menu"
role="menu"
aria-label="Admin menu">
<li role="none">
<a href="{{ url_for('suppressions_page') }}" role="menuitem"
class="{% if request.endpoint == 'suppressions_page' %}active{% endif %}">
Suppressions
</a>
</li>
</ul>
</div>
{% else %}
<a href="{{ url_for('suppressions_page') }}"
class="lt-nav-link{% if request.endpoint == 'suppressions_page' %} active{% endif %}"
{% if request.endpoint == 'suppressions_page' %}aria-current="page"{% endif %}>
@@ -166,11 +143,10 @@
<!-- ⌘K affordance -->
<button type="button"
class="lt-btn lt-btn-ghost lt-btn-sm"
class="lt-btn lt-btn-ghost lt-btn-sm lt-cmd-hint-btn"
title="Command palette (Ctrl+K)"
aria-label="Open command palette"
onclick="if(window.lt&&lt.cmdPalette)lt.cmdPalette.open()"
style="font-size:0.65rem;opacity:0.55;letter-spacing:0.03em;padding:0.2rem 0.45rem">&#x2315;&nbsp;K</button>
onclick="if(window.lt&&lt.cmdPalette)lt.cmdPalette.open()">&#x2315;&nbsp;K</button>
<button type="button" class="lt-theme-btn" id="lt-theme-btn"
aria-label="Toggle theme" title="Toggle light/dark mode">&#x2600;</button>
@@ -221,6 +197,59 @@
<span>GANDALF &mdash; TDS v1.2</span>
</footer>
<!-- QUICK-SUPPRESS MODAL — available on all pages via [S] shortcut -->
<div id="suppress-modal" class="lt-modal-overlay"
role="dialog" aria-modal="true" aria-labelledby="suppress-modal-title" aria-hidden="true">
<div class="lt-modal">
<div class="lt-modal-header">
<h3 class="lt-modal-title" id="suppress-modal-title">Suppress Alert</h3>
<button type="button" class="lt-modal-close" data-modal-close aria-label="Close">&#x2715;</button>
</div>
<form id="suppress-form">
<div class="lt-modal-body">
<div class="lt-form-group" style="margin-bottom:12px">
<label class="lt-label" for="sup-type">Target Type</label>
<select class="lt-select" id="sup-type" name="target_type">
<option value="host">Host (all interfaces)</option>
<option value="interface">Specific Interface</option>
<option value="unifi_device">UniFi Device</option>
<option value="all">Global Maintenance</option>
</select>
</div>
<div class="lt-form-group" id="sup-name-group" style="margin-bottom:12px">
<label class="lt-label" for="sup-name">Target Name</label>
<input type="text" class="lt-input" id="sup-name" name="target_name" placeholder="e.g. large1">
</div>
<div class="lt-form-group" id="sup-detail-group" style="margin-bottom:12px;display:none">
<label class="lt-label" for="sup-detail">Interface <span class="lt-field-hint">(interface type only)</span></label>
<input type="text" class="lt-input" id="sup-detail" name="target_detail" placeholder="e.g. enp35s0">
</div>
<div class="lt-form-group" style="margin-bottom:12px">
<label class="lt-label" for="sup-reason">Reason <span class="required">*</span></label>
<input type="text" class="lt-input" id="sup-reason" name="reason"
placeholder="e.g. Planned switch reboot" required>
</div>
<div class="lt-form-group" style="margin-bottom:0">
<label class="lt-label">Duration</label>
<div class="duration-pills">
<button type="button" class="pill" data-duration="30">30 min</button>
<button type="button" class="pill" data-duration="60">1 hr</button>
<button type="button" class="pill" data-duration="240">4 hr</button>
<button type="button" class="pill" data-duration="480">8 hr</button>
<button type="button" class="pill pill-manual active" data-duration="">Manual &#x221E;</button>
</div>
<input type="hidden" id="sup-expires" name="expires_minutes" value="">
<div class="lt-field-hint" id="duration-hint">Persists until manually removed.</div>
</div>
</div>
<div class="lt-modal-footer">
<button type="button" class="lt-btn lt-btn-secondary" data-modal-close>Cancel</button>
<button type="submit" class="lt-btn lt-btn-primary">Apply</button>
</div>
</form>
</div>
</div>
<!-- KEYBOARD SHORTCUTS MODAL -->
<div id="lt-keys-help" class="lt-modal-overlay" aria-hidden="true">
<div class="lt-modal" role="dialog" aria-modal="true" aria-labelledby="keys-help-title">
@@ -268,15 +297,11 @@
</div>
<div class="lt-divider" style="margin:1rem 0 0.75rem"></div>
<div class="lt-kv-grid">
<div class="lt-kv-row">
<span class="lt-kv-label">User</span>
<span class="lt-kv-value lt-text-cyan">{{ user.name or user.username }}</span>
</div>
<span class="lt-kv-key">User</span>
<span class="lt-kv-val lt-kv-val--cyan">{{ user.name or user.username }}</span>
{% if user.groups %}
<div class="lt-kv-row">
<span class="lt-kv-label">Groups</span>
<span class="lt-kv-value">{{ user.groups | join(', ') }}</span>
</div>
<span class="lt-kv-key">Groups</span>
<span class="lt-kv-val">{{ user.groups | join(', ') }}</span>
{% endif %}
</div>
</div>