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

diegopucci pushed a commit to branch chore/color-scheme-updates
in repository https://gitbox.apache.org/repos/asf/superset.git

commit b8a08372226b78dc83bf8a3e5df4813718486c25
Author: geido <[email protected]>
AuthorDate: Fri Jul 1 17:37:26 2022 +0300

    Update dashboard colors
---
 .../src/dashboard/actions/dashboardState.js        |  1 +
 .../DashboardBuilder/DashboardContainer.tsx        | 70 ++++++++++++++++++++++
 .../dashboard/components/PropertiesModal/index.tsx | 14 ++++-
 .../src/explore/actions/hydrateExplore.ts          |  6 +-
 .../controls/ColorSchemeControl/index.jsx          |  2 +-
 superset/dashboards/dao.py                         |  2 +-
 superset/dashboards/schemas.py                     |  1 +
 7 files changed, 89 insertions(+), 7 deletions(-)

diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js 
b/superset-frontend/src/dashboard/actions/dashboardState.js
index f96b3ebadf..204bd14e3a 100644
--- a/superset-frontend/src/dashboard/actions/dashboardState.js
+++ b/superset-frontend/src/dashboard/actions/dashboardState.js
@@ -240,6 +240,7 @@ export function saveDashboardRequest(data, id, saveType) {
         ...data.metadata,
         color_namespace: data.metadata?.color_namespace || undefined,
         color_scheme: data.metadata?.color_scheme || '',
+        color_scheme_domain: data.metadata?.color_scheme_domain || [],
         expanded_slices: data.metadata?.expanded_slices || {},
         label_colors: data.metadata?.label_colors || {},
         shared_label_colors: data.metadata?.shared_label_colors || {},
diff --git 
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
 
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
index c763f07267..f7083b9046 100644
--- 
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
+++ 
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx
@@ -24,7 +24,10 @@ import {
   FeatureFlag,
   Filter,
   Filters,
+  getCategoricalSchemeRegistry,
+  getSharedLabelColor,
   isFeatureEnabled,
+  SupersetClient,
 } from '@superset-ui/core';
 import { ParentSize } from '@vx/responsive';
 import pick from 'lodash/pick';
@@ -32,6 +35,7 @@ import Tabs from 'src/components/Tabs';
 import DashboardGrid from 'src/dashboard/containers/DashboardGrid';
 import {
   ChartsState,
+  DashboardInfo,
   DashboardLayout,
   LayoutItem,
   RootState,
@@ -46,6 +50,9 @@ import { setInScopeStatusOfFilters } from 
'src/dashboard/actions/nativeFilters';
 import { getRootLevelTabIndex, getRootLevelTabsComponent } from './utils';
 import { findTabsWithChartsInScope } from '../nativeFilters/utils';
 import { NATIVE_FILTER_DIVIDER_PREFIX } from 
'../nativeFilters/FiltersConfigModal/utils';
+import { dashboardInfoChanged } from 'src/dashboard/actions/dashboardInfo';
+import { setColorScheme } from 'src/dashboard/actions/dashboardState';
+import jsonStringify from 'json-stringify-pretty-compact';
 
 type DashboardContainerProps = {
   topLevelTabs?: LayoutItem;
@@ -73,6 +80,9 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ 
topLevelTabs }) => {
   const dashboardLayout = useSelector<RootState, DashboardLayout>(
     state => state.dashboardLayout.present,
   );
+  const dashboardInfo = useSelector<RootState, DashboardInfo>(
+    state => state.dashboardInfo,
+  );
   const directPathToChild = useSelector<RootState, string[]>(
     state => state.dashboardState.directPathToChild,
   );
@@ -122,6 +132,65 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ 
topLevelTabs }) => {
     dispatch(setInScopeStatusOfFilters(scopes));
   }, [nativeFilterScopes, dashboardLayout, dispatch]);
 
