fix(dashboard): call.js renderQuestions referenced tabs.js-only helper
renderQuestions (call.js) called snapshotOpenDetails()/restoreOpenDetails() which are closure-locals in tabs.js (built on MANAGED_SECTION_IDS) and not in call.js's module scope. On a /dashboard.html (Y3R C4LL tab) refresh this threw 'ReferenceError: snapshotOpenDetails is not defined' and aborted refreshState entirely. Give call.js its own section-scoped snapshot/restore pair operating on the questions-section root (the only section renderQuestions manages), so open <details> state still survives an SSE re-render without reaching into tabs.js internals.
This commit is contained in:
parent
86ad8bc914
commit
84077289f1
1 changed files with 23 additions and 2 deletions
|
|
@ -615,6 +615,27 @@ function buildQuestionLi(q) {
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Snapshot / restore open `<details>` state across a re-render, scoped to
|
||||||
|
// one section root. renderQuestions only manages `#questions-section`, so it
|
||||||
|
// keeps its own section-local pair rather than reaching into tabs.js's
|
||||||
|
// `MANAGED_SECTION_IDS`-based helpers (which aren't in this module's scope —
|
||||||
|
// referencing them threw `ReferenceError: snapshotOpenDetails is not defined`
|
||||||
|
// and aborted refreshState). Sections that should survive a refresh carry a
|
||||||
|
// stable `data-restore-key`.
|
||||||
|
function snapshotOpenDetails(root) {
|
||||||
|
const open = new Set();
|
||||||
|
for (const d of root.querySelectorAll('details[data-restore-key]')) {
|
||||||
|
if (d.open) open.add(d.dataset.restoreKey);
|
||||||
|
}
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
function restoreOpenDetails(root, open) {
|
||||||
|
if (!open.size) return;
|
||||||
|
for (const d of root.querySelectorAll('details[data-restore-key]')) {
|
||||||
|
if (open.has(d.dataset.restoreKey)) d.open = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function renderQuestions() {
|
export function renderQuestions() {
|
||||||
const root = $('questions-section');
|
const root = $('questions-section');
|
||||||
// #questions-section only lives on /dashboard.html (Y3R C4LL tab);
|
// #questions-section only lives on /dashboard.html (Y3R C4LL tab);
|
||||||
|
|
@ -625,7 +646,7 @@ export function renderQuestions() {
|
||||||
// any expanded sections. The keyed-cache approach reuses question
|
// any expanded sections. The keyed-cache approach reuses question
|
||||||
// <li> nodes (preserving textarea/checkbox state) and only rebuilds
|
// <li> nodes (preserving textarea/checkbox state) and only rebuilds
|
||||||
// cache-miss rows, so we no longer wipe the DOM at the start.
|
// cache-miss rows, so we no longer wipe the DOM at the start.
|
||||||
const openDetails = snapshotOpenDetails();
|
const openDetails = snapshotOpenDetails(root);
|
||||||
const fmt = (n) => new Date(n * 1000).toISOString().replace('T', ' ').slice(0, 19);
|
const fmt = (n) => new Date(n * 1000).toISOString().replace('T', ' ').slice(0, 19);
|
||||||
const allPending = questionsState.pending;
|
const allPending = questionsState.pending;
|
||||||
|
|
||||||
|
|
@ -750,7 +771,7 @@ export function renderQuestions() {
|
||||||
const histEl = root.querySelector('.q-history');
|
const histEl = root.querySelector('.q-history');
|
||||||
if (histEl) histEl.open = true;
|
if (histEl) histEl.open = true;
|
||||||
}
|
}
|
||||||
restoreOpenDetails(openDetails);
|
restoreOpenDetails(root, openDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format a remaining-seconds count as the `⏳ …` TTL chip text on a
|
// Format a remaining-seconds count as the `⏳ …` TTL chip text on a
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue