You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by el...@apache.org on 2026/01/20 19:04:16 UTC
(superset) 26/37: feat(charts): Enable async buildQuery support for complex chart logic (#34383)
This is an automated email from the ASF dual-hosted git repository.
elizabeth pushed a commit to branch elizabeth/fix-resize-bug
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 0951d6c4486a0b9a65619fa5016a62d68e8f1795
Author: Maxime Beauchemin <ma...@gmail.com>
AuthorDate: Tue Jul 29 13:08:55 2025 -0700
feat(charts): Enable async buildQuery support for complex chart logic (#34383)
Co-authored-by: Claude <no...@anthropic.com>
---
.../src/components/Chart/chartAction.js | 22 ++++++++++++----------
.../src/components/Chart/chartActions.test.js | 17 +++++++++++++----
.../src/explore/exploreUtils/exploreUtils.test.jsx | 4 ++--
.../src/explore/exploreUtils/index.js | 6 +++---
4 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/superset-frontend/src/components/Chart/chartAction.js b/superset-frontend/src/components/Chart/chartAction.js
index 10e45b385a..75a895b27c 100644
--- a/superset-frontend/src/components/Chart/chartAction.js
+++ b/superset-frontend/src/components/Chart/chartAction.js
@@ -164,7 +164,7 @@ const v1ChartDataRequest = async (
ownState,
parseMethod,
) => {
- const payload = buildV1ChartDataPayload({
+ const payload = await buildV1ChartDataPayload({
formData,
resultType,
resultFormat,
@@ -255,7 +255,7 @@ export function runAnnotationQuery({
isDashboardRequest = false,
force = false,
}) {
- return function (dispatch, getState) {
+ return async function (dispatch, getState) {
const { charts, common } = getState();
const sliceKey = key || Object.keys(charts)[0];
const queryTimeout = timeout || common.conf.SUPERSET_WEBSERVER_TIMEOUT;
@@ -310,17 +310,19 @@ export function runAnnotationQuery({
fd.annotation_layers[annotationIndex].overrides = sliceFormData;
}
+ const payload = await buildV1ChartDataPayload({
+ formData: fd,
+ force,
+ resultFormat: 'json',
+ resultType: 'full',
+ });
+
return SupersetClient.post({
url,
signal,
timeout: queryTimeout * 1000,
headers: { 'Content-Type': 'application/json' },
- jsonPayload: buildV1ChartDataPayload({
- formData: fd,
- force,
- resultFormat: 'json',
- resultType: 'full',
- }),
+ jsonPayload: payload,
})
.then(({ json }) => {
const data = json?.result?.[0]?.annotation_data?.[annotation.name];
@@ -420,6 +422,8 @@ export function exploreJSON(
const setDataMask = dataMask => {
dispatch(updateDataMask(formData.slice_id, dataMask));
};
+ dispatch(chartUpdateStarted(controller, formData, key));
+
const chartDataRequest = getChartDataRequest({
setDataMask,
formData,
@@ -431,8 +435,6 @@ export function exploreJSON(
ownState,
});
- dispatch(chartUpdateStarted(controller, formData, key));
-
const [useLegacyApi] = getQuerySettings(formData);
const chartDataRequestCaught = chartDataRequest
.then(({ response, json }) =>
diff --git a/superset-frontend/src/components/Chart/chartActions.test.js b/superset-frontend/src/components/Chart/chartActions.test.js
index c18d8b8c59..c606859497 100644
--- a/superset-frontend/src/components/Chart/chartActions.test.js
+++ b/superset-frontend/src/components/Chart/chartActions.test.js
@@ -64,6 +64,7 @@ describe('chart actions', () => {
let dispatch;
let getExploreUrlStub;
let getChartDataUriStub;
+ let buildV1ChartDataPayloadStub;
let waitForAsyncDataStub;
let fakeMetadata;
@@ -85,6 +86,13 @@ describe('chart actions', () => {
getChartDataUriStub = sinon
.stub(exploreUtils, 'getChartDataUri')
.callsFake(({ qs }) => URI(MOCK_URL).query(qs));
+ buildV1ChartDataPayloadStub = sinon
+ .stub(exploreUtils, 'buildV1ChartDataPayload')
+ .resolves({
+ some_param: 'fake query!',
+ result_type: 'full',
+ result_format: 'json',
+ });
fakeMetadata = { useLegacyApi: true };
getChartMetadataRegistry.mockImplementation(() => ({
get: () => fakeMetadata,
@@ -104,6 +112,7 @@ describe('chart actions', () => {
afterEach(() => {
getExploreUrlStub.restore();
getChartDataUriStub.restore();
+ buildV1ChartDataPayloadStub.restore();
fetchMock.resetHistory();
waitForAsyncDataStub.restore();
@@ -362,7 +371,7 @@ describe('chart actions timeout', () => {
jest.clearAllMocks();
});
- it('should use the timeout from arguments when given', () => {
+ it('should use the timeout from arguments when given', async () => {
const postSpy = jest.spyOn(SupersetClient, 'post');
postSpy.mockImplementation(() => Promise.resolve({ json: { result: [] } }));
const timeout = 10; // Set the timeout value here
@@ -370,7 +379,7 @@ describe('chart actions timeout', () => {
const key = 'chartKey'; // Set the chart key here
const store = mockStore(initialState);
- store.dispatch(
+ await store.dispatch(
actions.runAnnotationQuery({
annotation: {
value: 'annotationValue',
@@ -394,14 +403,14 @@ describe('chart actions timeout', () => {
expect(postSpy).toHaveBeenCalledWith(expectedPayload);
});
- it('should use the timeout from common.conf when not passed as an argument', () => {
+ it('should use the timeout from common.conf when not passed as an argument', async () => {
const postSpy = jest.spyOn(SupersetClient, 'post');
postSpy.mockImplementation(() => Promise.resolve({ json: { result: [] } }));
const formData = { datasource: 'table__1' }; // Set the formData here
const key = 'chartKey'; // Set the chart key here
const store = mockStore(initialState);
- store.dispatch(
+ await store.dispatch(
actions.runAnnotationQuery({
annotation: {
value: 'annotationValue',
diff --git a/superset-frontend/src/explore/exploreUtils/exploreUtils.test.jsx b/superset-frontend/src/explore/exploreUtils/exploreUtils.test.jsx
index 7e0a556d74..61dbf138ef 100644
--- a/superset-frontend/src/explore/exploreUtils/exploreUtils.test.jsx
+++ b/superset-frontend/src/explore/exploreUtils/exploreUtils.test.jsx
@@ -191,8 +191,8 @@ describe('exploreUtils', () => {
});
describe('buildV1ChartDataPayload', () => {
- it('generate valid request payload despite no registered buildQuery', () => {
- const v1RequestPayload = buildV1ChartDataPayload({
+ it('generate valid request payload despite no registered buildQuery', async () => {
+ const v1RequestPayload = await buildV1ChartDataPayload({
formData: { ...formData, viz_type: 'my_custom_viz' },
});
expect(v1RequestPayload.hasOwnProperty('queries')).toBeTruthy();
diff --git a/superset-frontend/src/explore/exploreUtils/index.js b/superset-frontend/src/explore/exploreUtils/index.js
index e26f693626..d3bd62ef41 100644
--- a/superset-frontend/src/explore/exploreUtils/index.js
+++ b/superset-frontend/src/explore/exploreUtils/index.js
@@ -207,7 +207,7 @@ export const getQuerySettings = formData => {
];
};
-export const buildV1ChartDataPayload = ({
+export const buildV1ChartDataPayload = async ({
formData,
force,
resultFormat,
@@ -242,7 +242,7 @@ export const buildV1ChartDataPayload = ({
export const getLegacyEndpointType = ({ resultType, resultFormat }) =>
resultFormat === 'csv' ? resultFormat : resultType;
-export const exportChart = ({
+export const exportChart = async ({
formData,
resultFormat = 'json',
resultType = 'full',
@@ -262,7 +262,7 @@ export const exportChart = ({
payload = formData;
} else {
url = ensureAppRoot('/api/v1/chart/data');
- payload = buildV1ChartDataPayload({
+ payload = await buildV1ChartDataPayload({
formData,
force,
resultFormat,