Show save/error status inside the open widget dialog, not behind it
Build and push server image / test (push) Successful in 21s
Build and push server image / build-and-push (push) Successful in 2m0s
Build and push server image / deploy (push) Successful in 54s

showStatus() always wrote to the page-level #result div, which sits
behind a <dialog>'s backdrop -- a save inside a widget's gear-icon
dialog produced a message the user couldn't see without closing the
dialog first. It now prefers a .dialog-result element inside whichever
<dialog> is currently open, falling back to #result everywhere else.

The dialog is a flex column with its body scrolling independently so
.dialog-result stays pinned as a visible footer regardless of scroll
position -- otherwise a save message on a long form (e.g. the calendar
dialog) could land off-screen below the fold with no visible feedback
at all.
This commit is contained in:
2026-07-24 14:48:50 -04:00
parent cb11ffdd2d
commit 569bf733e9
4 changed files with 19 additions and 1 deletions
+7 -1
View File
@@ -59,7 +59,13 @@
})();
function showStatus(ok, message) {
var el = document.getElementById('result');
// While a <dialog> is open, its own .dialog-result container gets the
// message instead of the page-level #result -- otherwise it lands
// behind the dialog's backdrop, invisible until the dialog closes
// (e.g. the widget config dialogs on the Layout tab, see
// frame_layout.js). Falls back to #result for everything else.
var openDialog = document.querySelector('dialog[open]');
var el = (openDialog && openDialog.querySelector('.dialog-result')) || document.getElementById('result');
if (!el) return;
el.innerHTML = '<div class="status ' + (ok ? 'ok' : 'err') + '"></div>';
el.firstChild.textContent = message;
+1
View File
@@ -274,6 +274,7 @@ async function openWidgetDialog(widget) {
const dialogEl = document.getElementById('widget-dialog');
const bodyEl = document.getElementById('widget-dialog-body');
bodyEl.innerHTML = '<p class="sub">Loading...</p>';
dialogEl.querySelector('.dialog-result').innerHTML = ''; // clear any message left over from a previous dialog
openDialogWidgetType = widget.widget_type;
dialogEl.showModal();
try {
+10
View File
@@ -402,6 +402,13 @@ button.secondary:hover { background: var(--surface-alt); }
background: var(--surface);
color: var(--text);
box-shadow: var(--shadow-hover);
/* #widget-dialog-body scrolls on its own (min-height: 0 is what lets a
flex child actually shrink/scroll instead of forcing the dialog
past max-height) so .dialog-result stays pinned as a visible footer
regardless of scroll position -- otherwise a save message can land
off-screen below a long form with no visible feedback at all. */
display: flex;
flex-direction: column;
}
#widget-dialog::backdrop { background: var(--overlay); }
#widget-dialog-close {
@@ -414,8 +421,11 @@ button.secondary:hover { background: var(--surface-alt); }
z-index: 1;
}
.dialog-title { margin: 0 40px 16px 0; font-size: 18px; }
#widget-dialog-body { overflow-y: auto; min-height: 0; }
#widget-dialog-body .card { box-shadow: none; }
#widget-dialog-body .card:first-child { margin-top: 0; }
.dialog-result { flex: none; }
.dialog-result:not(:empty) { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
code {
background: var(--surface-alt);
+1
View File
@@ -38,6 +38,7 @@
<dialog id="widget-dialog">
<button type="button" id="widget-dialog-close" class="icon-btn" aria-label="Close" title="Close">&times;</button>
<div id="widget-dialog-body"><p class="sub">Loading...</p></div>
<div class="dialog-result"></div>
</dialog>
<div id="result"></div>