You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2023/09/05 23:43:44 UTC
[superset] 01/01: Save outdated chart and reload
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 <ro...@dealmeida.net>
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