fix(frontend): container-logs misuse of wireModal blocked rest of features.js
container-logs.js called `wireModal(modal, null, closeModal)` — passing
the local `closeModal()` function as a third arg where wireModal expects
button elements. wireModal then did `closeModal.addEventListener('click',...)`,
threw TypeError, and because each module's IIFE is a top-level statement
in the concatenated features.js bundle, every IIFE *after* container-logs
silently skipped: snapshot, smart-arr-connect, notification-settings,
panel-tabs, backup-restore, resource-monitor, health-check, update-
management, docker-resources, compose-import, container-exec, audit-log,
weather, clock, card-badges, theme-builder, and license. Symptoms:
"Customize Theme" did nothing on click, license badge stuck at "FREE TIER"
(because license.js never ran), no weather, etc.
- container-logs.js: drop the wireModal call, wire backdrop click directly
to the local closeModal so the SSE log stream actually stops on close.
- globals.js: harden wireModal — skip any closeBtn that isn't a real
EventTarget. One typo upstream shouldn't take down the rest of features.js
init silently.
This commit is contained in:
@@ -398,8 +398,10 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Wire modal (close on backdrop click)
|
||||
wireModal(modal, null, closeModal);
|
||||
// Wire backdrop click to closeModal so the log stream stops too.
|
||||
// (Can't use wireModal here — it only does modal.classList.remove('show')
|
||||
// on backdrop click, which would leak the SSE/stream connection.)
|
||||
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
|
||||
|
||||
// Expose for use by service card buttons (grid.js calls openContainerLogsModal)
|
||||
window.openContainerLogsModal = function(containerId, containerName) {
|
||||
|
||||
@@ -293,7 +293,15 @@ function closeModal(id) {
|
||||
function wireModal(modal, ...closeBtns) {
|
||||
if (!modal) return;
|
||||
modal.addEventListener('click', (e) => { if (e.target === modal) modal.classList.remove('show'); });
|
||||
closeBtns.forEach(btn => btn?.addEventListener('click', () => modal.classList.remove('show')));
|
||||
// Skip anything that isn't a real listener target. Without this guard, a
|
||||
// single typo (e.g. passing a function or null instead of a button element)
|
||||
// throws and aborts the rest of the calling module's init — which can take
|
||||
// down license.js (FREE TIER badge), TOTP wiring, etc.
|
||||
closeBtns.forEach(btn => {
|
||||
if (btn && typeof btn.addEventListener === 'function') {
|
||||
btn.addEventListener('click', () => modal.classList.remove('show'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Toast-style notification (replaces all alert() usage) */
|
||||
|
||||
Reference in New Issue
Block a user