feat(prometheus): the widget template library: list, edit with live preview, paste in, upload, export, duplicate (#5692)
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 1m16s
CI / unit (push) Failing after 1m29s
CI / publish (push) Skipped

Prometheus gains a "Widget templates" tab beside Targets. It lists the
built-in templates and an admin's own, any that no longer pass the checker
first. A template opens as its YAML beside a live preview drawn over a
chosen target exactly as the dashboard widget draws it (routes.draw, now
shared by both). An admin writes or pastes a new one, reads a .yaml upload
into the editor to look over, duplicates any template under a free name,
edits and deletes their own; anyone can export the YAML. Built-in
templates are read-only.

Custom templates are rows in prometheus_widget_templates (migration
prometheus_002_templates), kept in backups, keyed "custom:<id>" so a
rename keeps its widgets. Saving needs a template that passes the checker
and a name no other template has. Create, update and delete are audited
and link to the template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 09:22:31 -04:00
co-authored by Claude Opus 5.5
parent 5ca13f9278
commit bd762307e0
18 changed files with 849 additions and 28 deletions
+5 -4
View File
@@ -11,7 +11,7 @@ _app: "Quart | None" = None
def setup(app: "Quart") -> None:
global _app
_app = app
from .models import PrometheusTarget # noqa: F401 — registers the table
from .models import PrometheusTarget, PrometheusWidgetTemplate # noqa: F401 — registers the tables
register_widgets()
@@ -64,6 +64,7 @@ def get_alert_metrics() -> dict[str, list[str]]:
def get_audit_entities() -> dict:
"""Audit rows about a target name it and link to its page."""
from .models import PrometheusTarget
return {"prometheus_target": (PrometheusTarget, "/plugins/prometheus/targets/{}")}
"""Audit rows about a target or a widget template name it and link to its page."""
from .models import PrometheusTarget, PrometheusWidgetTemplate
return {"prometheus_target": (PrometheusTarget, "/plugins/prometheus/targets/{}"),
"prometheus_template": (PrometheusWidgetTemplate, "/plugins/prometheus/templates/custom:{}")}