You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by en...@apache.org on 2026/07/03 18:57:18 UTC
(superset) 07/08: feat(ag-grid): move the summary checkbox to the customize tab
This is an automated email from the ASF dual-hosted git repository.
EnxDev pushed a commit to branch feat/ag-grid-table-raw-records-summary
in repository https://gitbox.apache.org/repos/asf/superset.git
commit b815539fd9f180931f44f25ffbbac6654da7c278
Author: Enzo Martellucci <en...@gmail.com>
AuthorDate: Fri Jul 3 20:42:11 2026 +0200
feat(ag-grid): move the summary checkbox to the customize tab
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 <no...@anthropic.com>
---
.../src/AgGridTableChart.tsx | 20 ++++++++
.../src/controlPanel.tsx | 27 +++++-----
.../src/utils/externalAPIs.ts | 1 +
.../test/AgGridTableChart.test.tsx | 57 ++++++++++++++++++++++
.../test/controlPanel.test.ts | 30 +++++-------
5 files changed, 104 insertions(+), 31 deletions(-)
diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx
index 16f2261ce06..2b7bb750fb8 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/AgGridTableChart.tsx
@@ -156,6 +156,26 @@ export default function TableChart<D extends DataRecord = DataRecord>(
setDataMask,
]);
+ useEffect(() => {
+ if (isRawRecords) {
+ return;
+ }
+ const requested = Boolean(serverPaginationData?.aggregateTotalsRequested);
+ // A renderTrigger toggle re-renders without re-querying; nudging ownState
+ // dispatches the standard re-query whose buildQuery carries the totals.
+ if (showTotals && totals === undefined && !requested) {
+ updateTableOwnState(setDataMask, {
+ ...serverPaginationData,
+ aggregateTotalsRequested: true,
+ });
+ } else if (!showTotals && requested) {
+ updateTableOwnState(setDataMask, {
+ ...serverPaginationData,
+ aggregateTotalsRequested: false,
+ });
+ }
+ }, [isRawRecords, showTotals, totals, serverPaginationData, setDataMask]);
+
const comparisonColumns = [
{ key: 'all', label: t('Display all') },
{ key: '#', label: '#' },
diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx
index 58571a9b626..3ef4ee27a40 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/controlPanel.tsx
@@ -425,19 +425,6 @@ const config: ControlPanelConfig = {
},
},
],
- [
- {
- name: 'show_totals',
- config: {
- type: 'CheckboxControl',
- label: t('Show summary'),
- default: false,
- description: t(
- 'Show a summary row of total aggregations: the selected metrics in aggregate mode, or the sum of numeric columns in raw records mode. Note that row limit does not apply to the result.',
- ),
- },
- },
- ],
],
},
{
@@ -494,6 +481,20 @@ const config: ControlPanelConfig = {
label: t('Visual formatting'),
expanded: true,
controlSetRows: [
+ [
+ {
+ name: 'show_totals',
+ config: {
+ type: 'CheckboxControl',
+ label: t('Show summary'),
+ default: false,
+ renderTrigger: true,
+ description: t(
+ 'Show a summary row of total aggregations: the selected metrics in aggregate mode, or the sum of numeric columns in raw records mode. Note that row limit does not apply to the result.',
+ ),
+ },
+ },
+ ],
[
{
name: 'show_numbered_column',
diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts
index 3402d3a408b..84312e9a7c8 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/externalAPIs.ts
@@ -28,6 +28,7 @@ interface TableOwnState {
searchText?: string;
sortBy?: SortByItem[];
rawSummaryColumns?: string[];
+ aggregateTotalsRequested?: boolean;
}
export const updateTableOwnState = (
diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/test/AgGridTableChart.test.tsx b/superset-frontend/plugins/plugin-chart-ag-grid-table/test/AgGridTableChart.test.tsx
index 8ecd411f116..fb03906a71a 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/test/AgGridTableChart.test.tsx
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/test/AgGridTableChart.test.tsx
@@ -501,6 +501,63 @@ test('AgGridTableChart clears a stale summary prime when no numeric columns rema
});
});
+test('AgGridTableChart requests aggregate totals when the summary toggles on without data', async () => {
+ const props = transformProps({
+ ...testData.basic,
+ rawFormData: {
+ ...testData.basic.rawFormData,
+ show_totals: true,
+ },
+ });
+
+ render(
+ ProviderWrapper({
+ children: (
+ <AgGridTableChart
+ {...props}
+ setDataMask={mockSetDataMask}
+ slice_id={1}
+ />
+ ),
+ }),
+ );
+
+ await waitFor(() => {
+ expect(mockSetDataMask).toHaveBeenCalledWith(
+ expect.objectContaining({
+ ownState: expect.objectContaining({ aggregateTotalsRequested: true }),
+ }),
+ );
+ });
+});
+
+test('AgGridTableChart clears the aggregate totals request when the summary is off', async () => {
+ const props = transformProps(testData.basic);
+ props.serverPaginationData = { aggregateTotalsRequested: true };
+
+ render(
+ ProviderWrapper({
+ children: (
+ <AgGridTableChart
+ {...props}
+ setDataMask={mockSetDataMask}
+ slice_id={1}
+ />
+ ),
+ }),
+ );
+
+ await waitFor(() => {
+ expect(mockSetDataMask).toHaveBeenCalledWith(
+ expect.objectContaining({
+ ownState: expect.objectContaining({
+ aggregateTotalsRequested: false,
+ }),
+ }),
+ );
+ });
+});
+
test('AgGridTableChart pins no summary row when totals are absent', async () => {
const props = transformProps({
...rawSummaryProps,
diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/test/controlPanel.test.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/test/controlPanel.test.ts
index 72f3310c497..05890b1c8e5 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/test/controlPanel.test.ts
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/test/controlPanel.test.ts
@@ -76,25 +76,19 @@ test('time_grain_sqla visibility should be case-insensitive', () => {
expect(vis(mkProps(['some_other_col']), controlState)).toBe(false);
});
-test('show_totals is available in both query modes', () => {
- let showTotals: CustomControlItem | undefined;
- config.controlPanelSections.forEach(section => {
- section?.controlSetRows.forEach(row => {
- row.forEach(item => {
- if (
- typeof item === 'object' &&
- item !== null &&
- 'name' in item &&
- (item as CustomControlItem).name === 'show_totals'
- ) {
- showTotals = item as CustomControlItem;
- }
- });
- });
- });
+test('show_totals renders in the customize tab atop visual formatting', () => {
+ const visualFormatting = config.controlPanelSections.find(
+ section => section?.label === 'Visual formatting',
+ );
+ expect(visualFormatting).toBeDefined();
- expect(showTotals).toBeDefined();
+ const [firstRow] = visualFormatting!.controlSetRows;
+ const firstControl = firstRow[0] as CustomControlItem;
+ expect(firstControl.name).toBe('show_totals');
+ // renderTrigger keeps the whole section classified into the customize tab
+ // and must not regress; without it the section moves to the data tab.
+ expect(firstControl.config.renderTrigger).toBe(true);
// No visibility gate: the summary checkbox must render in raw records
// mode as well as aggregate mode.
- expect(showTotals?.config?.visibility).toBeUndefined();
+ expect(firstControl.config.visibility).toBeUndefined();
});