feat(alerts): Steward's own confirm dialog, a verdict-first rules list, and a rule page in three sections (#5314, #5315, #5317)
Confirm dialog (#5314): - Every data-confirm form now asks in one native <dialog> (base.html + static/confirm.js) instead of window.confirm. - The question becomes the heading and what follows it the detail; the act's button is named after the form's own button; Cancel has the focus and Esc backs out. Optional data-confirm-title/-detail/-action/-dismiss attributes. - All 27 existing uses work as they are. Cancelling a run says 'Keep running'. Alerts list (#5315): - A verdict line (what is firing, how many rules, where notifications go, or 'notifies nobody yet' with a link) replaces the empty Active card. - Each rule's name opens it; rows show 'last fired' and fold fire/clear into the condition; History and Disable stay; Delete leaves the list. - .docker-verdict becomes the shared .page-verdict. Rule page (#5317): - Named for the rule (title and crumb), with when it last fired and how many changes of state it holds. - Three sections: what it watches, when it fires (checks side by side, seconds echoed as a duration), what happens (where notifications go, no-data, the playbook, whose fields stay folded until ticked). - Delete at the foot, behind the dialog, saying its history goes with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,13 +10,6 @@
|
||||
document.addEventListener('htmx:configRequest', function (ev) {
|
||||
ev.detail.headers['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').content;
|
||||
});
|
||||
// A form (or its submit button) with data-confirm="…" asks before it
|
||||
// submits. The prompt is attribute text read through dataset, never
|
||||
// parsed as JavaScript, so a name inside it cannot run as script (#5099).
|
||||
document.addEventListener('submit', function (ev) {
|
||||
var ask = (ev.submitter && ev.submitter.dataset.confirm) || ev.target.dataset.confirm;
|
||||
if (ask && !window.confirm(ask)) { ev.preventDefault(); ev.stopPropagation(); }
|
||||
}, true);
|
||||
</script>
|
||||
<title>{% block title %}Steward{% endblock %}</title>
|
||||
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='logo/steward-mark.svg') }}">
|
||||
@@ -28,6 +21,8 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='steward.css') }}">
|
||||
<script src="{{ url_for('static', filename='chart-colors.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='scroll-more.js') }}" defer></script>
|
||||
{# A form with data-confirm="…" asks in #confirm-dialog below before it submits (#5314). #}
|
||||
<script src="{{ url_for('static', filename='confirm.js') }}" defer></script>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
@@ -167,6 +162,19 @@ document.addEventListener('keydown', function (e) {
|
||||
<div class="nav-scrim" onclick="setNavOpen(false)"></div>
|
||||
{% endif %}
|
||||
|
||||
{# Steward's own confirm dialog (#5314): static/confirm.js fills it from the
|
||||
data-confirm attributes of the form being submitted. Cancel has the focus. #}
|
||||
<dialog id="confirm-dialog" class="modal modal-confirm" aria-labelledby="confirm-dialog-title" aria-describedby="confirm-dialog-detail">
|
||||
<form method="dialog">
|
||||
<h2 id="confirm-dialog-title" class="modal-title" data-part="title"></h2>
|
||||
<p id="confirm-dialog-detail" class="confirm-detail" data-part="detail"></p>
|
||||
<div class="modal-actions">
|
||||
<button type="submit" class="btn btn-sm btn-ghost" value="back" data-part="back" autofocus>Cancel</button>
|
||||
<button type="submit" class="btn btn-sm btn-danger" value="go" data-part="go">Continue</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user