betodealmeida commented on a change in pull request #17570:
URL: https://github.com/apache/superset/pull/17570#discussion_r763526321



##########
File path: superset/dashboards/dao.py
##########
@@ -173,79 +173,103 @@ def bulk_delete(models: Optional[List[Dashboard]], 
commit: bool = True) -> None:
             raise ex
 
     @staticmethod
-    def set_dash_metadata(
+    def set_dash_metadata(  # pylint: disable=too-many-locals
         dashboard: Dashboard,
         data: Dict[Any, Any],
         old_to_new_slice_ids: Optional[Dict[int, int]] = None,
-    ) -> None:
-        positions = data["positions"]
-        # find slices in the position data
-        slice_ids = [
-            value.get("meta", {}).get("chartId")
-            for value in positions.values()
-            if isinstance(value, dict)
-        ]
-
-        session = db.session()
-        current_slices = 
session.query(Slice).filter(Slice.id.in_(slice_ids)).all()
-
-        dashboard.slices = current_slices
-
-        # add UUID to positions
-        uuid_map = {slice.id: str(slice.uuid) for slice in current_slices}
-        for obj in positions.values():
-            if (
-                isinstance(obj, dict)
-                and obj["type"] == "CHART"
-                and obj["meta"]["chartId"]
-            ):
-                chart_id = obj["meta"]["chartId"]
-                obj["meta"]["uuid"] = uuid_map.get(chart_id)
-
-        # remove leading and trailing white spaces in the dumped json
-        dashboard.position_json = json.dumps(
-            positions, indent=None, separators=(",", ":"), sort_keys=True
-        )
+        commit: bool = False,
+    ) -> Dashboard:
+        positions = data.get("positions")
+        new_filter_scopes = {}
         md = dashboard.params_dict
-        dashboard.css = data.get("css")
-        dashboard.dashboard_title = data["dashboard_title"]
 
-        if "timed_refresh_immune_slices" not in md:
-            md["timed_refresh_immune_slices"] = []
-        new_filter_scopes = {}
-        if "filter_scopes" in data:
-            # replace filter_id and immune ids from old slice id to new slice 
id:
-            # and remove slice ids that are not in dash anymore
-            slc_id_dict: Dict[int, int] = {}
-            if old_to_new_slice_ids:
-                slc_id_dict = {
-                    old: new
-                    for old, new in old_to_new_slice_ids.items()
-                    if new in slice_ids
-                }
-            else:
-                slc_id_dict = {sid: sid for sid in slice_ids}
-            new_filter_scopes = copy_filter_scopes(
-                old_to_new_slc_id_dict=slc_id_dict,
-                old_filter_scopes=json.loads(data["filter_scopes"] or "{}"),
+        if positions is not None:
+            # find slices in the position data
+            slice_ids = [
+                value.get("meta", {}).get("chartId")
+                for value in positions.values()
+                if isinstance(value, dict)
+            ]
+
+            session = db.session()
+            current_slices = 
session.query(Slice).filter(Slice.id.in_(slice_ids)).all()
+
+            dashboard.slices = current_slices
+
+            # add UUID to positions
+            uuid_map = {slice.id: str(slice.uuid) for slice in current_slices}
+            for obj in positions.values():
+                if (
+                    isinstance(obj, dict)
+                    and obj["type"] == "CHART"
+                    and obj["meta"]["chartId"]
+                ):
+                    chart_id = obj["meta"]["chartId"]
+                    obj["meta"]["uuid"] = uuid_map.get(chart_id)
+
+            # remove leading and trailing white spaces in the dumped json
+            dashboard.position_json = json.dumps(
+                positions, indent=None, separators=(",", ":"), sort_keys=True
             )
+
+            if "filter_scopes" in data:
+                # replace filter_id and immune ids from old slice id to new 
slice id:
+                # and remove slice ids that are not in dash anymore
+                slc_id_dict: Dict[int, int] = {}
+                if old_to_new_slice_ids:
+                    slc_id_dict = {
+                        old: new
+                        for old, new in old_to_new_slice_ids.items()
+                        if new in slice_ids
+                    }
+                else:
+                    slc_id_dict = {sid: sid for sid in slice_ids}
+                new_filter_scopes = copy_filter_scopes(
+                    old_to_new_slc_id_dict=slc_id_dict,
+                    old_filter_scopes=json.loads(data["filter_scopes"] or "{}")
+                    if isinstance(data["filter_scopes"], str)
+                    else data["filter_scopes"],
+                )
+
+            default_filters_data = json.loads(data.get("default_filters", 
"{}"))
+            applicable_filters = {
+                key: v
+                for key, v in default_filters_data.items()
+                if int(key) in slice_ids
+            }
+            md["default_filters"] = json.dumps(applicable_filters)
+
+        # css and dashboard_title are not part of the metadata
+        # TODO remove by refactoring/deprecating save_dash endpoint

Review comment:
       ```suggestion
           # TODO (geido): remove by refactoring/deprecating save_dash endpoint
   ```
   
   I'm planning to write a bot that emails committers that leave TODOs open for 
too long. :)

##########
File path: superset/dashboards/dao.py
##########
@@ -173,79 +173,103 @@ def bulk_delete(models: Optional[List[Dashboard]], 
commit: bool = True) -> None:
             raise ex
 
     @staticmethod
