Skip to content

feat(ag-grid): support Show summary in raw records mode#41754

Merged
EnxDev merged 14 commits into
masterfrom
feat/ag-grid-table-raw-records-summary
Jul 6, 2026
Merged

feat(ag-grid): support Show summary in raw records mode#41754
EnxDev merged 14 commits into
masterfrom
feat/ag-grid-table-raw-records-summary

Conversation

@EnxDev

@EnxDev EnxDev commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Makes the Interactive Table (ag-grid-table) "Show summary" option available and functional in Raw Records mode, and moves the checkbox into the Customize tab.

Before, two independent gates made the summary aggregate-only: the control was declared with visibility: isAggMode (so it never rendered in Raw Records — a value set in Aggregate mode silently persisted via resetOnHide: false but was inert), and buildQuery only emitted the totals query when queryMode === Aggregate.
before

After:

  • In Raw Records mode, enabling Customize → Show summary pins a bottom row with a server-side SUM per numeric column, computed across the full filtered dataset (row limit does not apply — the same semantics the option already has in Aggregate mode). Non-numeric cells stay blank. Only columns backed by a dataset (physical or calculated) column are summed; free-form SQL expression columns are excluded.
  • The checkbox now lives at the top of the Visual formatting section in the Customize tab, for both query modes.
after

Design decisions worth calling out:

  • Numeric-column plumbing. buildQuery has no datasource column metadata, so transformProps derives the numeric, dataset-backed subset of the raw selection and the chart mirrors it into ownState.rawSummaryColumns — the same mechanism the plugin already uses for metricSqlExpressions. The totals query is then a standard extra query (columns: [], row_limit: 0, SIMPLE SUM adhoc metrics labeled with the column names), reusing the existing AG-Grid-filter exclusion (totalsExtras) logic. A raw chart with the summary enabled performs one priming re-query on first load (the base query is a cache hit; only the totals query is new work).
  • Customize-tab placement requires renderTrigger. Explore classifies a section into the Customize tab only when every control in it has renderTrigger (ControlPanelsContainer.tsx); adding show_totals to Visual formatting without it would have relocated all nine formatting controls to the Data tab. Since renderTrigger toggles don't re-query, the chart requests totals through the plugin's existing ownState re-query channel (totalsRequested) — the same sanctioned mechanism as server pagination. Toggle-on shows the standard loading state and issues the same query the old Data-tab checkbox produced; toggle-off hides the row instantly and issues one cache-friendly query to clear the request flag. All totals-related ownState writes are combined into a single delta per render to avoid same-render clobbering between the raw-mode prime and the re-query nudge.
  • Known bounded corner: with the summary enabled but no summable columns (raw mode with zero numeric columns, or aggregate mode with zero metrics), one nudge re-query fires, buildQuery adds no totals query, and the flag goes dormant — no pinned row is shown and no further queries are issued.
  • The legacy plugin-chart-table keeps show_totals in the Data tab and aggregate-only; this PR intentionally changes only the AG Grid table plugin.
  • No docs change: there is no existing table-viz options page documenting "Show summary" to extend.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before: in Raw Records mode the Customize tab has no "Show summary" option (it only appeared in the Data tab in Aggregate mode).
After: Customize → Visual formatting starts with "Show summary"; enabling it in Raw Records pins a SUM row.
(Screenshots to be attached.)

TESTING INSTRUCTIONS

  1. Enable the AG_GRID_TABLE_ENABLED feature flag.
  2. Create an Interactive Table chart in Raw Records query mode with at least one numeric column (e.g. birth_names with num).
  3. Open Customize → the Visual formatting section starts with Show summary; enable it.
  4. The grid re-queries once and pins a bottom row with the SUM of each numeric column, computed over the full filtered dataset (independent of row limit and server pagination).
  5. Toggle it off — the row disappears immediately. Toggle on/off across interactions (sort, filter, paginate) — the row always reflects the current filters (AG Grid column filters are excluded from totals, matching Aggregate-mode behavior).
  6. Switch to Aggregate mode — Show summary behaves as before, now from the Customize tab.
  7. Unit/component coverage: npx jest plugins/plugin-chart-ag-grid-table (250 tests).

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: AG_GRID_TABLE_ENABLED
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

