Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 48s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 49s
Lint / Python (flake8) (pull_request) Successful in 51s
Test / Python Tests (pytest) (push) Successful in 1m2s
Lint / JS (eslint) (pull_request) Successful in 7s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 50s
Test / Python Tests (pytest) (pull_request) Successful in 53s
Cutsheet items gain a "Gandalf device" link, so an item named after the product (UDM-Pro) shows the live device's faceplate, ports and status. Cable checks, suggestions, tickets and the device page treat an item and its linked device as one. Without this, product-named items drew as bare name plates. Items can sit on a shelf instead of a rack unit; the shelf draws what is on it with live status. Items have a rack, the page shows a tab per rack (config "racks"), and a rack can be downloaded as SVG or PNG. The rack is centred, long runs of empty units fold into one band (with a toggle), every device fills the 19" width, the UPS shows its front only, and the rack keeps its own palette so it reads in light mode. New cutsheet_items columns rack, shelf and device are added on first use. Deleting a shelf, or making it something else, is refused while it holds items; renaming it carries over. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
1.9 KiB
HTML
44 lines
1.9 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Rack{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="lt-page-header">
|
|
<div>
|
|
<h1 class="lt-page-title">Rack</h1>
|
|
<p class="g-page-sub">The rack front, drawn from the rack units on the cutsheet with live port state. Hover a port to light up every port on the same cable run; click it to open the port or the cable.</p>
|
|
</div>
|
|
<div class="cs-actions no-print">
|
|
<button type="button" class="lt-btn lt-btn-secondary lt-btn-sm" data-export="svg">Download SVG</button>
|
|
<button type="button" class="lt-btn lt-btn-secondary lt-btn-sm" data-export="png">Download PNG</button>
|
|
{% if can_edit %}
|
|
<a class="lt-btn lt-btn-secondary lt-btn-sm" href="/cutsheet#cs-items-section">Edit positions</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rack-tabs" id="rack-tabs" role="tablist" aria-label="Racks" hidden></div>
|
|
|
|
<div class="rack-warnings" id="rack-warnings" role="alert" hidden></div>
|
|
|
|
<section class="g-section">
|
|
<div class="g-section-header">
|
|
<h2 class="g-section-title" id="rack-title">Front</h2>
|
|
<span class="g-section-badge" id="rack-count">0</span>
|
|
</div>
|
|
<p class="rack-readout" id="rack-readout" aria-live="polite"></p>
|
|
<div class="rack-legend" aria-hidden="true">
|
|
<span><i class="rack-key rack-key-ok"></i>matches cutsheet</span>
|
|
<span><i class="rack-key rack-key-bad"></i>mismatch</span>
|
|
<span><i class="rack-key rack-key-doc"></i>documented, unconfirmed</span>
|
|
<label class="rack-toggle"><input type="checkbox" id="rack-show-empty"> Show empty units</label>
|
|
</div>
|
|
<div class="rack" id="rack"><div class="link-loading">Loading rack</div></div>
|
|
<p class="cs-hint rack-unplaced" id="rack-unplaced"></p>
|
|
</section>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script src="{{ url_for('static', filename='faceplates.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='rack.js') }}"></script>
|
|
{% endblock %}
|