msyavuz commented on code in PR #36237:
URL: https://github.com/apache/superset/pull/36237#discussion_r2565333937


##########
superset-frontend/src/embedded/api.tsx:
##########
@@ -80,10 +90,132 @@ const getDataMask = () => store?.getState()?.dataMask || 
{};
 const getChartStates = () =>
   store?.getState()?.dashboardState?.chartStates || {};
 
+/**
+ * Get query context payloads for stateful charts only (e.g., AG Grid tables).
+ * Returns payloads only for charts that have registered state converters.
+ * Non-stateful charts will not be included in the result.
+ *
+ * These payloads include dashboard filters and chart state (sorting, column 
order, etc.)
+ * and can be POSTed directly to /api/v1/chart/data for CSV export.
+ *
+ * If payload generation fails for a chart, an error object will be returned 
for that chart
+ * containing `{ error: true, message: string }`, allowing other charts to 
process successfully.
+ *
+ * @param chartId - Optional chart ID to get payload for a specific chart only
+ * @returns Record of chart IDs to their query context payloads (only for 
stateful charts).
+ *          Failed charts will have an error object instead of a valid payload.
+ */
+const getChartDataPayloads = async (params?: {
+  chartId?: number;
+}): Promise<Record<string, JsonObject>> => {
+  const { chartId } = params || {};
+  const state = store?.getState();
+  if (!state) return {};
+
+  const charts = state.charts || {};
+  const sliceEntities = state.sliceEntities?.slices || {};
+  const dataMask = state.dataMask || {};
+  const chartStates = state.dashboardState?.chartStates || {};
+  const chartConfiguration =
+    state.dashboardInfo?.metadata?.chart_configuration || {};
+  const nativeFilters = state.nativeFilters?.filters || {};
+  const allSliceIds = state.dashboardState?.sliceIds || [];
+  const colorScheme = state.dashboardState?.colorScheme;
+  const colorNamespace = state.dashboardState?.colorNamespace;
+
+  const chartEntries = Object.entries(charts).filter(([id]) => {
+    const numericId = Number(id);
+    const slice = sliceEntities[id];
+
+    if (!slice || !hasChartStateConverter(slice.viz_type)) {
+      return false;
+    }
+
+    if (chartId !== undefined && numericId !== chartId) {
+      return false;
+    }
+
+    return true;
+  });
+
+  const payloadPromises = chartEntries.map(async ([id, chart]) => {
+    const numericId = Number(id);
+    const slice = sliceEntities[id];
+
+    try {
+      if (!chart || typeof chart !== 'object' || !('form_data' in chart)) {
+        throw new Error(`Chart ${id} is missing form_data`);
+      }
+
+      const formData = getFormDataWithExtraFilters({
+        chart: { id: numericId, form_data: (chart as JsonObject).form_data },
+        chartConfiguration,
+        filters: getAppliedFilterValues(numericId),
+        colorScheme,
+        colorNamespace,
+        sliceId: numericId,
+        nativeFilters,
+        allSliceIds,
+        dataMask,
+        extraControls: {},
+      });
+
+      const chartState = chartStates[id]?.state;
+      const baseOwnState = dataMask[id]?.ownState || {};
+      const convertedState = chartState
+        ? convertChartStateToOwnState(slice.viz_type, chartState)
+        : {};
+
+      const ownState = {
+        ...baseOwnState,
+        ...convertedState,
+      };
+
+      const payload = await buildV1ChartDataPayload({
+        formData,
+        resultFormat: 'json',
+        resultType: 'results',
+        ownState,
+        setDataMask: null,
+        force: false,
+      });
+
+      return [id, payload] as const;
+    } catch (error) {
+      logging.error(`Failed to build payload for chart ${id}:`, error);
+      return [
+        id,
+        {
+          error: true,
+          message: error instanceof Error ? error.message : String(error),
+        },
+      ] as const;
+    }
+  });
+
+  const results = await Promise.all(payloadPromises);
+  const payloads = Object.fromEntries(results);
+
+  if (chartId !== undefined && Object.keys(payloads).length === 0) {
+    logging.warn(
+      `Chart ${chartId} not found or is not a stateful chart with a registered 
state converter`,
+    );
+    return {
+      [chartId]: {
+        error: true,
+        message: `Chart ${chartId} not found or is not a stateful chart`,
+      },
+    };
+  }
+
+  return payloads;
+};

Review Comment:
   Should we move this to the utils and test it? Similar to how other functions 
in this api is structured



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to