From 7ee70d9aba5a1641e73657ae359a8b12a4d9f62f Mon Sep 17 00:00:00 2001 From: Mehmet Salih Yavuz Date: Thu, 9 Apr 2026 11:11:43 +0300 Subject: [PATCH] fix(AlertsReports): untie filters from alerts reports tabs flag (#38722) Co-authored-by: Claude Opus 4.6 (1M context) (cherry picked from commit 5263abdc60ef790c649d799f4485c1f9f028e86b) --- .../src/features/alerts/AlertReportModal.tsx | 8 +-- superset/commands/report/execute.py | 17 +++++++ .../commands/report/execute_test.py | 50 +++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/features/alerts/AlertReportModal.tsx b/superset-frontend/src/features/alerts/AlertReportModal.tsx index f23cb98015a..fc3f3ce5fc0 100644 --- a/superset-frontend/src/features/alerts/AlertReportModal.tsx +++ b/superset-frontend/src/features/alerts/AlertReportModal.tsx @@ -1076,7 +1076,7 @@ const AlertReportModal: FunctionComponent = ({ const dashboard = currentAlert?.dashboard; useEffect(() => { - if (!tabsEnabled) return; + if (!tabsEnabled && !filtersEnabled) return; if (dashboard?.value) { SupersetClient.get({ @@ -1156,7 +1156,7 @@ const AlertReportModal: FunctionComponent = ({ addDangerToast(t('There was an error retrieving dashboard tabs.')); }); } - }, [dashboard, tabsEnabled, currentAlert?.extra, addDangerToast]); + }, [dashboard, tabsEnabled, filtersEnabled, currentAlert?.extra, addDangerToast]); const databaseLabel = currentAlert?.database && !currentAlert.database.label; useEffect(() => { @@ -1368,9 +1368,11 @@ const AlertReportModal: FunctionComponent = ({ updateAlertState('chart', null); if (tabsEnabled) { setTabOptions([]); - setNativeFilterOptions([]); updateAnchorState(''); } + if (tabsEnabled || filtersEnabled) { + setNativeFilterOptions([]); + } if (filtersEnabled) { setNativeFilterData([ { diff --git a/superset/commands/report/execute.py b/superset/commands/report/execute.py index 72c84986273..e94d215057e 100644 --- a/superset/commands/report/execute.py +++ b/superset/commands/report/execute.py @@ -299,6 +299,23 @@ class BaseReportState: ) ] + native_filter_params, filter_warnings = ( + self._report_schedule.get_native_filters_params() + ) + if filter_warnings: + self._filter_warnings.extend(filter_warnings) + if native_filter_params and native_filter_params != "()": + return [ + self._get_tab_url( + { + "urlParams": [ + ["native_filters", native_filter_params] # type: ignore + ], + }, + user_friendly=user_friendly, + ) + ] + dashboard = self._report_schedule.dashboard dashboard_id_or_slug = ( dashboard.uuid if dashboard and dashboard.uuid else dashboard.id diff --git a/tests/unit_tests/commands/report/execute_test.py b/tests/unit_tests/commands/report/execute_test.py index f1f73bcf4bc..b3f11c7b41e 100644 --- a/tests/unit_tests/commands/report/execute_test.py +++ b/tests/unit_tests/commands/report/execute_test.py @@ -413,6 +413,55 @@ def test_get_tab_url( assert result == urllib.parse.urljoin(base_url, "superset/dashboard/p/uri/") +@patch( + "superset.commands.dashboard.permalink.create.CreateDashboardPermalinkCommand.run" +) +@with_feature_flags(ALERT_REPORT_TABS=False) +def test_get_dashboard_urls_native_filters_without_tabs( + mock_run, + mocker: MockerFixture, + app, +) -> None: + """Native filters should be applied even when ALERT_REPORT_TABS is disabled.""" + mock_report_schedule: ReportSchedule = mocker.Mock(spec=ReportSchedule) + mock_report_schedule.chart = False + mock_report_schedule.chart_id = None + mock_report_schedule.dashboard_id = 123 + mock_report_schedule.force_screenshot = False + extra = { + "dashboard": { + "nativeFilters": [ + { + "nativeFilterId": "NATIVE_FILTER-abc", + "filterType": "filter_select", + "columnName": "col1", + "filterValues": ["val1"], + } + ] + } + } + mock_report_schedule.extra = extra # type: ignore[assignment] + mock_report_schedule.get_native_filters_params.return_value = ( # type: ignore + "(NATIVE_FILTER-abc:!(val1))", + [], + ) + + mock_dashboard = mocker.MagicMock() + mock_dashboard.uuid = UUID("12345678-1234-1234-1234-123456789abc") + mock_report_schedule.dashboard = mock_dashboard + + class_instance: BaseReportState = BaseReportState( + mock_report_schedule, "January 1, 2021", "execution_id_example" + ) + class_instance._report_schedule = mock_report_schedule + mock_run.return_value = "permalink_key" + + result: list[str] = class_instance.get_dashboard_urls() + + assert len(result) == 1 + assert "permalink_key" in result[0] + + def create_report_schedule( mocker: MockerFixture, custom_width: int | None = None, @@ -429,6 +478,7 @@ def create_report_schedule( schedule.database = None schedule.custom_width = custom_width schedule.custom_height = custom_height + schedule.get_native_filters_params = mocker.MagicMock(return_value=("", [])) return schedule