Move the port inspector onto device pages
Lint / JS (eslint) (push) Successful in 1m14s
Lint / Python (flake8) (push) Successful in 2m12s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 1m3s
Test / Python Tests (pytest) (push) Successful in 1m11s
Lint / Python (flake8) (pull_request) Successful in 1m1s
Lint / JS (eslint) (pull_request) Successful in 10s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 56s
Test / Python Tests (pytest) (pull_request) Successful in 1m5s

Replace the all-switches Inspector page with a per-device front panel,
port table and detail panel. /inspector now redirects to the dashboard,
and /device/<name>#port-<n> links directly to a port.

Restore neighbor names after UniFi's LLDP change: read local_port_idx
and resolve neighbors by MAC using Prometheus NIC data, UniFi devices
and the wired client table. This also brings back Run Diagnostics on
server ports, which depends on a named neighbor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 10:11:11 -05:00
co-authored by Claude Opus 5.5
parent e32499b7f6
commit bdcfb76c25
13 changed files with 484 additions and 226 deletions
+30
View File
@@ -16,10 +16,40 @@
<div id="device-root"><div class="link-loading">Loading device</div></div>
<!-- Outside device-root: auto-refresh must not reset the filter or port panel -->
<section class="g-section" id="device-ports" hidden>
<div class="g-section-header"><h2 class="g-section-title" id="device-ports-title">Ports</h2></div>
<div class="device-inspector" id="device-inspector">
<div class="device-chassis" id="device-chassis" role="region" aria-label="Front panel"></div>
<div class="inspector-panel" id="inspector-panel" role="complementary" aria-label="Port detail panel">
<div class="inspector-panel-inner" id="inspector-panel-inner"></div>
</div>
<div class="lt-frame device-port-table">
<span class="lt-frame-bl">&#x255A;</span>
<span class="lt-frame-br">&#x255D;</span>
<div class="lt-toolbar device-toolbar">
<div class="lt-toolbar-left">
<div class="lt-search">
<input type="search" class="lt-input lt-search-input lt-search-input--sm" id="device-table-search"
placeholder="Filter…" autocomplete="off" aria-label="Filter ports">
</div>
<div class="sev-pills" role="group" aria-label="Filter by state">
<button type="button" class="pill active" data-device-filter="all" aria-pressed="true">All</button>
<button type="button" class="pill" data-device-filter="up" aria-pressed="false">Up</button>
<button type="button" class="pill" data-device-filter="problems" aria-pressed="false">Errors (<span id="device-error-count">0</span>)</button>
</div>
</div>
</div>
<div id="device-table-wrap"></div>
</div>
</div>
</section>
{% include "_modem_panel.html" %}
{% endblock %}
{% block scripts %}
<script>const DEVICE_NAME = {{ device_name | tojson }};</script>
<script src="{{ url_for('static', filename='port-inspector.js') }}"></script>
<script src="{{ url_for('static', filename='device.js') }}"></script>
{% endblock %}