Files
FabledSteward/steward/templates/_anomaly_card.html
T
bvandeusenandClaude Opus 5.5 c38fd68e48
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m38s
CI / integration (push) Successful in 2m0s
CI / publish (push) Successful in 1m10s
feat(ui): a host's "Full metrics" heads its page, and a resource's anomalies are one line with a way to review them (#6797)
The host page's link to the full metrics sat in the Agent card, under the
anomaly card and the vitals strip, and was missed. It now heads the vitals
strip at the top of the page.

The anomaly card on the host, monitor, container and Traefik pages listed
every anomaly of the last 30 days with its review form, reviewed ones
included, and took over the top of the page. It is now one line: how many
wait for review, which are out of their normal now, and a Review button to
Alerts → Anomalies narrowed to that resource (?source=&resource=), where a
review returns. It is hidden when nothing waits and nothing is going on.
The callers fetch up to 100 rows so the count isn't capped at 10 or 20.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 14:09:18 -05:00

32 lines
1.7 KiB
HTML

{# A resource's metric anomalies, for its own page: one line saying how many
wait for review and which are out of their normal now, with a button to
Alerts → Anomalies narrowed to this resource, where they are reviewed.
`anomalies` are anomalies.views() rows; `base_resource` is the page's
resource (none for a page covering a whole source, like Traefik). Shown
only while one waits for review or is going on. #}
{% if anomalies %}
{% set waiting = anomalies | selectattr("anomaly.review", "equalto", "to_review") | list %}
{% set going = anomalies | selectattr("ongoing") | rejectattr("anomaly.review", "equalto", "normal") | list %}
{% if waiting or going %}
{% set q = {"source": anomalies[0].anomaly.source_module} %}
{% if base_resource %}{% set _ = q.update({"resource": base_resource}) %}{% endif %}
<section class="card{% if going %} problem-card{% endif %}" aria-labelledby="resource-anomalies"
style="margin-bottom:1rem;display:flex;align-items:center;gap:0.5rem 1rem;flex-wrap:wrap;">
<h2 id="resource-anomalies" class="section-title" style="margin:0;">
{% if going %}Out of its normal now{% else %}Metric anomalies{% endif %}
</h2>
<span style="font-size:0.85rem;">
{%- if going -%}
{%- for v in going -%}
{%- if v.anomaly.resource_name != base_resource %}{{ v.anomaly.resource_name }} {% endif -%}
{{ metric_label(v.anomaly.metric_name) }}{{ ", " if not loop.last }}
{%- endfor -%}
{%- if waiting %} · {% endif -%}
{%- endif -%}
{%- if waiting %}<strong>{{ waiting|length }}</strong> to review{% endif -%}
</span>
<a class="btn btn-sm" style="margin-left:auto;" href="/alerts/anomalies?{{ q|urlencode }}">Review</a>
</section>
{% endif %}
{% endif %}