-    def set_dash_metadata(
+    def set_dash_metadata(  # pylint: disable=too-many-locals
         dashboard: Dashboard,
         data: Dict[Any, Any],
         old_to_new_slice_ids: Optional[Dict[int, int]] = None,
-    ) -> None:
-        positions = data["positions"]
-        # find slices in the position data
-        slice_ids = [
-            value.get("meta", {}).get("chartId")
-            for value in positions.values()
-            if isinstance(value, dict)
-        ]
-
-        session = db.session()
-        current_slices = 
session.query(Slice).filter(Slice.id.in_(slice_ids)).all()
-
-        dashboard.slices = current_slices
-
-        # add UUID to positions
-        uuid_map = {slice.id: str(slice.uuid) for slice in current_slices}
-        for obj in positions.values():
-            if (
-                isinstance(obj, dict)
-                and obj["type"] == "CHART"
-                and obj["meta"]["chartId"]
-            ):
-                chart_id = obj["meta"]["chartId"]
-                obj["meta"]["uuid"] = uuid_map.get(chart_id)
-
-        # remove leading and trailing white spaces in the dumped json
-        dashboard.position_json = json.dumps(
-            positions, indent=None, separators=(",", ":"), sort_keys=True
-        )
+        commit: bool = False,
+    ) -> Dashboard:
+        positions = data.get("positions")
+        new_filter_scopes = {}
         md = dashboard.params_dict
-        dashboard.css = data.get("css")
-        dashboard.dashboard_title = data["dashboard_title"]
 
-        if "timed_refresh_immune_slices" not in md:
-            md["timed_refresh_immune_slices"] = []
-        new_filter_scopes = {}
-        if "filter_scopes" in data:
-            # replace filter_id and immune ids from old slice id to new slice 
id:
-            # and remove slice ids that are not in dash anymore
-            slc_id_dict: Dict[int, int] = {}
-            if old_to_new_slice_ids:
-                slc_id_dict = {
-                    old: new
-                    for old, new in old_to_new_slice_ids.items()
-                    if new in slice_ids
-                }
-            else:
-                slc_id_dict = {sid: sid for sid in slice_ids}
-            new_filter_scopes = copy_filter_scopes(
-                old_to_new_slc_id_dict=slc_id_dict,
-                old_filter_scopes=json.loads(data["filter_scopes"] or "{}"),
+        if positions is not None:
+            # find slices in the position data
+            slice_ids = [
+                value.get("meta", {}).get("chartId")
+                for value in positions.values()
+                if isinstance(value, dict)
+            ]
+
+            session = db.session()
+            current_slices = 
session.query(Slice).filter(Slice.id.in_(slice_ids)).all()
+
+            dashboard.slices = current_slices
+
+            # add UUID to positions
+            uuid_map = {slice.id: str(slice.uuid) for slice in current_slices}
+            for obj in positions.values():
+                if (
+                    isinstance(obj, dict)
+                    and obj["type"] == "CHART"
+                    and obj["meta"]["chartId"]
+                ):
+                    chart_id = obj["meta"]["chartId"]
+                    obj["meta"]["uuid"] = uuid_map.get(chart_id)
+
+            # remove leading and trailing white spaces in the dumped json
+            dashboard.position_json = json.dumps(
+                positions, indent=None, separators=(",", ":"), sort_keys=True
             )
+
+            if "filter_scopes" in data:
+                # replace filter_id and immune ids from old slice id to new 
slice id:
+                # and remove slice ids that are not in dash anymore
+                slc_id_dict: Dict[int, int] = {}
+                if old_to_new_slice_ids:
+                    slc_id_dict = {
+                        old: new
+                        for old, new in old_to_new_slice_ids.items()
+                        if new in slice_ids
+                    }
+                else:
+                    slc_id_dict = {sid: sid for sid in slice_ids}
+                new_filter_scopes = copy_filter_scopes(
+                    old_to_new_slc_id_dict=slc_id_dict,
+                    old_filter_scopes=json.loads(data["filter_scopes"] or "{}")
+                    if isinstance(data["filter_scopes"], str)
+                    else data["filter_scopes"],
+                )
+
+            default_filters_data = json.loads(data.get("default_filters", 
"{}"))
+            applicable_filters = {
+                key: v
+                for key, v in default_filters_data.items()
+                if int(key) in slice_ids
+            }
+            md["default_filters"] = json.dumps(applicable_filters)
+
+        # css and dashboard_title are not part of the metadata
+        # TODO remove by refactoring/deprecating save_dash endpoint
+        if data.get("css") is not None:
+            dashboard.css = data.get("css")
+        if data.get("dashboard_title") is not None:
+            dashboard.dashboard_title = data.get("dashboard_title")
+
         if new_filter_scopes:
             md["filter_scopes"] = new_filter_scopes
         else:
             md.pop("filter_scopes", None)
+
+        if "timed_refresh_immune_slices" not in md:
+            md["timed_refresh_immune_slices"] = []

Review comment:
       Python dictionaries have an odd-named method for this:
   
   ```suggestion
           md.setdefault("timed_refresh_immune_slices", [])
   ```

##########
File path: superset/dashboards/commands/update.py
##########
@@ -51,6 +52,12 @@ def run(self) -> Model:
         try:
             dashboard = DashboardDAO.update(self._model, self._properties, 
commit=False)
             dashboard = DashboardDAO.update_charts_owners(dashboard, 
commit=True)
+            if self._properties.get("json_metadata") is not None:
+                dashboard = DashboardDAO.set_dash_metadata(
+                    dashboard,
+                    data=json.loads(self._properties.get("json_metadata", 
"{}")),

Review comment:
       If for some reason `json_metadata` is an empty string this would raise 
an error:
   
   ```python
   >>> properties = {'json_metadata': ''}
   >>> properties.get('json_metadata') is not None
   True
   >>> json.loads(properties.get("json_metadata", "{}"))
   json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
   ```
   
   You might wanna do instead:
   
   ```suggestion
               if self._properties.get("json_metadata"):
                   dashboard = DashboardDAO.set_dash_metadata(
                       dashboard,
                       data=json.loads(self._properties.get("json_metadata", 
"{}")),
   ```




-- 
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]

Reply via email to