diff --git a/superset/commands/dashboard/importers/v1/utils.py b/superset/commands/dashboard/importers/v1/utils.py index 853a77f345..37dfe6d660 100644 --- a/superset/commands/dashboard/importers/v1/utils.py +++ b/superset/commands/dashboard/importers/v1/utils.py @@ -57,6 +57,24 @@ def build_uuid_to_id_map(position: dict[str, Any]) -> dict[str, int]: } +def __fix_charts_references_in_scope( + configuration: dict[str, Any], charts_map: dict[int, int] +) -> dict[str, Any]: + configuration_scope = configuration.get("scope", {}) + if isinstance(configuration_scope, dict): # means is not "global" + if scope_excluded := configuration_scope.get("excluded", []): + configuration_scope["excluded"] = [ + charts_map[old_id] for old_id in scope_excluded if old_id in charts_map + ] + + if charts_in_scope := configuration.get("chartsInScope", []): + configuration["chartsInScope"] = [ + charts_map[old_id] for old_id in charts_in_scope if old_id in charts_map + ] + + return configuration + + def update_id_refs( # pylint: disable=too-many-locals config: dict[str, Any], chart_ids: dict[str, int], @@ -134,17 +152,28 @@ def update_id_refs( # pylint: disable=too-many-locals if dataset_uuid: target["datasetId"] = dataset_info[dataset_uuid]["datasource_id"] - scope_excluded = native_filter.get("scope", {}).get("excluded", []) - if scope_excluded: - native_filter["scope"]["excluded"] = [ - id_map[old_id] for old_id in scope_excluded if old_id in id_map - ] + __fix_charts_references_in_scope(native_filter, id_map) - charts_in_scope = native_filter.get("chartsInScope", []) - if charts_in_scope: - native_filter["chartsInScope"] = [ - id_map[old_id] for old_id in charts_in_scope if old_id in id_map - ] + # fix global chart configuration + global_chart_configuration = fixed.get("metadata", {}).get( + "global_chart_configuration", {} + ) + __fix_charts_references_in_scope(global_chart_configuration, id_map) + + # fix chart configuration + chart_configuration = fixed.get("metadata", {}).get("chart_configuration", {}) + for ( + chart_configuration_key, + chart_configuration_value, + ) in chart_configuration.copy().items(): + if new_chart_configuration_key := id_map.get(int(chart_configuration_key)): + chart_configuration_value["id"] = new_chart_configuration_key + __fix_charts_references_in_scope( + chart_configuration_value["crossFilters"], id_map + ) + chart_configuration[str(new_chart_configuration_key)] = ( + chart_configuration.pop(chart_configuration_key) + ) return fixed diff --git a/tests/unit_tests/dashboards/commands/importers/v1/utils_test.py b/tests/unit_tests/dashboards/commands/importers/v1/utils_test.py index f2d01fccc6..f95661a733 100644 --- a/tests/unit_tests/dashboards/commands/importers/v1/utils_test.py +++ b/tests/unit_tests/dashboards/commands/importers/v1/utils_test.py @@ -82,7 +82,7 @@ def test_update_id_refs_immune_missing( # pylint: disable=invalid-name } -def test_update_native_filter_config_scope_excluded(): +def test_update_charts_reference(): from superset.commands.dashboard.importers.v1.utils import update_id_refs config = { @@ -97,12 +97,61 @@ def test_update_native_filter_config_scope_excluded(): "meta": {"chartId": 102, "uuid": "uuid2"}, "type": "CHART", }, + "CHART3": { + "id": "CHART3", + "meta": {"chartId": 103, "uuid": "uuid3"}, + "type": "CHART", + }, + "CHART4": { + "id": "CHART4", + "meta": {"chartId": 104, "uuid": "uuid4"}, + "type": "CHART", + }, }, "metadata": { - "native_filter_configuration": [{"scope": {"excluded": [101, 102, 103]}}], + "chart_configuration": { + "101": { + "id": 101, + "crossFilters": { + "chartsInScope": [102, 103], + "scope": {"excluded": [101, 110]}, + }, + }, + "102": { + "id": 102, + "crossFilters": { + "chartsInScope": [], + "scope": {"excluded": [101, 102, 103, 110]}, + }, + }, + "103": { + "id": 103, + "crossFilters": { + "chartsInScope": [110], + "scope": {"excluded": [101, 102, 103]}, + }, + }, + "104": { + "id": 104, + "crossFilters": { + "chartsInScope": [110], + "scope": "global", + }, + }, + }, + "global_chart_configuration": { + "chartsInScope": [101, 103, 110], + "scope": {"excluded": [102, 110]}, + }, + "native_filter_configuration": [ + { + "chartsInScope": [101, 102, 103, 110], + "scope": {"excluded": [101, 102, 103, 110]}, + } + ], }, } - chart_ids = {"uuid1": 1, "uuid2": 2} + chart_ids = {"uuid1": 1, "uuid2": 2, "uuid3": 3, "uuid4": 4} dataset_info: dict[str, dict[str, Any]] = {} # not used fixed = update_id_refs(config, chart_ids, dataset_info) @@ -118,47 +167,54 @@ def test_update_native_filter_config_scope_excluded(): "meta": {"chartId": 2, "uuid": "uuid2"}, "type": "CHART", }, - }, - "metadata": {"native_filter_configuration": [{"scope": {"excluded": [1, 2]}}]}, - } - - -def test_update_native_filter_charts_in_scope(): - from superset.commands.dashboard.importers.v1.utils import update_id_refs - - config = { - "position": { - "CHART1": { - "id": "CHART1", - "meta": {"chartId": 101, "uuid": "uuid1"}, + "CHART3": { + "id": "CHART3", + "meta": {"chartId": 3, "uuid": "uuid3"}, "type": "CHART", }, - "CHART2": { - "id": "CHART2", - "meta": {"chartId": 102, "uuid": "uuid2"}, + "CHART4": { + "id": "CHART4", + "meta": {"chartId": 4, "uuid": "uuid4"}, "type": "CHART", }, }, "metadata": { - "native_filter_configuration": [{"chartsInScope": [101, 102, 103]}], + "chart_configuration": { + "1": { + "id": 1, + "crossFilters": { + "chartsInScope": [2, 3], + "scope": {"excluded": [1]}, + }, + }, + "2": { + "id": 2, + "crossFilters": { + "chartsInScope": [], + "scope": {"excluded": [1, 2, 3]}, + }, + }, + "3": { + "id": 3, + "crossFilters": { + "chartsInScope": [], + "scope": {"excluded": [1, 2, 3]}, + }, + }, + "4": { + "id": 4, + "crossFilters": { + "chartsInScope": [], + "scope": "global", + }, + }, + }, + "global_chart_configuration": { + "chartsInScope": [1, 3], + "scope": {"excluded": [2]}, + }, + "native_filter_configuration": [ + {"chartsInScope": [1, 2, 3], "scope": {"excluded": [1, 2, 3]}} + ], }, } - chart_ids = {"uuid1": 1, "uuid2": 2} - dataset_info: dict[str, dict[str, Any]] = {} # not used - - fixed = update_id_refs(config, chart_ids, dataset_info) - assert fixed == { - "position": { - "CHART1": { - "id": "CHART1", - "meta": {"chartId": 1, "uuid": "uuid1"}, - "type": "CHART", - }, - "CHART2": { - "id": "CHART2", - "meta": {"chartId": 2, "uuid": "uuid2"}, - "type": "CHART", - }, - }, - "metadata": {"native_filter_configuration": [{"chartsInScope": [1, 2]}]}, - }