+  useEffect(() => {
+    const currentMetadata = 
+      dashboardInfo.json_metadata?.length && 
JSON.parse(dashboardInfo.json_metadata);
+      if (currentMetadata?.color_scheme) {
+        const metadata = {...currentMetadata};
+        const colorScheme = metadata?.color_scheme;
+        const colorSchemeDomain = metadata?.color_scheme_domain || [];
+        const colorNamespace = metadata?.color_namespace || '';
+        const categoricalSchemes = getCategoricalSchemeRegistry();
+        const registryColorSchemeDomain = 
categoricalSchemes.get(colorScheme)?.colors || [];
+        const defaultColorScheme = categoricalSchemes.defaultKey;
+        const isColorSchemeExisting = !!categoricalSchemes.get(colorScheme);
+        const updateDashboard = () => {
+          SupersetClient.put({
+            endpoint: `/api/v1/dashboard/${dashboardInfo.id}`,
+            headers: { 'Content-Type': 'application/json' },
+            body: JSON.stringify({
+              json_metadata: jsonStringify(metadata),
+            }),
+          }).then(() => {
+            dispatch(dashboardInfoChanged({
+              metadata,
+            }));
+            dispatch(setColorScheme(defaultColorScheme))
+          })
+        }
+        const genColorMap = (scheme: string, update = false) => {
+          // TODO: to check why colorMap is always empty
+          const colorMap = getSharedLabelColor().getColorMap(
+            colorNamespace,
+            scheme,
+            update,
+          );
+          return colorMap;
+        }
+
+        // color scheme does not exist anymore
+        // must fallback to the available default one
+        if (colorScheme && !isColorSchemeExisting) {
+          const updatedScheme = defaultColorScheme?.toString() || 
'supersetColors';
+          metadata.color_scheme = updatedScheme;
+          metadata.shared_label_colors = genColorMap(updatedScheme, true);
+          metadata.color_scheme_domain = 
categoricalSchemes.get(defaultColorScheme)?.colors;
+          updateDashboard();
+          return;
+        }
+
+        // if this dashboard does not have a color_scheme_domain saved must 
create one
+        // if the color_scheme_domain does not correspond to the registry must 
update
+        if (
+          colorScheme && 
+          ((!colorSchemeDomain.length) || 
(registryColorSchemeDomain.toString() !== colorSchemeDomain.toString()))) {
+          metadata.color_scheme_domain = registryColorSchemeDomain;
+          metadata.shared_label_colors = genColorMap(colorScheme, true);
+          updateDashboard();
+        }
+      }
+  }, [dashboardInfo.json_metadata, dispatch])
+
   const childIds: string[] = topLevelTabs
     ? topLevelTabs.children
     : [DASHBOARD_GRID_ID];
@@ -171,3 +240,4 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ 
topLevelTabs }) => {
 };
 
 export default DashboardContainer;
