diff --git a/ui/src/views/Forecast.jsx b/ui/src/views/Forecast.jsx index ce4a1d0..3e73393 100644 --- a/ui/src/views/Forecast.jsx +++ b/ui/src/views/Forecast.jsx @@ -1237,16 +1237,19 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio table.addStyleListener(() => { // The grand-total row, hidden on request. The engine has no rollup mode // for "subtotals but no grand total" -- rollup, flat and total are the - // three -- so it is dropped here instead. It is view row 0 with a row - // header blank at every level; y alone is not enough, since under flat - // rollup there is no total and row 0 is a leaf. Tagged per draw, because - // the grid recycles its tr elements as it scrolls. + // three -- so it is dropped here instead. It is view row 0, whose row + // header the datagrid fills with a label object reading "TOTAL" and + // blanks below it -- not blank throughout, which is what this first + // assumed. y alone is not enough, since under flat rollup there is no + // total and row 0 is a leaf. Tagged per draw, because the grid recycles + // its tr elements as it scrolls. for (const tr of table.querySelectorAll('tbody tr')) { const th = tr.querySelector('th') let meta try { meta = th ? table.getMeta(th) : null } catch { meta = null } - const isTotal = meta?.y === 0 && Array.isArray(meta.row_header) && - !meta.row_header.some(notBlank) + const head = meta?.row_header + const isTotal = meta?.y === 0 && Array.isArray(head) && + String(head[0]) === 'TOTAL' && !head.slice(1).some(notBlank) tr.classList.toggle('pf-total-row', isTotal && !showTotalRowRef.current) }