MakerFLOSS/notes/dev/specs/2026-06-24-rack-presentation-design.md

137 lines
6.6 KiB
Markdown
Raw Normal View History

# Rack Presentation Improvements Design
**Date:** 2026-06-24
**Status:** Approved
**Parent spec:** `notes/dev/specs/2026-06-24-rack-documentation-design.md` (extension)
## Goal
Improve the graphical presentation of the generated rack page: make the
elevation **interactive** (inline SVG, clickable boxes, hover tooltips), encode
device **status** visually, add a **legend**, and **polish** both the elevation
and the mermaid power/network graphs. No new data is modelled; this is a
rendering upgrade of what `gen_rack.py` already produces.
## Context
- `render_svg` writes a standalone `rack01-elevation.svg`, embedded in
`rack01.md` as `![Rack rack01 elevation](rack01-elevation.svg)` — i.e. an
`<img>`, which is a **flat image**: links and tooltips inside it do not work.
- `render_power`/`render_network` emit default-themed mermaid flowcharts with
uncoloured, non-clickable nodes.
- The occupancy table already links to host pages; the SVG and graphs do not.
- `md_in_html` is enabled in `mkdocs.yml`, so raw inline HTML/SVG in a Markdown
page is rendered. Mermaid is enabled (Phase 2).
- `use_directory_urls` is unset → defaults to **true**: pages build to
`/<path>/index.html`, so a host page is served at `/hardware/<host>/` and the
rack page at `/infrastructure/racks/rack01/`. The site is served at the domain
root (`docs.makerfloss.eu`).
- `KIND_COLORS` already maps kinds → fill colours. There is no status encoding,
legend, link, or tooltip today.
## Decisions
### A. Inline, interactive elevation
- `render_page` embeds the SVG markup **inline** in `rack01.md`, inside a
`<div class="rack-elevation"> … </div>` block, replacing the
`![…](rack01-elevation.svg)` image line. (`md_in_html` passes the raw block
through.)
- The standalone `rack01-elevation.svg` is **still generated** (identical markup,
still drift-checked) and offered below the diagram as a
`[Download SVG](rack01-elevation.svg)` link.
- The `<svg>` opening tag gains `style="max-width:100%;height:auto"` so it scales
on narrow screens.
- **Clickable boxes:** every device drawing (rail box, shelf-occupant box, 0U
rail bar, shelf strip) is wrapped in
`<a href="/hardware/<hostname>/"> … </a>`. URLs are **root-relative final
URLs** — mkdocs does **not** rewrite `.md`/source-relative hrefs inside raw
inline SVG, and `use_directory_urls` + domain-root hosting make
`/hardware/<host>/` correct and robust.
- **Tooltips:** the `<a>` wrapper's first child is an SVG `<title>` carrying full
details: `"<hostname> · <kind> · <status> · cluster: <cluster|—> · <placement>"`,
where `<placement>` is the U-range (rail item), `0U <left|right>` (0U rail), or
`<shelf>/<face>/slot <slot>` (mounted item). Text run through `_esc`.
### B. Status encoded as border
Fill stays the kind colour; the box **border** encodes `status` via a
`_status_stroke(status) -> (stroke, stroke_width, dash)` helper:
| status | stroke | width | dash |
|--------|--------|-------|------|
| in-use | `#333` | 1.5 | none |
| staging | `#333` | 1.5 | `4 2` (dashed) |
| broken | `#e15759` | 3 | none |
| spare | `#bbbbbb` | 1.5 | none |
| donated | `#bbbbbb` | 1.5 | none |
| (other/missing) | `#333` | 1.5 | none |
Applied to every device rect (rail `draw_device` and shelf-occupant boxes). The
shelf strip and the faint empty-U slots keep their existing styling.
### C. Legend
A legend strip is drawn at the **bottom of the SVG canvas**, below the columns;
the canvas height grows by a fixed `LEGEND_H` band:
- **Kind swatches:** for each `kind` actually present in the rack (sorted), a
small colour rect + the kind name.
- **Status key:** four small sample borders (solid, dashed, red-thick, grey) with
labels `in-use`, `staging`, `broken`, `spare`.
### D. Aesthetic polish
- **U-numbers in both gutters:** the existing left-gutter U-number column is
mirrored to the right of the rear column.
- **Column frame:** a thin outer stroke rectangle around each column's full body
(front and rear).
- **Mermaid graphs** (`render_power`/`render_network`):
- **Colour nodes by kind:** emit a `style <id> fill:<kind-colour>,stroke:#333,color:#ffffff`
line per node, looking the kind up from the rack items (`KIND_COLORS`,
falling back to `DEFAULT_COLOR`).
- **Clickable nodes:** emit `click <id> "/hardware/<host>/"` for every node whose
hostname resolves to a rack item; off-rack nodes get no click.
- Edge labels and layout are unchanged.
## Technical constraints (rationale carried into implementation)
- `<img>`-embedded SVG is inert → inlining is required for links/tooltips.
- mkdocs rewrites Markdown `.md` links but **not** raw `href`/`click` URLs inside
inline SVG or mermaid → emit final root-relative URLs `/hardware/<host>/`.
- `md_in_html` (already enabled) renders the raw `<div><svg>…</svg></div>` block.
## Integration
| File | Change |
|------|--------|
| `scripts/gen_rack.py` | helpers `_host_url`, `_status_stroke`, `_tooltip`; `render_svg` (status borders, `<a>`+`<title>` wrapping, both-gutter U-numbers, column frame, legend, `style=` on `<svg>`); `render_page` (inline SVG `<div>` + download link); `render_power`/`render_network` (per-node `style` + `click`) |
| `tests/test_gen_rack.py` | assertions for links, titles, status strokes, legend, both-gutter numbers, inline page block, mermaid style/click |
| `docs/infrastructure/racks/rack01.md`, `rack01-elevation.svg` | regenerated |
No `mkdocs.yml`, `Makefile`, `.forgejo/workflows/docs.yml`, or
`overview_config.yml` changes. Occupancy table and all validation unchanged.
## Test plan
- **`render_svg`:** output contains `<a href="/hardware/srv04/"`, a `<title>` with
the host details, a dashed stroke for a `staging` fixture and a thick red stroke
for a `broken` fixture, kind swatches for the kinds present, U-number text on
both sides; deterministic for reordered input.
- **`render_page`:** contains `<div class="rack-elevation">` and `<svg`, the
`[Download SVG](rack01-elevation.svg)` link, and **no** `![`-image embed of the
elevation.
- **`render_power`/`render_network`:** contain `style <id> fill:` lines coloured
by kind and `click <id> "/hardware/<host>/"` lines; still start with
` ```mermaid ` + `flowchart LR`.
- **Drift / build / visual:** `make docs-check` exits 0; `mkdocs build --strict`
passes; on the rendered page the elevation boxes are clickable, hovering shows
the tooltip, the legend is visible, and the mermaid nodes are coloured and
clickable.
## Out of scope
- The summary dashboard (U-utilisation / counts) — not selected.
- Dark-mode-specific palettes.
- A cluster colour system — cluster appears in the tooltip only.