diff --git a/app-profiles/research-dashboard/src/components/dashboards/DashboardMapPanel.vue b/app-profiles/research-dashboard/src/components/dashboards/DashboardMapPanel.vue index d66a9d407..7f51fa428 100644 --- a/app-profiles/research-dashboard/src/components/dashboards/DashboardMapPanel.vue +++ b/app-profiles/research-dashboard/src/components/dashboards/DashboardMapPanel.vue @@ -53,6 +53,7 @@ let added = false // container calls map.resize() on ANY container-size change, so the canvas always fills its cell. // General-correct (not table-specific): also covers window/rail/facet reflow. rAF-coalesced. let containerRO = null +let offToggleTable = null let _resizeRaf = 0 function scheduleMapResize() { if (_resizeRaf) return @@ -209,8 +210,16 @@ onMounted(async () => { containerRO = new ResizeObserver(scheduleMapResize) containerRO.observe(mapContainer.value) } + // Belt-and-suspenders: the RO observes the container, but when the table cell toggles + // display:none (v-show) the grid reflow can land a frame before the observer notices, so + // the 1fr map row grows without the canvas following → the reported gray gap. Resize + // explicitly the moment collapse state flips (rAF now + one delayed pass for the settle). + if (bus && typeof bus.on === 'function') { + offToggleTable = bus.on('toggleTable', () => { scheduleMapResize(); setTimeout(scheduleMapResize, 280) }) + } }) onBeforeUnmount(() => { + try { offToggleTable && offToggleTable() } catch (_) {} offToggleTable = null if (containerRO) { try { containerRO.disconnect() } catch (_) {} containerRO = null } if (_resizeRaf) { cancelAnimationFrame(_resizeRaf); _resizeRaf = 0 } try { destroy && destroy() } catch (_) {} diff --git a/layouts/app-wrapper-material/index.html b/layouts/app-wrapper-material/index.html index 3f37f8b7d..202f7c2bf 100644 --- a/layouts/app-wrapper-material/index.html +++ b/layouts/app-wrapper-material/index.html @@ -675,11 +675,15 @@ function rowHTML(n, cur){ } function drawSide(){ let h = '' + // The `sep` is a divider BETWEEN groups — the first group must not carry a + // leading one (a rule under the header with nothing above it to divide). + let firstGroup = true for (const n of tree){ - if (n.kind === 'item'){ h += rowHTML(n, active); continue } + if (n.kind === 'item'){ h += rowHTML(n, active); firstGroup = false; continue } if (n.kind === 'section'){ - h += `
-
${icon(n.icon)}${n.label}
` + if (!firstGroup) h += '
' + h += `
${icon(n.icon)}${n.label}
` + firstGroup = false // A section's children may be plain items OR a nested 'subgroup' // (e.g. Laborer Mobilization > Research > Research Map). for (const c of n.children){ @@ -694,8 +698,9 @@ function drawSide(){ } if (n.kind === 'folder'){ const o = open.get(n.id) - h += `
-