Inventory links, cutsheet marks on faceplates, single page titles #22

Merged
jared merged 1 commits from inventory-and-faceplate-marks into main 2026-11-10 20:50:27 -05:00
Owner

What changes

Inventory links. Device pages get a 📦 button:

  • With a linked record, it opens the device's record in the inventory.
  • Without one, it searches the inventory for the device's model.
  • Admins set or clear the link with ✎ by pasting the record's URL. Only https:// URLs on inventory.base_url are accepted, which rules out other hosts, lookalike hosts, embedded credentials and javascript: URLs, since the link is shown to every viewer.
  • Links are stored in a new device_links table, created alongside the cutsheet tables.
  • PUT /api/device/<name>/inventory requires admin rights and a JSON body.
  • Tickets now include the inventory link when one is set.

Cutsheet marks on faceplates. A port with a documented cable gets a corner dot:

  • green: it matches what Gandalf sees
  • red: a mismatch (wrong neighbor, no link, missing port, or port conflict)
  • grey: documented but not confirmable (planned, dark, through a panel, or the far end isn't visible)

Hovering a port names the cable and the check result. The legend shows a key for the dots plus a "Cutsheet marks" checkbox that hides them; the browser remembers the choice. The data comes from what /api/device already returns, so no new API calls are made.

Page titles. base.html already appended "— GANDALF", and every page added "– GANDALF" again, so tabs read "Alert History – GANDALF — GANDALF". Each title now has the name once, and a test covers it.

Config: inventory.base_url (default https://inventory.lotusguild.org) and inventory.search_url (default {base}/items?q={q}). I couldn't confirm HomeBox's search route from here because it's behind Authelia. If "Find in inventory" opens the wrong page, set inventory.search_url.

Testing

  • Automated: 339 tests pass (14 new). They cover the inventory link's validation and auth, the configured host, the device API fields, the ticket link, and the page titles.
  • Local MariaDB: device_links table creation can run twice safely. Insert, update and clear all work.
  • Playwright:
    • The page shows 6 marks: 1 green, 2 red and 3 grey, as expected for the seeded cables.
    • The port tooltip names the cable.
    • The marks toggle survives a reload.
    • A bad URL is rejected with a clear message.
    • Removing a link switches the button to "Find in inventory", and saving one switches it back.
    • The phone header fits at 390 px.
  • flake8 and bandit are clean, and ESLint reports 0 errors.

Screenshots are in the comments.

🤖 Generated with Claude Code

## What changes **Inventory links.** Device pages get a 📦 button: - With a linked record, it opens the device's record in the inventory. - Without one, it searches the inventory for the device's model. - Admins set or clear the link with ✎ by pasting the record's URL. Only `https://` URLs on `inventory.base_url` are accepted, which rules out other hosts, lookalike hosts, embedded credentials and `javascript:` URLs, since the link is shown to every viewer. - Links are stored in a new `device_links` table, created alongside the cutsheet tables. - `PUT /api/device/<name>/inventory` requires admin rights and a JSON body. - Tickets now include the inventory link when one is set. **Cutsheet marks on faceplates.** A port with a documented cable gets a corner dot: - **green**: it matches what Gandalf sees - **red**: a mismatch (wrong neighbor, no link, missing port, or port conflict) - **grey**: documented but not confirmable (planned, dark, through a panel, or the far end isn't visible) Hovering a port names the cable and the check result. The legend shows a key for the dots plus a "Cutsheet marks" checkbox that hides them; the browser remembers the choice. The data comes from what `/api/device` already returns, so no new API calls are made. **Page titles.** `base.html` already appended "— GANDALF", and every page added "– GANDALF" again, so tabs read "Alert History – GANDALF — GANDALF". Each title now has the name once, and a test covers it. **Config:** `inventory.base_url` (default `https://inventory.lotusguild.org`) and `inventory.search_url` (default `{base}/items?q={q}`). I couldn't confirm HomeBox's search route from here because it's behind Authelia. If "Find in inventory" opens the wrong page, set `inventory.search_url`. ## Testing - **Automated:** 339 tests pass (14 new). They cover the inventory link's validation and auth, the configured host, the device API fields, the ticket link, and the page titles. - **Local MariaDB:** `device_links` table creation can run twice safely. Insert, update and clear all work. - **Playwright:** - The page shows 6 marks: 1 green, 2 red and 3 grey, as expected for the seeded cables. - The port tooltip names the cable. - The marks toggle survives a reload. - A bad URL is rejected with a clear message. - Removing a link switches the button to "Find in inventory", and saving one switches it back. - The phone header fits at 390 px. - flake8 and bandit are clean, and ESLint reports 0 errors. Screenshots are in the comments. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jared added 1 commit 2026-11-10 20:47:26 -05:00
Inventory links, cutsheet marks on faceplates, and single page titles
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
c262e5ecc8
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>
jared referenced this issue from a commit 2026-11-10 20:47:43 -05:00
Author
Owner

Screenshots (local preview, sample data)

Faceplate with cutsheet marks. Port 9 is green: its documented cable matches. Ports 10 and 12 are red: on 12 a different host is plugged in, and on 10 the planned device isn't linked. Ports 3, 6 and 15 are grey: two run through the patch panel to wall jacks, and one is still planned. The legend has the key and the toggle.

Faceplate

Device header with a linked inventory record. The ✎ button is admin-only.

Header

Inventory link editor, after trying a URL on another host, which was rejected.

Editor

Phone (390 px).

Mobile header

## Screenshots (local preview, sample data) **Faceplate with cutsheet marks.** Port 9 is green: its documented cable matches. Ports 10 and 12 are red: on 12 a different host is plugged in, and on 10 the planned device isn't linked. Ports 3, 6 and 15 are grey: two run through the patch panel to wall jacks, and one is still planned. The legend has the key and the toggle. ![Faceplate](https://code.lotusguild.org/LotusGuild/gandalf/raw/branch/pr-22-screenshots/2-faceplate.png) **Device header with a linked inventory record.** The ✎ button is admin-only. ![Header](https://code.lotusguild.org/LotusGuild/gandalf/raw/branch/pr-22-screenshots/1-header.png) **Inventory link editor**, after trying a URL on another host, which was rejected. ![Editor](https://code.lotusguild.org/LotusGuild/gandalf/raw/branch/pr-22-screenshots/3-editor.png) **Phone (390 px).** ![Mobile header](https://code.lotusguild.org/LotusGuild/gandalf/raw/branch/pr-22-screenshots/4-mobile-header.png)
jared merged commit ee2708dccb into main 2026-11-10 20:50:27 -05:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/gandalf#22