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

6.6 KiB

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.