This is an automated email from the ASF dual-hosted git repository.

beto pushed a commit to branch sc_74253
in repository https://gitbox.apache.org/repos/asf/superset.git

commit e2cfd6ecd3ee4a5e4964ccf39e7130e4e6f477ab
Author: Beto Dealmeida <[email protected]>
AuthorDate: Tue Sep 5 16:43:30 2023 -0700

    Save outdated chart and reload
---
 .../explore/components/ExploreChartPanel/index.jsx | 30 ++++++++++++++++++++++
 superset-frontend/src/types/Chart.ts               |  1 +
 superset/charts/api.py                             |  1 +
 superset/charts/schemas.py                         | 10 ++++++++
 superset/explore/schemas.py                        |  5 ++++
 superset/models/slice.py                           |  5 ++++
 6 files changed, 52 insertions(+)

diff --git 
a/superset-frontend/src/explore/components/ExploreChartPanel/index.jsx 
b/superset-frontend/src/explore/components/ExploreChartPanel/index.jsx
index 984b389a5c..4fa45501f9 100644
--- a/superset-frontend/src/explore/components/ExploreChartPanel/index.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartPanel/index.jsx
@@ -172,6 +172,36 @@ const ExploreChartPanel = ({
     chart.chartStatus !== 'failed' &&
     ensureIsArray(chart.queriesResponse).length > 0;
 
+  /* When feature flags are toggled we might need to resave the chart to 
update all
+   * required parameters. This can be done by setting `Slice.outdated` to 
false in a
+   * migration or manually. */
+  const updateChart = useCallback(
+    async function overwriteChart() {
+      if (slice.outdated) {
+        await SupersetClient.put({
+          endpoint: `/api/v1/chart/${slice.slice_id}`,
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify({
+            query_context: slice.query_context,
+            params: JSON.stringify(slice.form_data),
+            outdated: false,
+          }),
+        });
+        // TODO: update slice in the parent and trigger render
+        window.location.reload();
+      }
+    },
+    [slice],
+  );
+
+  useEffect(() => {
+    updateChart();
+  }, [updateChart]);
+
+  /* Orignally charts could be saved without `Slice.query_context`, but the 
field is
+   * needed for alerts & reports and can only be computed by the visualization 
Javascript
+   * code. Because of this, when we encounter a chart where the field is null 
we compute
+   * and store it. */
   const updateQueryContext = useCallback(
     async function fetchChartData() {
       if (slice && slice.query_context === null) {
diff --git a/superset-frontend/src/types/Chart.ts 
b/superset-frontend/src/types/Chart.ts
index f26525cd33..649de90a4d 100644
--- a/superset-frontend/src/types/Chart.ts
+++ b/superset-frontend/src/types/Chart.ts
@@ -74,6 +74,7 @@ export type Slice = {
   query_context?: object;
   is_managed_externally: boolean;
   owners?: number[];
+  outdated?: boolean;
 };
 
 export default Chart;
diff --git a/superset/charts/api.py b/superset/charts/api.py
index 768d330291..d8ca3d6c15 100644
--- a/superset/charts/api.py
+++ b/superset/charts/api.py
@@ -194,6 +194,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
         "thumbnail_url",
         "url",
         "viz_type",
+        "outdated",
         "tags.id",
         "tags.name",
         "tags.type",
diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py
index 6476c409ec..c83ea057d5 100644
--- a/superset/charts/schemas.py
+++ b/superset/charts/schemas.py
@@ -162,6 +162,11 @@ class ChartEntityResponseSchema(Schema):
     description_markeddown = fields.String(
         metadata={"description": description_markeddown_description}
     )
+    outdated = fields.Boolean(
+        metadata={
+            "description": "Does the chart need to be re-saved to update 
metadata?"
+        }
+    )
     form_data = fields.Dict(metadata={"description": form_data_description})
     slice_url = fields.String(metadata={"description": slice_url_description})
     certified_by = fields.String(metadata={"description": 
certified_by_description})
@@ -285,6 +290,11 @@ class ChartPutSchema(Schema):
     is_managed_externally = fields.Boolean(allow_none=True, dump_default=False)
     external_url = fields.String(allow_none=True)
     tags = fields.Nested(TagSchema, many=True)
+    outdated = fields.Boolean(
+        metadata={
+            "description": "Does the chart need to be re-saved to update 
metadata?"
+        }
+    )
 
 
 class ChartGetDatasourceObjectDataResponseSchema(Schema):
diff --git a/superset/explore/schemas.py b/superset/explore/schemas.py
index 75c3dcac2c..421bebcd92 100644
--- a/superset/explore/schemas.py
+++ b/superset/explore/schemas.py
@@ -147,6 +147,11 @@ class SliceSchema(Schema):
     slice_id = fields.Integer(metadata={"description": "The slice ID."})
     slice_name = fields.String(metadata={"description": "The slice name."})
     slice_url = fields.String(metadata={"description": "The slice URL."})
+    oudated = fields.Boolean(
+        metadata={
+            "description": "Does the chart need to be re-saved to update 
metadata?"
+        }
+    )
 
 
 class ExploreContextSchema(Schema):
diff --git a/superset/models/slice.py b/superset/models/slice.py
index 248f4ee947..6b42b917c4 100644
--- a/superset/models/slice.py
+++ b/superset/models/slice.py
@@ -118,6 +118,10 @@ class Slice(  # pylint: disable=too-many-public-methods
         lazy="subquery",
     )
 
+    # force the chart to re-save itself; this is useful when the backend has 
missing
+    # information that can only be computed by the frontend
+    outdated = Column(Boolean, nullable=True, default=False)
+
     token = ""
 
     export_fields = [
@@ -247,6 +251,7 @@ class Slice(  # pylint: disable=too-many-public-methods
             "certified_by": self.certified_by,
             "certification_details": self.certification_details,
             "is_managed_externally": self.is_managed_externally,
+            "outdated": self.outdated,
         }
 
     @property

Reply via email to