9e4f1983f8
The full-metrics page rendered once server-side with the history query inline, so the charts blocked first paint and nothing refreshed without a reload (it reads the latest snapshot the server holds — the agent pushes ~every 30s). Split it into a shell + two HTMX fragments: - Shell (host_detail.html): header + shared time-range toggle + two containers; paints instantly. - Current state (/<id>/metrics → _host_metrics.html): identity + gauges + per-core + filesystems + interfaces/disks + temps, from the DISTINCT ON latest query. hx-trigger "load, every 15s" → live numbers at ~the agent cadence. - History charts (/<id>/charts → _host_charts.html): the 3 charts + Chart.js, from the date_bin history query. hx-trigger "load, every 60s, rangeChange" so they lazy-load (never block paint), refresh slowly, and follow the range selector. Leak-safe: previous Chart instances are destroyed before re-render. - Range toggle switched from full-reload links to the shared _time_range.html (setTimeRange + rangeChange), so only the fragments refetch. - routes: host_detail (shell) + host_detail_metrics + host_detail_charts, with a _split_host_metrics helper. - tests/test_templates_parse.py now also parses plugin templates (these fragments aren't rendered in the unit lane). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Jg27rgypiW2efULXJDtMC
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
"""Syntax-parse every first-party template so a broken tag fails the unit lane.
|
|
|
|
The app only renders a handful of templates in unit tests (e.g. the login page),
|
|
so a Jinja syntax error elsewhere would otherwise ship green. env.parse() checks
|
|
syntax without resolving extends/includes/imports — enough to catch an unbalanced
|
|
or mistyped tag across the whole template tree (e.g. the base.html layout).
|
|
"""
|
|
import pathlib
|
|
|
|
import jinja2
|
|
|
|
import steward
|
|
|
|
_REPO = pathlib.Path(steward.__file__).parent.parent
|
|
_CORE_TEMPLATES = _REPO / "steward" / "templates"
|
|
_PLUGINS = _REPO / "plugins"
|
|
|
|
|
|
def test_all_steward_templates_parse():
|
|
env = jinja2.Environment()
|
|
files = sorted(_CORE_TEMPLATES.rglob("*.html"))
|
|
assert files, "no steward templates found"
|
|
for f in files:
|
|
env.parse(f.read_text()) # raises TemplateSyntaxError on a bad tag
|
|
|
|
|
|
def test_all_plugin_templates_parse():
|
|
# First-party plugins ship templates too (host_agent fragments, docker, …);
|
|
# they aren't rendered in the unit lane, so parse them here to catch a bad tag.
|
|
env = jinja2.Environment()
|
|
files = sorted(_PLUGINS.rglob("templates/**/*.html"))
|
|
assert files, "no plugin templates found"
|
|
for f in files:
|
|
env.parse(f.read_text())
|