+
diff --git 
a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx 
b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
index effd18b3d0..dc554c4e22 100644
--- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
+++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
@@ -173,10 +173,14 @@ const PropertiesModal = ({
       if (metadata?.positions) {
         delete metadata.positions;
       }
-      const metaDataCopy = { ...metadata };
+      const metaDataCopy = { ...metadata }; 
+      
       if (metaDataCopy?.shared_label_colors) {
         delete metaDataCopy.shared_label_colors;
       }
+      if (metaDataCopy?.color_scheme_domain) {
+        delete metaDataCopy.color_scheme_domain;
+      }
       setJsonMetadata(metaDataCopy ? jsonStringify(metaDataCopy) : '');
     },
     [form],
@@ -262,7 +266,8 @@ const PropertiesModal = ({
     { updateMetadata = true } = {},
   ) => {
     // check that color_scheme is valid
-    const colorChoices = getCategoricalSchemeRegistry().keys();
+    const categoricalSchemeRegistry = getCategoricalSchemeRegistry();
+    const colorChoices = categoricalSchemeRegistry.keys();
     const jsonMetadataObj = getJsonMetadata();
 
     // only fire if the color_scheme is present and invalid
@@ -279,6 +284,8 @@ const PropertiesModal = ({
     if (updateMetadata) {
       jsonMetadataObj.color_scheme = colorScheme;
       jsonMetadataObj.label_colors = jsonMetadataObj.label_colors || {};
+      jsonMetadataObj.color_scheme_domain = 
+        categoricalSchemeRegistry.get(colorScheme)?.colors || [];
 
       setJsonMetadata(jsonStringify(jsonMetadataObj));
     }
@@ -302,6 +309,9 @@ const PropertiesModal = ({
       if (metadata?.shared_label_colors) {
         delete metadata.shared_label_colors;
       }
+      if (metadata?.color_scheme_domain) {
+        delete metadata.color_scheme_domain;
+      }
       const colorMap = getSharedLabelColor().getColorMap(
         colorNamespace,
         currentColorScheme,
diff --git a/superset-frontend/src/explore/actions/hydrateExplore.ts 
b/superset-frontend/src/explore/actions/hydrateExplore.ts
index 454f1449d8..cf7e111d66 100644
--- a/superset-frontend/src/explore/actions/hydrateExplore.ts
+++ b/superset-frontend/src/explore/actions/hydrateExplore.ts
@@ -69,13 +69,13 @@ export const hydrateExplore =
     ) as ControlStateMapping;
     const colorSchemeKey = initialControls['color_scheme'] && 'color_scheme';
     const linearColorSchemeKey = initialControls['linear_color_scheme'] && 
'linear_color_scheme';
-    // verifies whether the current color scheme exists in the registry
-    // if not fallbacks to the default color scheme key
+    // if the color scheme does not exist anymore
+    // fallbacks to the available default key
     const verifyColorScheme = (type: 'CATEGORICAL' | 'SEQUENTIAL') => {
       const schemes = type === 'CATEGORICAL' ? getCategoricalSchemeRegistry() 
: getSequentialSchemeRegistry();
       const key = type === 'CATEGORICAL' ? colorSchemeKey : 
linearColorSchemeKey;
       const currentScheme = initialFormData[key];
-      if (currentScheme && !schemes.items[currentScheme]) {
+      if (currentScheme && !schemes.get[currentScheme]) {
         initialControls[key].value = schemes.defaultKey
       }
     }
diff --git 
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.jsx
 
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.jsx
index f0ccc12398..e12b258c28 100644
--- 
a/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.jsx
+++ 
b/superset-frontend/src/explore/components/controls/ColorSchemeControl/index.jsx
@@ -192,7 +192,7 @@ export default class ColorSchemeControl extends 
React.PureComponent {
       onChange: this.onChange,
       options,
       placeholder: t('Select scheme'),
-      value: currentScheme,
+      value: currentScheme && currentScheme.toString(),
     };
 
     return (
diff --git a/superset/dashboards/dao.py b/superset/dashboards/dao.py
index 62b6843ce2..8e54ef1124 100644
--- a/superset/dashboards/dao.py
+++ b/superset/dashboards/dao.py
@@ -267,7 +267,7 @@ class DashboardDAO(BaseDAO):
         md["color_scheme"] = data.get("color_scheme", "")
         md["label_colors"] = data.get("label_colors", {})
         md["shared_label_colors"] = data.get("shared_label_colors", {})
-
+        md["color_scheme_domain"] = data.get("color_scheme_domain", [])
         dashboard.json_metadata = json.dumps(md)
 
         if commit:
diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py
index d91879f0d8..a930d87d08 100644
--- a/superset/dashboards/schemas.py
+++ b/superset/dashboards/schemas.py
@@ -129,6 +129,7 @@ class DashboardJSONMetadataSchema(Schema):
     positions = fields.Dict(allow_none=True)
     label_colors = fields.Dict()
     shared_label_colors = fields.Dict()
+    color_scheme_domain = fields.List(fields.Str())
     # used for v0 import/export
     import_time = fields.Integer()
     remote_id = fields.Integer()

Reply via email to