[fix](trx-frontend-http): fix map and statistics tabs requiring refresh to show data
Move template cloning into navigateToTab() so deferred <template> content is materialized before any tab-specific initialization runs. Previously the document-level template cloner fired after navigateToTab due to event propagation order, causing initAprsMap() and scheduleStatsRender() to target elements that did not yet exist. Also defer statistics control wiring until the first render so event listeners are attached after the template is cloned. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -4444,7 +4444,14 @@ function navigateToTab(name, options = {}) {
|
|||||||
document.querySelectorAll(".tab-bar .tab").forEach((t) => t.classList.remove("active"));
|
document.querySelectorAll(".tab-bar .tab").forEach((t) => t.classList.remove("active"));
|
||||||
btn.classList.add("active");
|
btn.classList.add("active");
|
||||||
document.querySelectorAll(".tab-panel").forEach((p) => p.style.display = "none");
|
document.querySelectorAll(".tab-panel").forEach((p) => p.style.display = "none");
|
||||||
document.getElementById(`tab-${name}`).style.display = "";
|
const panel = document.getElementById(`tab-${name}`);
|
||||||
|
panel.style.display = "";
|
||||||
|
// Clone deferred <template> content into the panel before any tab-specific init.
|
||||||
|
const tmpl = panel.querySelector("template");
|
||||||
|
if (tmpl) {
|
||||||
|
panel.appendChild(tmpl.content.cloneNode(true));
|
||||||
|
tmpl.remove();
|
||||||
|
}
|
||||||
if (updateHistory) {
|
if (updateHistory) {
|
||||||
updateTabHistory(name, replaceHistory);
|
updateTabHistory(name, replaceHistory);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1655,21 +1655,7 @@
|
|||||||
window.loadPluginsForTab = loadPlugins;
|
window.loadPluginsForTab = loadPlugins;
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<!-- Template cloning is handled by navigateToTab() in app.js -->
|
||||||
(function() {
|
|
||||||
document.addEventListener('click', function(e) {
|
|
||||||
var tab = e.target.closest('[data-tab]');
|
|
||||||
if (!tab) return;
|
|
||||||
var panel = document.getElementById('tab-' + tab.dataset.tab);
|
|
||||||
if (!panel) return;
|
|
||||||
var tmpl = panel.querySelector('template');
|
|
||||||
if (tmpl) {
|
|
||||||
panel.appendChild(tmpl.content.cloneNode(true));
|
|
||||||
tmpl.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<script defer src="/vendor/leaflet.js"></script>
|
<script defer src="/vendor/leaflet.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3178,11 +3178,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _statsRenderPending = false;
|
let _statsRenderPending = false;
|
||||||
|
let _statsControlsWired = false;
|
||||||
|
function _wireStatsControls() {
|
||||||
|
if (_statsControlsWired) return;
|
||||||
|
const rigEl = document.getElementById("stats-rig-filter");
|
||||||
|
const histEl = document.getElementById("stats-history-limit");
|
||||||
|
if (!rigEl && !histEl) return; // template not yet cloned
|
||||||
|
_statsControlsWired = true;
|
||||||
|
if (rigEl) {
|
||||||
|
rigEl.addEventListener("change", () => {
|
||||||
|
statsRigFilter = rigEl.value;
|
||||||
|
scheduleStatsRender();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (histEl) {
|
||||||
|
histEl.value = String(statsHistoryLimitMinutes);
|
||||||
|
histEl.addEventListener("change", () => {
|
||||||
|
statsHistoryLimitMinutes = Number(histEl.value) || 1440;
|
||||||
|
scheduleStatsRender();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
function scheduleStatsRender() {
|
function scheduleStatsRender() {
|
||||||
if (_statsRenderPending) return;
|
if (_statsRenderPending) return;
|
||||||
_statsRenderPending = true;
|
_statsRenderPending = true;
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
_statsRenderPending = false;
|
_statsRenderPending = false;
|
||||||
|
_wireStatsControls();
|
||||||
renderStatsCounters();
|
renderStatsCounters();
|
||||||
renderStatsDecodeTypes();
|
renderStatsDecodeTypes();
|
||||||
renderStatsBandActivity();
|
renderStatsBandActivity();
|
||||||
@@ -3194,25 +3216,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wire up statistics panel controls
|
|
||||||
(function() {
|
|
||||||
const rigEl = document.getElementById("stats-rig-filter");
|
|
||||||
if (rigEl) {
|
|
||||||
rigEl.addEventListener("change", () => {
|
|
||||||
statsRigFilter = rigEl.value;
|
|
||||||
scheduleStatsRender();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const histEl = document.getElementById("stats-history-limit");
|
|
||||||
if (histEl) {
|
|
||||||
histEl.value = String(statsHistoryLimitMinutes);
|
|
||||||
histEl.addEventListener("change", () => {
|
|
||||||
statsHistoryLimitMinutes = Number(histEl.value) || 1440;
|
|
||||||
scheduleStatsRender();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
function buildBookmarkLocatorPopupHtml(grid, bookmarks) {
|
function buildBookmarkLocatorPopupHtml(grid, bookmarks) {
|
||||||
const list = Array.isArray(bookmarks) ? bookmarks : [];
|
const list = Array.isArray(bookmarks) ? bookmarks : [];
|
||||||
const rows = list
|
const rows = list
|
||||||
|
|||||||
Reference in New Issue
Block a user