Webapp redesign: fixes from the functional regression test
- Unattend: a command's '...' menu stayed open after Move up/down and covered the next row's menu, so the next click could stage removing the wrong command. The menu now closes and focus returns to its button. - '...' menus close on an outside click, on Escape and when another opens (static/app.js), for every page. - Drivers: Remove asks to confirm again, as before the redesign. Long zip paths in a row body wrap (the page scrolled sideways at 390 px). - Rollback review returns to the page it was opened from (Dell page or Updates overview), for both Cancel and the rollback itself. - To-do: the ServiceNow period offers a year again (366 days). - Imaging floor: a search that matches a log-only bay opens that group; its open state survives the live refresh. 'Clear all' states the number of session files it deletes, hidden finished ones included. - Dashboard: the image key pattern is valid under the browser's v flag (client-side validation was silently skipped). - Import: allowed_import_source() compares real paths, so '<upload dir>/../..' is refused. This path traversal predates the redesign; the import moves the source tree, so it mattered.
This commit is contained in:
@@ -494,3 +494,19 @@ document.addEventListener('click', function (e) {
|
||||
document.body.removeChild(ta);
|
||||
done(ok);
|
||||
});
|
||||
|
||||
// "..." menus (details.more): close on a click outside, on Escape, and when
|
||||
// another one opens, so an open menu never covers the next row's controls.
|
||||
document.addEventListener('click', function (e) {
|
||||
document.querySelectorAll('details.more[open]').forEach(function (d) {
|
||||
if (!d.contains(e.target)) d.open = false;
|
||||
});
|
||||
});
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key !== 'Escape') return;
|
||||
document.querySelectorAll('details.more[open]').forEach(function (d) {
|
||||
d.open = false;
|
||||
var s = d.querySelector('summary');
|
||||
if (s && d.contains(document.activeElement)) s.focus();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -244,14 +244,17 @@
|
||||
if (btn.classList.contains('una-add')) { addRow(btn.getAttribute('data-list')); return; }
|
||||
var row = btn.closest('.una-row, .una-simple');
|
||||
var name = listName(row);
|
||||
// Close the row's menu first: left open it covers the next row's menu.
|
||||
var menu = btn.closest('details.more');
|
||||
if (menu) menu.open = false;
|
||||
if (btn.classList.contains('una-remove')) {
|
||||
row.remove();
|
||||
} else if (btn.classList.contains('una-up') && row.previousElementSibling) {
|
||||
row.parentNode.insertBefore(row, row.previousElementSibling);
|
||||
btn.focus();
|
||||
if (menu) menu.querySelector('summary').focus();
|
||||
} else if (btn.classList.contains('una-down') && row.nextElementSibling) {
|
||||
row.parentNode.insertBefore(row.nextElementSibling, row);
|
||||
btn.focus();
|
||||
if (menu) menu.querySelector('summary').focus();
|
||||
}
|
||||
afterChange(name);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user