Commit Graph
10 Commits
Author SHA1 Message Date
jaredandClaude Opus 5.5 a9de175d90 Rack: ports-facing separate from posts, three views, ZimaBoard 832 shelves to scale
Lint / JS (eslint) (push) Successful in 8s
Lint / Python (flake8) (push) Successful in 1m0s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 1m9s
Lint / Python (flake8) (pull_request) Successful in 57s
Test / Python Tests (pytest) (push) Successful in 1m14s
Lint / JS (eslint) (pull_request) Successful in 8s
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
Gear on the rear posts usually still faces the front (the StarTech's RPDU
and ZimaBoard shelf), so "which posts" and "which way the ports face" are
now separate fields (mount, facing). The page has three views: Front (front
posts), Rear posts (rear-post gear seen from the front, i.e. what is behind
the front gear) and Rear (from behind). An item seen from the side it
doesn't face shows its back. Facing defaults to front, so existing items
keep their meaning.

Shelves are drawn at true scale with their contents ordered by a new
"Position on shelf". The IceWhale ZimaBoard 832 is traced from IceWhale's
labelled photo of its port end (ZimaDocs): Mini-DP, two RJ45-over-USB 3.0
stacks with link/activity LEDs, DC jack, gunmetal case, gold PCB edge and
black base. Its RJ45 link lights follow the host's physical NICs and the
status glow follows the host.

New cutsheet_items columns facing and slot, added on first use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 00:12:07 -05:00
jaredandClaude Opus 5.5 5fdd317539 Rack: clicking a port on an unlinked faceplate opens the cutsheet
Lint / JS (eslint) (push) Successful in 8s
Lint / Python (flake8) (push) Successful in 50s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 1m8s
Lint / JS (eslint) (pull_request) Successful in 22s
Lint / Python (flake8) (pull_request) Successful in 1m49s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 1m12s
Test / Python Tests (pytest) (pull_request) Successful in 1m9s
Test / Python Tests (pytest) (push) Successful in 1m3s
The NVR Pro is drawn by Front drawing because UniFi doesn't report it, so
it has no device page; clicking one of its ports went to /device/UNVR-Pro
and showed "No device with this name". Ports on a faceplate whose item
isn't linked to a live device now open the port's cable when one is
documented, and otherwise the item on the cutsheet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:53:18 -05:00
jaredandClaude Opus 5.5 50db56cdcb Rack: draw the UniFi UACC blank 24-port keystone patch panel
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 58s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Lint / JS (eslint) (pull_request) Successful in 11s
Lint / Python (flake8) (pull_request) Successful in 1m6s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (push) Successful in 1m0s
Test / Python Tests (pytest) (push) Successful in 1m59s
Security / Python Security (bandit) (pull_request) Successful in 1m42s
Test / Python Tests (pytest) (pull_request) Successful in 1m0s
Front drawing "UniFi Patch Panel Blank 24" draws the real panel, laid out
from the CC0 NetBox devicetype-library image: grey steel face, darker ears
with oval holes, 24 keystone openings with the cable-support bar behind
them, and a cable slot at each end. Ports with a documented cable get a
keystone jack; cutsheet marks, port labels and run highlighting work as on
the generic panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:39:27 -05:00
jaredandClaude Opus 5.5 619a2c913d Remove em and en dashes from the UI, code and docs
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 57s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 57s
Lint / JS (eslint) (pull_request) Successful in 10s
Lint / Python (flake8) (pull_request) Successful in 51s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 1m0s
Test / Python Tests (pytest) (push) Successful in 1m3s
Test / Python Tests (pytest) (pull_request) Successful in 52s
Page titles read "Rack | GANDALF", ranges use a hyphen (U26-42,
1-100 of 300), empty cells show "-", and dash-separated phrases use a
colon, comma or full stop. In the shared base.js only the on-screen strings
changed (boot line, placeholders, offline banner and toast).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:37:56 -05:00
jaredandClaude Opus 5.5 565fdd81de Rack: NVR Pro as a real faceplate; Sliger and Rosewill touch-ups
Lint / JS (eslint) (push) Successful in 18s
Security / Python Security (bandit) (push) Successful in 1m45s
Lint / Python (flake8) (push) Successful in 1m25s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Lint / Python (flake8) (pull_request) Successful in 52s
Lint / JS (eslint) (pull_request) Successful in 6s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Test / Python Tests (pytest) (push) Successful in 1m18s
Security / Python Security (bandit) (pull_request) Successful in 56s
Test / Python Tests (pytest) (pull_request) Successful in 53s
The hand-drawn NVR Pro didn't match the UniFi faceplates: flat colours,
low contrast and its own port shapes. It is now a FACEPLATES entry
(UNVRPRO) built from the same parts as the UDM Pro: metal body, RJ45 jack,
SFP+ cage, quad screen, vents and labels. Front drawing "UniFi NVR Pro"
uses it, and it would go live if UniFi ever reports the model.

