Webapp: Last 3 months evidence range, keep popovers on screen

Evidence pack gets a Last 3 months quick range (three full calendar
months). Opened menus are nudged back inside the window, so header
popovers no longer start off-screen on phones or a wrapped header.
Buttons and filter pills inside a menu keep their own styling.
This commit is contained in:
cproudlock
2026-10-14 15:12:38 -04:00
parent 2dbaaded44
commit 4db9dc093f
3 changed files with 18 additions and 2 deletions

View File

@@ -510,3 +510,17 @@ document.addEventListener('keydown', function (e) {
if (s && d.contains(document.activeElement)) s.focus(); if (s && d.contains(document.activeElement)) s.focus();
}); });
}); });
// Keep an opened menu inside the window: a right-aligned menu under a button
// near the left edge (a wrapped page header, a phone) would start off-screen.
document.addEventListener('toggle', function (e) {
var d = e.target;
if (!d.matches || !d.matches('details.more') || !d.open) return;
var m = d.querySelector('.menu');
if (!m) return;
m.style.transform = '';
var r = m.getBoundingClientRect(), pad = 8, dx = 0;
if (r.left < pad) dx = pad - r.left;
else if (r.right > window.innerWidth - pad) dx = window.innerWidth - pad - r.right;
if (dx) m.style.transform = 'translateX(' + Math.round(dx) + 'px)';
}, true);

View File

@@ -203,11 +203,11 @@ details.more .menu {
background: var(--surface); border: 1px solid var(--line-2); border-radius: 8px; box-shadow: 0 6px 18px var(--shadow); background: var(--surface); border: 1px solid var(--line-2); border-radius: 8px; box-shadow: 0 6px 18px var(--shadow);
padding: 4px; display: flex; flex-direction: column; text-align: left; padding: 4px; display: flex; flex-direction: column; text-align: left;
} }
details.more .menu a, details.more .menu button, details.more .menu form > button { details.more .menu a:not(.ui-btn):not(.fbtn), details.more .menu button:not(.ui-btn):not(.fbtn) {
display: block; width: 100%; padding: 9px 12px; border: 0; background: none; font: inherit; font-size: 13px; color: var(--text); display: block; width: 100%; padding: 9px 12px; border: 0; background: none; font: inherit; font-size: 13px; color: var(--text);
text-decoration: none; text-align: left; border-radius: 5px; cursor: pointer; white-space: nowrap; text-decoration: none; text-align: left; border-radius: 5px; cursor: pointer; white-space: nowrap;
} }
details.more .menu a:hover, details.more .menu button:hover { background: var(--surface-3); } details.more .menu a:not(.ui-btn):not(.fbtn):hover, details.more .menu button:not(.ui-btn):not(.fbtn):hover { background: var(--surface-3); }
details.more .menu .sep { height: 1px; background: var(--line); margin: 4px 0; } details.more .menu .sep { height: 1px; background: var(--line); margin: 4px 0; }
details.more .menu .del { color: var(--fail-text); } details.more .menu .del { color: var(--fail-text); }
details.more .menu [disabled] { color: var(--muted); cursor: not-allowed; } details.more .menu [disabled] { color: var(--muted); cursor: not-allowed; }

View File

@@ -73,6 +73,7 @@
</div> </div>
<div style="display: flex; gap: 6px; flex-wrap: wrap" aria-label="Quick ranges"> <div style="display: flex; gap: 6px; flex-wrap: wrap" aria-label="Quick ranges">
<button type="button" class="fbtn" data-range="last-month">Last month</button> <button type="button" class="fbtn" data-range="last-month">Last month</button>
<button type="button" class="fbtn" data-range="last-3-months">Last 3 months</button>
<button type="button" class="fbtn" data-range="this-month">This month</button> <button type="button" class="fbtn" data-range="this-month">This month</button>
<button type="button" class="fbtn" data-range="last-30">Last 30 days</button> <button type="button" class="fbtn" data-range="last-30">Last 30 days</button>
</div> </div>
@@ -208,6 +209,7 @@
b.addEventListener('click', function () { b.addEventListener('click', function () {
var now = new Date(), from, to; var now = new Date(), from, to;
if (b.dataset.range === 'last-month') { from = new Date(now.getFullYear(), now.getMonth() - 1, 1); to = new Date(now.getFullYear(), now.getMonth(), 0); } if (b.dataset.range === 'last-month') { from = new Date(now.getFullYear(), now.getMonth() - 1, 1); to = new Date(now.getFullYear(), now.getMonth(), 0); }
else if (b.dataset.range === 'last-3-months') { from = new Date(now.getFullYear(), now.getMonth() - 3, 1); to = new Date(now.getFullYear(), now.getMonth(), 0); }
else if (b.dataset.range === 'this-month') { from = new Date(now.getFullYear(), now.getMonth(), 1); to = now; } else if (b.dataset.range === 'this-month') { from = new Date(now.getFullYear(), now.getMonth(), 1); to = now; }
else { to = now; from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 29); } else { to = now; from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 29); }
document.getElementById('evidenceFrom').value = iso(from); document.getElementById('evidenceFrom').value = iso(from);