From 86952cc0dee37d5cd027e24a9c98c3889fd39754 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 18 Sep 2026 19:04:04 -0400 Subject: [PATCH] fix: give the log panel its own strings refs #5147 The panel's messages came from the global translate object that views/js/log.js.php defined, which the footer only loads for the Log view. On any other view Clear Logs threw "translate is not defined" out of deleteLogs() before it sent anything, and a failed table query would have thrown the same way. Carry the five strings on the panel element as data-i18n and read them in initLogPanel(), so a panel is self-contained wherever it is embedded. views/js/log.js.php held nothing else, so it goes. Co-Authored-By: Claude Opus 5 (1M context) --- web/skins/classic/includes/logpanel.php | 10 +++++++++- web/skins/classic/js/logpanel.js | 8 +++++--- web/skins/classic/views/js/log.js.php | 8 -------- 3 files changed, 14 insertions(+), 12 deletions(-) delete mode 100644 web/skins/classic/views/js/log.js.php diff --git a/web/skins/classic/includes/logpanel.php b/web/skins/classic/includes/logpanel.php index 5b8512250..e365e58e2 100644 --- a/web/skins/classic/includes/logpanel.php +++ b/web/skins/classic/includes/logpanel.php @@ -67,9 +67,17 @@ function getLogPanelHTML($options=array()) { $levels[$level] = $level; } + # The panel is loaded on every view, so it cannot rely on a per-view + # views/js/.js.php defining a translate object. Carry its own strings. + $strings = array(); + foreach (array('Reason', 'AJAXRequestError', 'ErrorUpdatingLogTable', + 'ErrorDeletingRowFromLogTable', 'DeletingRowsFromTable') as $string) { + $strings[$string] = translate($string); + } + ob_start(); ?> -
+
 -   -  diff --git a/web/skins/classic/js/logpanel.js b/web/skins/classic/js/logpanel.js index c7d6d25b4..bdcfe75c8 100644 --- a/web/skins/classic/js/logpanel.js +++ b/web/skins/classic/js/logpanel.js @@ -37,6 +37,8 @@ function initLogPanel(panel) { // A panel locked to a set of components queries only those and never writes // the user's Log view selection back to the session. const lockedComponents = panel.dataset.components ? JSON.parse(panel.dataset.components) : null; + // The panel's own strings; a view's views/js/.js.php is not loaded here. + const i18n = panel.dataset.i18n ? JSON.parse(panel.dataset.i18n) : {}; let ajax = null; let allowRequest = false; // Allow unscheduled AJAX requests @@ -179,7 +181,7 @@ function initLogPanel(panel) { updateRequestStatus("stopped"); } else { updateRequestStatus("error"); - zmAlert(translate["Reason"] + ": " + jqxhr.statusText + "~~" + translate["ErrorUpdatingLogTable"], translate["AJAXRequestError"]); + zmAlert(i18n["Reason"] + ": " + jqxhr.statusText + "~~" + i18n["ErrorUpdatingLogTable"], i18n["AJAXRequestError"]); } table.bootstrapTable('hideLoading'); logAjaxFail(jqxhr); @@ -241,7 +243,7 @@ function initLogPanel(panel) { deleteProgressBar.appendChild(fill); idsLength = log_ids.length; - handlerAlert = zmAlert(translate["DeletingRowsFromTable"]); + handlerAlert = zmAlert(i18n["DeletingRowsFromTable"]); waitUntil(() => (document.querySelector('#' + handlerAlert + ' .modal-body')), 10000).then((result) => { // We're waiting for the modal information block to appear. @@ -288,7 +290,7 @@ function initLogPanel(panel) { table.bootstrapTable('refresh'); updateRequestStatus("error"); if (handlerAlert) closeZmAlert(handlerAlert); - zmAlert(translate["Reason"] + ": " + jqxhr.statusText + "~~" + translate["ErrorDeletingRowFromLogTable"], translate["AJAXRequestError"]); + zmAlert(i18n["Reason"] + ": " + jqxhr.statusText + "~~" + i18n["ErrorDeletingRowFromLogTable"], i18n["AJAXRequestError"]); } }); } diff --git a/web/skins/classic/views/js/log.js.php b/web/skins/classic/views/js/log.js.php deleted file mode 100644 index dbf3b416a..000000000 --- a/web/skins/classic/views/js/log.js.php +++ /dev/null @@ -1,8 +0,0 @@ -var translate = { - "Reason": "", - "Aborted": "", - "ErrorUpdatingLogTable": "", - "ErrorDeletingRowFromLogTable": "", - "DeletingRowsFromTable": "", - "AJAXRequestError": "", -};