codeant-ai-for-open-source[bot] commented on code in PR #41133:
URL: https://github.com/apache/superset/pull/41133#discussion_r3507585692
##########
superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx:
##########
@@ -68,8 +71,19 @@ export const useDownloadMenuItems = (
} = props;
const { addDangerToast, addSuccessToast } = useToasts();
+ const dataMask = useSelector((state: RootState) => state.dataMask);
const SCREENSHOT_NODE_SELECTOR = '.dashboard';
+ const buildActiveDataMask = (): Record<string, { extraFormData: object }> =>
+ Object.entries(dataMask || {}).reduce<
+ Record<string, { extraFormData: object }>
+ >((acc, [id, mask]) => {
+ if (id.startsWith(NATIVE_FILTER_PREFIX)) {
+ acc[id] = { extraFormData: mask?.extraFormData ?? {} };
+ }
+ return acc;
+ }, {});
Review Comment:
**Suggestion:** The payload builder currently includes every native filter
ID, even when a filter has no resolved value yet (`extraFormData` is empty).
The backend contract treats a present key with empty `extraFormData` as an
explicit user clear, so this can incorrectly suppress saved defaults during
export. Only include filters in `active_data_mask` when they actually have an
active value or an explicit cleared state that you can positively distinguish
from “not initialized yet”. [api mismatch]
<details>
<summary><b>Severity Level:</b> Critical 🚨</summary>
```mdx
❌ /api/v1/dashboard/<id>/export_xlsx/ ignores default filters.
❌ Excel export workbook can diverge from on-screen filter state.
⚠️ Users may trust exported data that is unintentionally unfiltered.
```
</details>
<details>
<summary><b>Steps of Reproduction ✅ </b></summary>
```mdx
1. Configure a dashboard with a native filter that has a saved default value
(this is
stored in `Dashboard.json_metadata.native_filter_configuration` and read by
`get_dashboard_filter_context` at
`superset/superset/charts/data/dashboard_filter_context.py:46-49`; the
behavior of
defaults is illustrated in
`tests/unit_tests/charts/test_dashboard_filter_context.py:13-22` where
`default_value` is
set).
2. Load that dashboard in the UI and, without touching the filter, open the
Download menu
and click “Export Data to Excel” (the handler is `onExportXlsx` in
`superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx:111-134`,
which posts to `/api/v1/dashboard/<id>/export_xlsx/` with `jsonPayload: {
active_data_mask: buildActiveDataMask() }`).
3. On the client, `buildActiveDataMask` at
`superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx:77-85`
iterates over `state.dataMask`, and for every entry whose id starts with
`NATIVE_FILTER_PREFIX` it unconditionally sets `acc[id] = { extraFormData:
mask?.extraFormData ?? {} }`, so even filters whose `filterState.value` is
still
`undefined` (not initialized, see the missing-value logic in
`superset-frontend/src/dashboard/components/DashboardBuilder/state.ts:70-76`
and its tests
at `state.test.ts:39-43`) are included in the payload with `extraFormData:
{}`.
4. On the backend, the Celery task `export_dashboard_excel` calls
`get_dashboard_filter_context(dashboard_id, chart.id, active_data_mask)` at
`superset/superset/tasks/export_dashboard_excel.py:15-21`; the docstring and
tests in
`superset/superset/charts/data/dashboard_filter_context.py:23-28` and
`tests/unit_tests/charts/test_dashboard_filter_context.py:38-60` show that
“an empty
active extraFormData clears the filter; the default is NOT used”, while
filters absent
from `active_data_mask` fall back to defaults. Because the front-end sent an
entry with
empty `extraFormData` for an uninitialized filter, the filter is treated as
cleared
(`DashboardFilterStatus.NOT_APPLIED` and no default `filters` in
`ctx.extra_form_data`),
so the generated Excel workbook contains unfiltered data even though the
dashboard view is
using the saved default.
```
</details>
[](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=55c100ea49b34768bcea3b7d6ec0590b&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
[](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=55c100ea49b34768bcea3b7d6ec0590b&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:**
superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx
**Line:** 77:85
**Comment:**
*Api Mismatch: The payload builder currently includes every native
filter ID, even when a filter has no resolved value yet (`extraFormData` is
empty). The backend contract treats a present key with empty `extraFormData` as
an explicit user clear, so this can incorrectly suppress saved defaults during
export. Only include filters in `active_data_mask` when they actually have an
active value or an explicit cleared state that you can positively distinguish
from “not initialized yet”.
Validate the correctness of the flagged issue. If correct, How can I resolve
this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask
user if the user wants to fix the rest of the comments as well. if said yes,
then fetch all the comments validate the correctness and implement a minimal fix
```
</details>
<a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41133&comment_hash=76460f90ec7ea55fccbc273d475d579ac3e8c29c6a9daee034c5ff3975f30303&reaction=like'>👍</a>
| <a
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41133&comment_hash=76460f90ec7ea55fccbc273d475d579ac3e8c29c6a9daee034c5ff3975f30303&reaction=dislike'>👎</a>
--
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]