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:
cproudlock
2026-10-14 14:48:10 -04:00
parent 2bcc9d8016
commit 2ed2cbe2e9
11 changed files with 61 additions and 15 deletions

View File

@@ -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);
});