🤖 Generated with Claude Code

EnxDev and others added 8 commits July 3, 2026 17:06
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the rawSummaryColumns.length === 0 guard in the priming effect so a
primed->empty transition writes the cleared list instead of leaving a
stale prime behind. Gate the pinned totals row on totals being defined
so raw-records mode with zero numeric columns renders no blank summary
row, matching aggregate mode where a defined totals row is required.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Relocate show_totals to the top of Visual formatting and mark it
renderTrigger so the whole section stays classified into the
Customize tab. Since renderTrigger toggles skip the query cycle,
add a symmetric ownState nudge (aggregateTotalsRequested) so
switching the summary on in aggregate mode still re-queries for
totals, mirroring the existing raw-records priming effect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two separate ownState effects (raw-mode summary priming and the
aggregate-only totals nudge) each spread serverPaginationData in the
same render, so they could clobber each other's writes. This let raw
mode starve: toggling the summary off then back on with a prime that
already matched the derived column list skipped both the priming
write and the nudge, leaving totals unrequested and the row missing.

Replace both effects with one that computes a single combined
ownState delta covering priming and the totals request/clear for both
query modes, and rename aggregateTotalsRequested to totalsRequested
now that it applies to raw records too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dosubot dosubot Bot added change:frontend Requires changing the frontend explore:design Related to the Explore UI/UX viz:charts:table Related to the Table chart labels Jul 3, 2026
@bito-code-review

bito-code-review Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #c05d36

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts - 1
    • Missing interface documentation · Line 30-31
      Consider adding JSDoc to the `TableOwnState` interface to document what `rawSummaryColumns` (columns for summary totals) and `totalsRequested` (toggle for showing totals) represent. This helps future maintainers understand the contract.
Review Details
  • Files reviewed - 9 · Commit Range: a4585a3..3b213da
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/buildQuery.ts
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/transformProps.ts
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/types.ts
    • superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts
    • superset-frontend/plugins/plugin-chart-ag-grid-table/test/AgGridTableChart.test.tsx
    • superset-frontend/plugins/plugin-chart-ag-grid-table/test/buildQuery.test.ts
    • superset-frontend/plugins/plugin-chart-ag-grid-table/test/controlPanel.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@EnxDev EnxDev requested a review from amaannawab923 July 3, 2026 19:07
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.67%. Comparing base (1575b83) to head (4a961d5).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41754      +/-   ##
==========================================
- Coverage   64.72%   64.67%   -0.05%     
==========================================
  Files        2686     2686              
  Lines      148651   148594      -57     
  Branches    34309    34308       -1     
==========================================
- Hits        96213    96108     -105     
- Misses      50676    50731      +55     
+ Partials     1762     1755       -7     
Flag Coverage Δ
javascript 69.58% <100.00%> (+0.01%) ⬆️
presto ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Jul 6, 2026
@netlify

netlify Bot commented Jul 6, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit b24280d
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a4bbe660b91e30008abd7cb
😎 Deploy Preview https://deploy-preview-41754--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx Outdated
EnxDev and others added 2 commits July 6, 2026 16:32
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@EnxDev

EnxDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Both CodeAnt findings were valid; fixed in ca9d23c and 0cb8c56 (254/254 plugin tests passing).

