fix(dashboard): update cross filter scoping chart id references during dashboard import (#34418)

Co-authored-by: chanduapple <80615671+chanduapple@users.noreply.github.com>
Co-authored-by: chandrasekhar jandhyam <chandrasekhar.jandhyam@digital.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Trent Schmidt
2025-08-17 21:41:38 -07:00
committed by GitHub
parent fbcdf6909c
commit ff6dc03ddf
2 changed files with 126 additions and 0 deletions

View File

@@ -139,7 +139,55 @@ def update_id_refs( # pylint: disable=too-many-locals # noqa: C901
native_filter["scope"]["excluded"] = [
id_map[old_id] for old_id in scope_excluded if old_id in id_map
]
fixed = update_cross_filter_scoping(fixed, id_map)
return fixed
def update_cross_filter_scoping(
config: dict[str, Any], id_map: dict[int, int]
) -> dict[str, Any]:
# fix cross filter references
fixed = config.copy()
cross_filter_global_config = fixed.get("metadata", {}).get(
"global_chart_configuration", {}
)
scope_excluded = cross_filter_global_config.get("scope", {}).get("excluded", [])
if scope_excluded:
cross_filter_global_config["scope"]["excluded"] = [
id_map[old_id] for old_id in scope_excluded if old_id in id_map
]
if "chart_configuration" in (metadata := fixed.get("metadata", {})):
# Build remapped configuration in a single pass for clarity/readability.
new_chart_configuration: dict[str, Any] = {}
for old_id_str, chart_config in metadata["chart_configuration"].items():
try:
old_id_int = int(old_id_str)
except (TypeError, ValueError):
continue
new_id = id_map.get(old_id_int)
if new_id is None:
continue
if isinstance(chart_config, dict):
chart_config["id"] = new_id
# Update cross filter scope excluded ids
scope = chart_config.get("crossFilters", {}).get("scope", {})
if isinstance(scope, dict):
excluded_scope = scope.get("excluded", [])
if excluded_scope:
chart_config["crossFilters"]["scope"]["excluded"] = [
id_map[old_id]
for old_id in excluded_scope
if old_id in id_map
]
new_chart_configuration[str(new_id)] = chart_config
metadata["chart_configuration"] = new_chart_configuration
return fixed

View File

@@ -121,3 +121,81 @@ def test_update_native_filter_config_scope_excluded():
},
"metadata": {"native_filter_configuration": [{"scope": {"excluded": [1, 2]}}]},
}
def test_update_id_refs_cross_filter_chart_configuration_key_and_excluded_mapping():
from superset.commands.dashboard.importers.v1.utils import update_id_refs
# Build a minimal dashboard position with uuids -> old ids
config: dict[str, Any] = {
"position": {
"CHART1": {
"id": "CHART1",
"meta": {"chartId": 101, "uuid": "uuid1"},
"type": "CHART",
},
"CHART2": {
"id": "CHART2",
"meta": {"chartId": 102, "uuid": "uuid2"},
"type": "CHART",
},
},
"metadata": {
"chart_configuration": {
"101": {
"id": 101,
"crossFilters": {"scope": {"excluded": [102, 103]}},
},
"104": {"crossFilters": {"scope": {"excluded": [105]}}},
},
"global_chart_configuration": {"scope": {"excluded": [102, 999]}},
},
}
chart_ids = {"uuid1": 1, "uuid2": 2}
dataset_info: dict[str, dict[str, Any]] = {}
fixed = update_id_refs(config, chart_ids, dataset_info)
metadata = fixed["metadata"]
# Expect top-level key remapped from "101" to "1"
assert "1" in metadata["chart_configuration"]
assert "101" not in metadata["chart_configuration"]
chart_config = metadata["chart_configuration"]["1"]
# Expect inner id updated to new id
assert chart_config.get("id") == 1
# Expect excluded list remapped and unknown ids dropped
assert chart_config["crossFilters"]["scope"]["excluded"] == [2]
# Expect entries without id_map mapping to be dropped
assert "104" not in metadata["chart_configuration"]
# Expect global scope excluded remapped too
assert metadata["global_chart_configuration"]["scope"]["excluded"] == [2]
def test_update_id_refs_cross_filter_handles_string_excluded():
from superset.commands.dashboard.importers.v1.utils import update_id_refs
config: dict[str, Any] = {
"position": {
"CHART1": {
"id": "CHART1",
"meta": {"chartId": 101, "uuid": "uuid1"},
"type": "CHART",
},
},
"metadata": {
"chart_configuration": {
"101": {"crossFilters": {"scope": {"excluded": "all"}}}
}
},
}
chart_ids = {"uuid1": 1}
dataset_info: dict[str, dict[str, Any]] = {}
fixed = update_id_refs(config, chart_ids, dataset_info)
# Should not raise and should remap key
assert "1" in fixed["metadata"]["chart_configuration"]