diff --git a/steward/static/steward.css b/steward/static/steward.css index 45a9077..a7459cc 100644 --- a/steward/static/steward.css +++ b/steward/static/steward.css @@ -210,6 +210,12 @@ strong, b, th { font-weight: 500; } /* The Docker page's one-line answer, above its tiles (#5298). */ .page-verdict { margin: 0 0 0.75rem; font-size: 0.95rem; } .table tr.row-off > td { opacity: 0.55; } +/* A row that opens as a whole: its one .row-target link stretches over the + row, and the actions cell sits above it so its buttons keep their own + clicks. One real link per row, so keyboard and screen readers meet it once. */ +.table tr.row-link { position: relative; cursor: pointer; } +.table tr.row-link .row-target::after { content: ""; position: absolute; inset: 0; } +.table tr.row-link .td-actions { position: relative; z-index: 1; cursor: auto; } .table td.nowrap { white-space: nowrap; } .cell-note { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.2rem; } /* An alert episode's own transitions, folded under it (#5316). */ diff --git a/steward/templates/alerts/list.html b/steward/templates/alerts/list.html index f04e4d8..27ac079 100644 --- a/steward/templates/alerts/list.html +++ b/steward/templates/alerts/list.html @@ -1,7 +1,8 @@ {# alerts/list.html — the Alerts page (#5315): the verdict and what is active (alerts/_active.html, polled), then every rule: what it is doing now and - when it last fired, what it fires on, and its History and Disable. A rule's - name opens it; deleting one is on its own page, behind the confirm dialog. #} + 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. #} {% extends "base.html" %} {% block title %}Alerts — Steward{% endblock %} {% from "_macros.html" import page_header, status_badge, empty_state %} @@ -36,9 +37,9 @@ {% for rule in rules %} {% set fired = (last_fired or {}).get(rule.id) %} - + - {{ rule.name }} + {{ rule.name }}
{{ source_label(rule.source_module) }}
diff --git a/tests/core/test_alerts_page.py b/tests/core/test_alerts_page.py index 14b7bba..b94c4d3 100644 --- a/tests/core/test_alerts_page.py +++ b/tests/core/test_alerts_page.py @@ -86,6 +86,10 @@ async def test_an_operator_sees_the_sentence_linked_and_can_acknowledge(app): assert 'Firing' in page assert 'action="/alerts/r1/acknowledge"' in page assert 'href="/alerts/rules/new"' in page and 'href="/alerts/rules/r1/edit"' in page + # The whole row opens the rule: one stretched link, the row marked for it. + row = page[page.index('")] + assert row.count('class="row-target"') == 1 and 'class="row-target" href="/alerts/rules/r1/edit"' in row assert 'action="/alerts/rules/r1/delete"' not in page # deleting a rule is the admin's main = page[page.index("Rules"):] assert 'Firing' in rules assert 'title="Within its threshold">quiet' in rules - assert 'off' in rules and 'class="row-off"' in rules + assert 'off' in rules and 'class="row-link row-off"' in rules assert 'hx-get="/alerts/active"' in page