Skip to content

feat(table): add spreadsheet selection aggregates in CsvTable toolbar - #230

Merged
obvious-autobuild-staging[bot] merged 1 commit into
masterfrom
feat/selection-aggregates
Oct 20, 2026
Merged

obvious-autobuild-staging[bot] merged 1 commit into
masterfrom
feat/selection-aggregates

Conversation

@obvious-autobuild-staging

@obvious-autobuild-staging obvious-autobuild-staging Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Why

Selecting rows, columns, or rectangular cell ranges in the CSV grid previously offered no way to inspect counts, distinct values, blank cells, or numeric totals without copying the selection into an external spreadsheet. Furthermore, selecting a multi-cell rectangular range with the mouse or keyboard did not surface the selection toolbar strip or its Copy as CSV button unless a full row or column header was clicked.

What

  • Pure selection aggregate calculator (app/src/lib/tableSelection.ts): Added SelectionStats and computeSelectionStats(table, view, selection, gutterColumns), collecting unique (viewRow, dataCol) coordinates across rectangular ranges (skipping gutter columns < gutterColumns), selected rows, and selected columns (capped at 100,000 cells so huge tables stay instantaneous). Returns null when nothing is selected or when only a single cell (cellCount < 2) is focused without a row or column selection.
  • Live aggregate pill & range copy in CsvTable.tsx: Extended the selection toolbar strip to activate whenever selectedInView.length > 0 || selectedColumnCount > 0 || selectionStats !== null, enabling Copy as CSV for multi-cell rectangular ranges and rendering data-testid="{testId}-selection-stats" with Cells · Distinct, conditional Empty, and Intl.NumberFormat("en-US", { maximumFractionDigits: 4 })-formatted Sum · Avg · Min · Max when numeric cells are present.
  • Changelog & Tests: Added bundled changelog entry #18 (2026-10-20, tag "new"), unit tests in app/src/lib/tableSelection.test.ts, and component tests in app/src/components/CsvTable.test.tsx. Rebuilt app/dist.

How to Review

  • app/src/lib/tableSelection.ts & app/src/lib/tableSelection.test.ts — coordinate deduplication across ranges/rows/columns, gutter exclusion, 100k-cell cap, and numeric parsing (/^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?$/).
  • app/src/components/CsvTable.tsx & app/src/components/CsvTable.test.tsx — memoized selectionStats, toolbar visibility for multi-cell ranges, and formatted live readout pill.

Test Evidence

AC-17: Spreadsheet selection aggregates (Cells · Distinct · Empty · Sum · Avg · Min · Max) in CsvTable toolbar
AC-17: Spreadsheet selection aggregates (Cells · Distinct · Empty · Sum · Avg · Min · Max) in CsvTable toolbar — before
AC-17: Spreadsheet selection aggregates (Cells · Distinct · Empty · Sum · Avg · Min · Max) in CsvTable toolbar — after
AC-17: Spreadsheet selection aggregates (Cells · Distinct · Empty · Sum · Avg · Min · Max) in CsvTable toolbar — recording

  • cd app && npm run lint && npx tsc -b --noEmit && npm test && npm run build (34 test files, 568 tests passing)
  • bash .github/scripts/verify-seo.sh (passed, 45,103 bytes of prerendered HTML)
  • Verified interactively in headless Chromium (agent-browser at 1440×900) and uploaded QA evidence (tc-17).

Human author: David Boskovic (david@obvious.ai)

🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact

Compute live cell, distinct, empty, and numeric (Sum, Avg, Min, Max)
aggregates across multi-cell rectangular ranges, selected rows, and
selected columns in CsvTable, and surface them in the selection toolbar
strip alongside Copy as CSV.

Co-authored-by: David Boskovic <david@obvious.ai>
@obvious-autobuild-staging
obvious-autobuild-staging Bot marked this pull request as ready for review October 20, 2026 02:29
@obvious-autobuild-staging
obvious-autobuild-staging Bot merged commit e3c1fae into master Oct 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants