{% extends "ui/_layout.html" %}
{% from "ui/_table_macros.html" import sort_header, pagination_inline with context %}
{% block title %}Machines - bty-web{% endblock %}
{% block subnav %}
{# Left: in-page jump links (List | Activity).
Right: the inline add-by-MAC action, moved here from the card
header so the page-level "create a new machine" action lives in
the page chrome and the card-body stays focused on the data
table. The form's id + JS submit are unchanged so the existing
upsert handler + the inline-add tests keep working. #}
{% endblock %}
{% block intro %}
{% from "ui/_intro_box.html" import render as intro_box %}
{% call intro_box() %}
Machines auto-appear on first remote contact (PXE or manual
tui --server .. --mac ..); to stage one before it
boots, use the Add field in the table header
(image binding + boot mode are set per-machine on the detail
page).
{% endcall %}
{% endblock %}
{% block content %}
{# Post-delete flash banner. A non-trivial action (delete a machine
record) deserves operator feedback whether or not the row
actually existed. ``?deleted=`` after a real removal;
``?missing=`` when the row was already gone (stale tab,
re-clicked delete). Auto-dismiss after 5 seconds via the
bootstrap data-bs-dismiss + setTimeout below. #}
{% if flash_deleted %}
Deleted machine {{ flash_deleted }}.
{% elif flash_missing %}
Machine {{ flash_missing }} was not found (already deleted, or never bound).
{% endif %}
{% if flash_deleted or flash_missing %}
{% endif %}
{# The live table of all machines, with a minimal inline add-by-MAC
field in the header. Machines also auto-appear on first PXE
contact; the inline Add just stages a row early. #}
{# Card header: "Machines | Filter: " flexes
to fill the left side; pagination sits on the right. The
Add-MAC action moved into the subnav strip; this card
stays focused on the data view. #}
{# Column order is identity (MAC, Labels) -> configuration
(Image, Boot) -> timeline (Last seen, Last IP, Last
flashed) -> actions. Narrow columns get width:1% +
nowrap so they stay tight and only MAC / Labels /
Image absorb the slack. Labels is unsortable -- a
machine carries a SET of tags, "sort by labels" has
no natural meaning when each row has several. #}
{# The tbody subscribes to the SSE stream so it auto-updates
when the operator (or auto-discovery) mutates machines.
The browser carries the bty-token cookie automatically;
that is what authenticates the EventSource connection.
``sse-target`` opts in to the layout-level flash animation.
When a server-side filter is active (``?filter=...``)
the SSE wiring is dropped: the next ``machines-update``
would replace the filtered tbody with the full
un-filtered list, which is operator-confusing. The page
becomes static under filter; reload to refresh. #}
{% include "ui/_machines_tbody.html" %}