2026-11-10 20:59:30 -05:00
{% 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" >
2026-11-10 21:44:59 -05:00
< 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 %}
2026-11-10 22:35:37 -05:00
< button type = "button" class = "lt-btn lt-btn-secondary lt-btn-sm" data-action = "rack-settings" > Rack settings</ button >
< button type = "button" class = "lt-btn lt-btn-secondary lt-btn-sm" data-action = "add-rack" > + Rack</ button >
2026-11-10 20:59:30 -05:00
< a class = "lt-btn lt-btn-secondary lt-btn-sm" href = "/cutsheet#cs-items-section" > Edit positions</ a >
2026-11-10 21:44:59 -05:00
{% endif %}
2026-11-10 20:59:30 -05:00
</ div >
</ div >
2026-11-10 22:35:37 -05:00
< div class = "rack-bar" >
< div class = "rack-tabs" id = "rack-tabs" role = "tablist" aria-label = "Racks" hidden ></ div >
< div class = "rack-face" role = "group" aria-label = "Rack side" >
2026-11-11 00:12:07 -05:00
< button type = "button" class = "rack-face-btn active" data-face = "front" aria-pressed = "true"
title = "The front posts, seen from the front" > Front</ button >
< button type = "button" class = "rack-face-btn" data-face = "behind" aria-pressed = "false"
title = "Gear on the rear posts, seen from the front (what is behind the front gear)" > Rear posts</ button >
< button type = "button" class = "rack-face-btn" data-face = "rear" aria-pressed = "false"
title = "The rack seen from behind" > Rear</ button >
2026-11-10 22:35:37 -05:00
</ div >
</ div >
2026-11-10 21:44:59 -05:00
2026-11-10 20:59:30 -05:00
< div class = "rack-warnings" id = "rack-warnings" role = "alert" hidden ></ div >
< section class = "g-section" >
< div class = "g-section-header" >
2026-11-10 21:44:59 -05:00
< h2 class = "g-section-title" id = "rack-title" > Front</ h2 >
2026-11-10 20:59:30 -05:00
< 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 >
2026-11-10 21:44:59 -05:00
< label class = "rack-toggle" >< input type = "checkbox" id = "rack-show-empty" > Show empty units</ label >
2026-11-10 20:59:30 -05:00
</ 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 >
2026-11-10 22:35:37 -05:00
{% if can_edit %}
< div id = "rack-modal" class = "lt-modal-overlay" role = "dialog" aria-modal = "true" aria-labelledby = "rack-modal-title" aria-hidden = "true" >
< div class = "lt-modal" >
< div class = "lt-modal-header" >
< h3 class = "lt-modal-title" id = "rack-modal-title" > Rack settings</ h3 >
< button type = "button" class = "lt-modal-close" data-modal-close aria-label = "Close" > ✕ </ button >
</ div >
< form id = "rack-form" autocomplete = "off" >
< div class = "lt-modal-body" >
< input type = "hidden" name = "id" >
< input type = "hidden" name = "previous" >
< div class = "form-row" >
< div class = "lt-form-group" >
< label class = "lt-label" for = "rack-name" > Name < span class = "required" > *</ span ></ label >
< input class = "lt-input" id = "rack-name" name = "name" required maxlength = "100" placeholder = "e.g. StarTech 25U" >
</ div >
< div class = "lt-form-group" >
< label class = "lt-label" for = "rack-units" > Height (U) < span class = "required" > *</ span ></ label >
< input class = "lt-input" id = "rack-units" name = "units" type = "number" min = "1" max = "60" required >
</ div >
</ div >
< div class = "lt-form-group" >
< label class = "lt-label" for = "rack-notes" > Notes</ label >
< textarea class = "lt-input" id = "rack-notes" name = "notes" rows = "2" maxlength = "2000" placeholder = "model, location, depth" ></ textarea >
</ div >
< p class = "cs-hint" > Renaming a rack moves its items with it. A rack can be deleted once it is empty.</ p >
</ div >
< div class = "lt-modal-footer" >
< button type = "button" class = "lt-btn lt-btn-danger" data-action = "delete-rack" > Delete</ button >
< 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 %}
2026-11-10 20:59:30 -05:00
{% endblock %}
{% block scripts %}
2026-11-10 22:35:37 -05:00
< script > const RACK_CAN_EDIT = {{ 'true' if can_edit else 'false' }};</ script >
2026-11-10 20:59:30 -05:00
< script src = "{{ url_for('static', filename='faceplates.js') }}" ></ script >
2026-11-10 23:25:02 -05:00
< script src = "{{ url_for('static', filename='fronts.js') }}" ></ script >
2026-11-10 20:59:30 -05:00
< script src = "{{ url_for('static', filename='rack.js') }}" ></ script >
{% endblock %}