Sliger bays are numbered 1-10 (driveAtlas's order); the Rosewill door is
perforated with a latch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:31:19 -05:00
jaredandClaude Opus 5.5 0f4e129c20 Rack: drawn fronts for the NVR and server cases
Lint / JS (eslint) (push) Successful in 15s
Security / Python Security (bandit) (push) Successful in 1m5s
Lint / Python (flake8) (push) Successful in 49s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Lint / Python (flake8) (pull_request) Successful in 53s
Test / Python Tests (pytest) (push) Successful in 1m0s
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 53s
Test / Python Tests (pytest) (pull_request) Successful in 57s
Items Gandalf has no live faceplate for can pick a Front drawing: the
UniFi NVR Pro (drawn from the CC0 NetBox devicetype-library image), the
Sliger CX4712 4U and Rosewill RSV-L4500U 4U cases (from driveAtlas's
layouts), and generic 1U/2U/4U servers. The power light shows the linked
device's live status. They export with the rest of the rack.

New cutsheet_items column chassis, added on first use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:25:02 -05:00
jaredandClaude Opus 5.5 97e6692ebf Rack: put a patch panel's name above its ports
Lint / JS (eslint) (push) Successful in 8s
Lint / Python (flake8) (push) Successful in 51s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 54s
Test / Python Tests (pytest) (push) Successful in 1m21s
Lint / Python (flake8) (pull_request) Successful in 1m7s
Lint / JS (eslint) (pull_request) Successful in 13s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 1m18s
Test / Python Tests (pytest) (pull_request) Successful in 1m5s
A long panel name (UACC-Rack-Panel-Patch-Blank-24) was drawn in the left
ear at full size and ran under the ports. It is now a small caption in
the panel's top-left corner, shortened past 48 characters with the full
name in its tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:02:18 -05:00
jaredandClaude Opus 5.5 c50e1f8322 Rack: front and rear mounting, rack settings in the page
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 49s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 51s
Lint / Python (flake8) (pull_request) Successful in 55s
Test / Python Tests (pytest) (push) Successful in 1m4s
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 52s
Test / Python Tests (pytest) (pull_request) Successful in 55s
Items are mounted from the front, the rear, or full depth. On a 4-post
rack a front and a rear item can share a unit; a full-depth one takes
both sides, and the rear view shows its back. Overlaps are checked per
side. Shelf contents take the shelf's side. A Front / Rear switch flips
the drawing.

Racks are saved in Gandalf (new cutsheet_racks table) and edited on the
rack page by admins: name, height, notes, add and delete. Renaming moves
the rack's items; saving the first rack carries over the items of the
config default it replaces. Config racks remain the fallback.

Faceplates are stretched to the full width only when the drawing is
close to the slot's proportions, so the PDU is not squashed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 22:35:37 -05:00
jaredandClaude Opus 5.5 bdd68a397d Rack: link items to devices, shelves, several racks, export; fix layout and light mode
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>
2026-11-10 21:44:59 -05:00
jaredandClaude Opus 5.5 f655836446 Add a rack drawing (/rack)
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 50s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 50s
Test / Python Tests (pytest) (push) Successful in 1m2s
Lint / Python (flake8) (pull_request) Successful in 52s
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 1m42s
Test / Python Tests (pytest) (pull_request) Successful in 2m2s
The rack front is drawn from the rack units on cutsheet items. Switches
with a faceplate use it, with live port state; patch panels get a generic
panel with port labels; everything else is a labelled plate. Each
documented port shows its cutsheet state, and hovering a port lights up
every port on the same cable run (through patch panels) and names the
cables. Clicking opens the switch port or the cable.

Overlapping items and items past the top of the rack are listed instead
of drawn over another; where two claim the same top unit, the first one
recorded wins. rack.units sets the height (default 42).

/api/rack builds on the cutsheet view; cutsheet.rack_layout and
cutsheet.port_marks hold the placement and per-port logic.

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