From 1631dbd2cc3cf95a7c6416ea8d9c2fdf2899a989 Mon Sep 17 00:00:00 2001 From: Paul Trowbridge Date: Tue, 14 Apr 2026 22:14:45 -0400 Subject: [PATCH] Pivot: fix slice filtering by zipping __ROW_PATH__ with group_by columns Co-Authored-By: Claude Sonnet 4.6 --- ui/src/pages/Pivot.jsx | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/ui/src/pages/Pivot.jsx b/ui/src/pages/Pivot.jsx index a4a63f1..73ee838 100644 --- a/ui/src/pages/Pivot.jsx +++ b/ui/src/pages/Pivot.jsx @@ -49,19 +49,24 @@ function normalize(v) { function filterRows(allRows, row, config) { const groupBy = config.group_by || [] - const splitBy = config.split_by || [] - const pivotCols = [...groupBy, ...splitBy] - if (pivotCols.length === 0) { - // Flat view — the clicked row IS one underlying row; return it directly - // (no need to re-filter; Perspective already shows one row per record) + if (groupBy.length === 0) { + // Flat view — clicked row IS the record return [row] } - // Pivoted — filter allRows by each group/split column value - const criteria = pivotCols - .map(col => ({ col, val: normalize(row[col]) })) - .filter(({ val }) => val != null) + // __ROW_PATH__ is an array of the group_by values in order, e.g. ["Groceries", "Wal-Mart"] + const rowPath = row['__ROW_PATH__'] + const pathVals = Array.isArray(rowPath) + ? rowPath + : String(rowPath).split(',').map(s => s.trim()) + + // Zip group_by columns with __ROW_PATH__ values to build filter criteria + const criteria = groupBy + .map((col, i) => ({ col, val: pathVals[i] != null ? String(pathVals[i]).trim() : null })) + .filter(({ val }) => val != null && val !== '') + + if (criteria.length === 0) return allRows return allRows.filter(r => criteria.every(({ col, val }) => normalize(r[col]) === val) @@ -113,12 +118,14 @@ export default function Pivot({ source }) { const viewer = viewerRef.current - viewer.addEventListener('perspective-click', (e) => { + viewer.addEventListener('perspective-click', async (e) => { const detail = e.detail || {} - const { row, config, column_names } = detail + const { row, column_names } = detail if (!row) return + // perspective-click's config only has filter — save() gives us the full config incl. group_by + const config = await viewer.save() setClickDetail({ row, config, column_names }) - const matched = filterRows(allRowsRef.current, row, config || {}) + const matched = filterRows(allRowsRef.current, row, config) setInspectedRows(matched) })