From 4e3d0a1f0a12d8e2a319eec1ff89afd38aad8556 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Mon, 11 May 2026 12:58:32 -0400 Subject: [PATCH] fix: aria-required sync, aria-label pills, deduplicate setDuration logic - updateSuppressForm() now sets required + aria-required on sup-name/sup-detail when target type changes; sup-reason gets static aria-required="true" - onTypeChange() in suppressions page syncs aria-required on s-name - s-name in suppressions.html gets initial required/aria-required (default type=host) - Duration pills in both modal and suppressions page now have descriptive aria-label ("30 minutes", "1 hour", etc.) alongside the group aria-label - setDuration() in app.js accepts optional {expiresId,pillSel,hintId} opts so logic lives in one place; suppressions.html setDur() delegates to it - Post-create form reset uses setDur() instead of manually patching DOM Co-Authored-By: Claude Sonnet 4.6 --- static/app.js | 23 +++++++++++++++++++---- templates/base.html | 12 ++++++------ templates/suppressions.html | 37 ++++++++++++++----------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/static/app.js b/static/app.js index 2dfb050..2697fbf 100644 --- a/static/app.js +++ b/static/app.js @@ -294,18 +294,33 @@ function updateSuppressForm() { const type = document.getElementById('sup-type').value; const nameGrp = document.getElementById('sup-name-group'); const detailGrp = document.getElementById('sup-detail-group'); + const nameInput = document.getElementById('sup-name'); + const detailInput = document.getElementById('sup-detail'); if (nameGrp) nameGrp.style.display = (type === 'all') ? 'none' : ''; if (detailGrp) detailGrp.style.display = (type === 'interface') ? '' : 'none'; + if (nameInput) { + const req = (type !== 'all'); + nameInput.required = req; + nameInput.setAttribute('aria-required', String(req)); + } + if (detailInput) { + const req = (type === 'interface'); + detailInput.required = req; + detailInput.setAttribute('aria-required', String(req)); + } } -function setDuration(mins, el) { - document.getElementById('sup-expires').value = mins || ''; - document.querySelectorAll('#suppress-modal .pill').forEach(p => { +function setDuration(mins, el, opts) { + const o = opts || {}; + const expiresEl = document.getElementById(o.expiresId || 'sup-expires'); + const pillSel = o.pillSel || '#suppress-modal .pill'; + const hint = document.getElementById(o.hintId || 'duration-hint'); + if (expiresEl) expiresEl.value = mins || ''; + document.querySelectorAll(pillSel).forEach(p => { p.classList.remove('active'); p.setAttribute('aria-pressed', 'false'); }); if (el) { el.classList.add('active'); el.setAttribute('aria-pressed', 'true'); } - const hint = document.getElementById('duration-hint'); if (hint) { if (mins) { const h = Math.floor(mins / 60), m = mins % 60; diff --git a/templates/base.html b/templates/base.html index b142b38..9e3b700 100644 --- a/templates/base.html +++ b/templates/base.html @@ -227,16 +227,16 @@
+ placeholder="e.g. Planned switch reboot" required aria-required="true">
- - - - - + + + + +
Persists until manually removed.
diff --git a/templates/suppressions.html b/templates/suppressions.html index 7e74cf8..20b30ec 100644 --- a/templates/suppressions.html +++ b/templates/suppressions.html @@ -32,7 +32,7 @@ + required aria-required="true" list="target-name-list"> {% for name in snapshot.hosts.keys() | sort %}