Show save/error status inside the open widget dialog, not behind it
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:
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<dialog id="widget-dialog">
|
||||
<button type="button" id="widget-dialog-close" class="icon-btn" aria-label="Close" title="Close">×</button>
|
||||
<div id="widget-dialog-body"><p class="sub">Loading...</p></div>
|
||||
<div class="dialog-result"></div>
|
||||
</dialog>
|
||||
|
||||
<div id="result"></div>
|
||||
|
||||
Reference in New Issue
Block a user