Files
gandalf/templates/device.html
T
jaredandClaude Opus 5.5 c262e5ecc8
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 54s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 1m1s
Lint / JS (eslint) (pull_request) Successful in 19s
Test / Python Tests (pytest) (push) Successful in 2m6s
Security / Python Security (bandit) (pull_request) Successful in 1m18s
Lint / Python (flake8) (pull_request) Successful in 53s
Test / Python Tests (pytest) (pull_request) Successful in 1m1s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Inventory links, cutsheet marks on faceplates, and single page titles
Device pages get an Inventory button: it opens the device's HomeBox record
once an admin pastes its URL (stored in the new device_links table; only
URLs on inventory.base_url are accepted), and searches the inventory for
the model until then. Tickets link the record too.

Faceplate ports with a documented cable get a corner dot: green matches,
red mismatch, grey documented but unconfirmed. The port's tooltip names
the cable, and a legend toggle (remembered per browser) hides them.

Page titles no longer repeat GANDALF ("Alert History - GANDALF - GANDALF").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 20:47:14 -05:00

84 lines
3.9 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ device_name }}{% endblock %}
{% block content %}
<div class="lt-page-header">
<div>
<p class="g-page-sub"><a href="{{ url_for('index') }}">← Dashboard</a></p>
<h1 class="lt-page-title device-title">
<span id="device-dot" class="dot-unknown"></span>
<span>{{ device_name }}</span>
</h1>
<p class="g-page-sub" id="device-subtitle"></p>
</div>
<div id="device-actions" class="device-actions"></div>
</div>
<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" %}
{% if can_edit %}
<div id="inventory-modal" class="lt-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="inventory-title" aria-hidden="true">
<div class="lt-modal">
<div class="lt-modal-header">
<h3 class="lt-modal-title" id="inventory-title">Inventory link</h3>
<button type="button" class="lt-modal-close" data-modal-close aria-label="Close">&#x2715;</button>
</div>
<form id="inventory-form">
<div class="lt-modal-body">
<p class="cs-hint">Open this device's record in the inventory and paste its address here. Leave it empty to remove the link.</p>
<div class="lt-form-group">
<label class="lt-label" for="inventory-url">Inventory record URL</label>
<input class="lt-input" id="inventory-url" name="url" type="url" inputmode="url" autocomplete="off"
placeholder="https://inventory.lotusguild.org/item/…">
</div>
<p class="cs-hint"><a id="inventory-search" href="#" target="_blank" rel="noopener">Search the inventory for this model ↗</a></p>
</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">Save</button>
</div>
</form>
</div>
</div>
{% endif %}
{% endblock %}
{% block scripts %}
<script>const DEVICE_NAME = {{ device_name | tojson }};
const CAN_EDIT = {{ 'true' if can_edit else 'false' }};</script>
<script src="{{ url_for('static', filename='faceplates.js') }}"></script>
<script src="{{ url_for('static', filename='port-inspector.js') }}"></script>
<script src="{{ url_for('static', filename='device.js') }}"></script>
{% endblock %}