mirror of
https://github.com/apache/superset.git
synced 2026-05-05 07:54:17 +00:00
Compare commits
1 Commits
react18-em
...
enxdev/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d049b316e |
@@ -280,6 +280,7 @@ class BaseReportState:
|
||||
)
|
||||
urls = self._get_tabs_urls(
|
||||
anchor_list,
|
||||
dashboard_state=dashboard_state,
|
||||
native_filter_params=native_filter_params,
|
||||
user_friendly=user_friendly,
|
||||
)
|
||||
@@ -356,21 +357,33 @@ class BaseReportState:
|
||||
def _get_tabs_urls(
|
||||
self,
|
||||
tab_anchors: list[str],
|
||||
dashboard_state: Optional[DashboardPermalinkState] = None,
|
||||
native_filter_params: Optional[str] = None,
|
||||
user_friendly: bool = False,
|
||||
) -> list[str]:
|
||||
"""
|
||||
Get multple tabs urls
|
||||
Get multiple tabs urls.
|
||||
|
||||
Each per-tab permalink preserves the original ``dashboard_state``
|
||||
``urlParams`` (e.g. ``standalone=true``) and merges in the report's
|
||||
``native_filters`` with the same precedence rules as the single-tab
|
||||
branch. Per-tab fields (``anchor``, ``activeTabs``) are overridden
|
||||
for each tab in the fan-out.
|
||||
"""
|
||||
base_state: DashboardPermalinkState = dashboard_state or {}
|
||||
existing_params: list[tuple[str, str]] = base_state.get("urlParams") or []
|
||||
merged_params: list[list[str]] = [
|
||||
list(p) for p in existing_params if p[0] != "native_filters"
|
||||
]
|
||||
merged_params.append(["native_filters", native_filter_params or ""])
|
||||
|
||||
return [
|
||||
self._get_tab_url(
|
||||
{
|
||||
**base_state,
|
||||
"anchor": tab_anchor,
|
||||
"dataMask": None,
|
||||
"activeTabs": None,
|
||||
"urlParams": [
|
||||
["native_filters", native_filter_params] # type: ignore
|
||||
],
|
||||
"activeTabs": [tab_anchor],
|
||||
"urlParams": merged_params, # type: ignore[typeddict-item]
|
||||
},
|
||||
user_friendly=user_friendly,
|
||||
)
|
||||
|
||||
@@ -624,6 +624,73 @@ def test_get_tab_urls(
|
||||
]
|
||||
|
||||
|
||||
@patch("superset.commands.report.execute.CreateDashboardPermalinkCommand")
|
||||
@with_feature_flags(ALERT_REPORT_TABS=True)
|
||||
def test_get_dashboard_urls_multitab_preserves_url_params(
|
||||
mock_permalink_cls,
|
||||
mocker: MockerFixture,
|
||||
app,
|
||||
) -> None:
|
||||
"""Multi-tab fan-out must preserve dashboard_state.urlParams (e.g. standalone)
|
||||
and per-tab anchor/activeTabs, the same way the single-tab branch does."""
|
||||
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.type = "report_type"
|
||||
mock_report_schedule.report_format = "report_format"
|
||||
mock_report_schedule.owners = [1, 2]
|
||||
mock_report_schedule.recipients = []
|
||||
native_filter_rison = "(NATIVE_FILTER-1:(filterType:filter_select))"
|
||||
mock_report_schedule.extra = {
|
||||
"dashboard": {
|
||||
"anchor": json.dumps(["TAB-1", "TAB-2"]),
|
||||
"dataMask": {"NATIVE_FILTER-1": {"filterState": {"value": ["Sales"]}}},
|
||||
"activeTabs": ["irrelevant"],
|
||||
"urlParams": [("standalone", "true"), ("show_filters", "0")],
|
||||
"nativeFilters": [ # type: ignore[typeddict-unknown-key]
|
||||
{
|
||||
"nativeFilterId": "NATIVE_FILTER-1",
|
||||
"filterType": "filter_select",
|
||||
"columnName": "department",
|
||||
"filterValues": ["Sales"],
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
mock_report_schedule.get_native_filters_params.return_value = ( # type: ignore[attr-defined]
|
||||
native_filter_rison,
|
||||
[],
|
||||
)
|
||||
mock_permalink_cls.return_value.run.side_effect = ["key1", "key2"]
|
||||
|
||||
class_instance: BaseReportState = BaseReportState(
|
||||
mock_report_schedule, "January 1, 2021", "execution_id_example"
|
||||
)
|
||||
class_instance._report_schedule = mock_report_schedule
|
||||
|
||||
class_instance.get_dashboard_urls()
|
||||
|
||||
assert mock_permalink_cls.call_count == 2
|
||||
for idx, expected_anchor in enumerate(["TAB-1", "TAB-2"]):
|
||||
state = mock_permalink_cls.call_args_list[idx].kwargs["state"]
|
||||
# urlParams from the original dashboard_state are preserved and the
|
||||
# report's native_filters is appended.
|
||||
assert state["urlParams"] == [
|
||||
["standalone", "true"],
|
||||
["show_filters", "0"],
|
||||
["native_filters", native_filter_rison],
|
||||
]
|
||||
# Each per-tab permalink targets exactly that tab.
|
||||
assert state["anchor"] == expected_anchor
|
||||
assert state["activeTabs"] == [expected_anchor]
|
||||
# dataMask from the user-supplied dashboard_state is preserved
|
||||
# (the previous implementation cleared it to None).
|
||||
assert state["dataMask"] == {
|
||||
"NATIVE_FILTER-1": {"filterState": {"value": ["Sales"]}}
|
||||
}
|
||||
|
||||
|
||||
@patch(
|
||||
"superset.commands.dashboard.permalink.create.CreateDashboardPermalinkCommand.run"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user