AgGridTableChart.tsx — falsy-zero page clamp (re: the clamp thread, and @alexandrusoare's question): confirmed. The falsy rowCount guard skipped the clamp entirely on empty result sets — behavior this branch inherited from the pre-existing standalone effect and kept when merging it into the unified ownState delta. The guard now checks rowCount !== undefined and the clamp is a single Math.max(0, Math.min(currentPage, totalPages - 1)), so zero rows reset to page 0 and a shrunken result set lands on its last remaining page.

One correction to the snippet proposed in that thread: clamping every currentPage >= totalPages case to 0 would lose the user's position on ordinary shrinks — page 5 over 3 remaining pages must land on page 2, which an existing regression test in the suite pins. The min/max form covers both cases. New test: raw mode + server pagination + rowCount: 0 asserts the unified write carries currentPage: 0 together with the totals keys, pinning the behavior to this effect rather than the pagination footer's own page reset.

buildQuery.ts — stale ownState.rawSummaryColumns (re: the totals thread): confirmed. For a datasource swap this was a real wedge: the stale name fails the totals query server-side, the chart errors before rendering, and the priming effect never gets a chance to clear its own state. buildQuery now intersects ownState.rawSummaryColumns with the current all_columns labels before emitting SUM metrics, so a persisted name that left the selection (or belonged to a previous datasource) can never reach the totals query; if nothing survives the intersection, no totals query is emitted at all. Two new tests cover the partial and empty intersections.

@amaannawab923 amaannawab923 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few minor comments, rest of the pr looks good to me. mostly a small correctness nit and a test coverage ask, plus one non blocking question on the extra queries. nice work overall.

}
cleanedTotals={totals || {}}
showTotals={showTotals}
showTotals={showTotals && totals !== undefined}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small correctness thing. this only guards against totals being undefined, but if an aggregate totals query comes back as an empty {} it would still pin a blank summary row, since {} !== undefined is true. we might want Object.keys(totals).length > 0 here to cover that case.

@EnxDev EnxDev Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty {} totals confirmed, and there is a concrete path to it: processComparisonTotals returns {} when the time-comparison totals result has no rows, which slipped past totals !== undefined and pinned a blank row. The gate is now showTotals && totals !== undefined && Object.keys(totals).length > 0, with a RED-first test (totals = {} → no pinned row). Note the SUM-over-zero-rows case still pins as intended: the backend returns a row with NULL values there, so the keys are present.

// A renderTrigger toggle re-renders without re-querying; requesting totals
// through ownState dispatches the standard re-query whose buildQuery
// carries the totals query for the active mode.
if (showTotals && totals === undefined && !requested) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a blocker, just want to confirm the intent here. since the checkbox is a renderTrigger, a saved raw + summary chart does a priming re-query after the base load, and toggling off fires a query just to reset totalsRequested. its reasonable given buildQuery cant see column types and you already called it out in the description, so im mostly flagging the extra round trips, especially the reset only one, so its a conscious call. all good if the answer is yes, thats acceptable.

@EnxDev EnxDev Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, conscious call, with these bounds: a saved aggregate + summary chart does zero extra work (totals ride the initial formData-driven query; the nudge only fires in the renderTrigger gap). A saved raw + summary chart pays one priming re-query on first load — the base query is a server-side cache hit, only the totals query is new work. The toggle-off reset query is the deliberate trade-off: the alternative (clearing the flag when data arrives) would fire an extra query after every totals fetch, which is strictly worse; toggle-off stays visually instant regardless because the grid gate hides the row before the query returns.

EnxDev and others added 2 commits July 6, 2026 17:05
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@amaannawab923

Copy link
Copy Markdown
Contributor

Thanks for the detailed follow ups. The empty totals guard and the calculated column test both look good, and the answer on the extra queries makes sense as a conscious trade off . LGTM !! @EnxDev

@EnxDev EnxDev merged commit b421813 into master Jul 6, 2026
66 checks passed
@EnxDev EnxDev deleted the feat/ag-grid-table-raw-records-summary branch July 6, 2026 15:58
@bito-code-review

Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:frontend Requires changing the frontend explore:design Related to the Explore UI/UX plugins size/XL viz:charts:table Related to the Table chart

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants