feat(alerts): a covering rule's hosts fold away behind its "N hosts" (#5483)
#5483 "Alerts list: a covering rule's hosts start collapsed behind a toggle; no dashed rows", from the operator's review of the Alerts list. Each rule is its own tbody; its hosts sit in another, hidden until "N hosts" is pressed. A rule with a host that isn't quiet opens on its own and names the host where "last fired" was, so a problem never hides behind the fold. Host rows lose the dashed rules for a sunken band under the indent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
when it last fired, what it fires on, and its History and Disable. The
|
||||
whole row opens the rule (.row-link, its name is the link); deleting one is
|
||||
on its own page, behind the confirm dialog. A rule covering hosts (#5464)
|
||||
lists its per-host rules under it; each opens its history. #}
|
||||
lists its per-host rules under it, closed behind its "N hosts" toggle
|
||||
unless one of them isn't quiet (#5483); each opens its history. #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Alerts — Steward{% endblock %}
|
||||
{% from "_macros.html" import page_header, status_badge, empty_state %}
|
||||
@@ -35,22 +36,27 @@
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for rule in rules %}
|
||||
{% set kids = (children or {}).get(rule.id, []) %}
|
||||
{% set fired = (last_fired or {}).get(rule.id) %}
|
||||
{% set restless = (uneasy or {}).get(rule.id, []) %}
|
||||
<tbody>
|
||||
{% for rule in rules %}
|
||||
{% set kids = (children or {}).get(rule.id, []) %}
|
||||
{% set fired = (last_fired or {}).get(rule.id) %}
|
||||
<tr class="row-link{% if not rule.enabled %} row-off{% endif %}">
|
||||
<td class="cell-name">
|
||||
<a class="row-target" href="{{ ('/alerts/rules/' ~ rule.id ~ '/edit') if can_edit else ('/alerts/history?rule=' ~ rule.id) }}" title="{{ rule.name }}">{{ rule.name }}</a>
|
||||
<div class="cell-sub">{{ source_label(rule.source_module) }}
|
||||
{%- if rule.covers != "resource" %} · {{ kids|length }} host{{ "s" if kids|length != 1 }}{% endif %}</div>
|
||||
{%- if rule.covers != "resource" %} · <button type="button" class="row-toggle row-inner"
|
||||
aria-expanded="{{ 'true' if restless else 'false' }}" aria-controls="hosts-{{ rule.id }}"
|
||||
onclick="toggleHosts(this)">{{ kids|length }} host{{ "s" if kids|length != 1 }}</button>{% endif %}</div>
|
||||
</td>
|
||||
<td>
|
||||
{%- set now_label = (rule_state or {}).get(rule.id) %}
|
||||
{%- if not rule.enabled %}<span class="tone-dim">off</span>
|
||||
{%- elif now_label and now_label not in ('inactive', 'resolved') %}{{ status_badge(now_label) }}
|
||||
{%- else %}<span class="tone-ok" title="Within its threshold">quiet</span>{% endif -%}
|
||||
<div class="cell-sub">{% if fired %}last fired {{ fired|ago }}{% else %}never fired{% endif %}</div>
|
||||
<div class="cell-sub">
|
||||
{%- if restless %}on {{ restless|join(", ") }}
|
||||
{%- elif fired %}last fired {{ fired|ago }}{% else %}never fired{% endif %}</div>
|
||||
</td>
|
||||
<td>
|
||||
{% if rule.covers == "group" %}every host in {{ rule.cover_group }}{% elif rule.covers == "all_hosts" %}every host{% else %}{{ rule.resource_name }}{% endif %} · {{ rule_condition(rule) }}
|
||||
@@ -71,6 +77,9 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{% if kids %}
|
||||
<tbody id="hosts-{{ rule.id }}" class="row-children"{% if not restless %} hidden{% endif %}>
|
||||
{% for kid in kids %}
|
||||
{% set kid_label = (rule_state or {}).get(kid.id) %}
|
||||
{% set kid_fired = (last_fired or {}).get(kid.id) %}
|
||||
@@ -88,10 +97,19 @@
|
||||
<td class="td-actions"><a href="/alerts/history?rule={{ kid.id }}" class="btn btn-sm btn-ghost">History</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
// A covering rule's hosts (#5483): closed unless one of them isn't quiet.
|
||||
function toggleHosts(btn) {
|
||||
var open = btn.getAttribute('aria-expanded') !== 'true';
|
||||
btn.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||
document.getElementById(btn.getAttribute('aria-controls')).hidden = !open;
|
||||
}
|
||||
</script>
|
||||
{% else %}
|
||||
<div class="card">{{ empty_state("No alert rules yet.", "New rule" if can_edit else none, "/alerts/rules/new" if can_edit else none) }}</div>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user