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

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


The following commit(s) were added to refs/heads/master by this push:
     new 3311128c5e fix: Reverts #20749 and #20645 (#20796)
3311128c5e is described below

commit 3311128c5e6c5de2ea5d6a2dfeb01ea3179e9af8
Author: Michael S. Molina <[email protected]>
AuthorDate: Wed Jul 20 17:03:19 2022 -0300

    fix: Reverts #20749 and #20645 (#20796)
    
    * Revert "fix: Error when saving datasource from Explore (#20749)"
    
    This reverts commit 92f3621c754a4f3ddb99285aad273296be26567e.
    
    * Revert "refactor: Unify shared datasources reducers and actions (#20645)"
    
    This reverts commit 2a705406e1883834bb6696c1585ef65f787ce7b3.
---
 .../superset-ui-chart-controls/src/types.ts        |  3 -
 superset-frontend/spec/helpers/reducerIndex.ts     |  2 +-
 .../src/components/Chart/chartReducer.ts           |  4 +-
 .../src/dashboard/actions/dashboardState.js        |  2 +-
 .../datasources.ts}                                | 40 ++++++++--
 .../FiltersConfigModal/FiltersConfigForm/utils.ts  |  4 +-
 superset-frontend/src/dashboard/constants.ts       |  4 +-
 .../src/dashboard/containers/Dashboard.ts          |  2 +-
 .../src/dashboard/containers/DashboardPage.tsx     |  2 +-
 .../reducers/datasources.ts}                       | 20 ++---
 superset-frontend/src/dashboard/types.ts           |  8 +-
 .../src/explore/actions/datasourcesActions.test.ts | 85 ++++++++++++++++++++++
 .../actions/datasourcesActions.ts}                 | 51 ++++++-------
 .../src/explore/actions/exploreActions.ts          | 21 ------
 .../src/explore/actions/hydrateExplore.test.ts     |  3 +
 .../src/explore/actions/hydrateExplore.ts          | 12 +--
 .../components/ExploreViewContainer/index.jsx      |  4 +-
 .../reducers/datasourcesReducer.ts}                | 29 +++-----
 .../src/explore/reducers/exploreReducer.js         | 13 ----
 .../src/hooks/apiResources/dashboards.ts           |  5 +-
 superset-frontend/src/views/store.ts               | 33 ++++++++-
 21 files changed, 224 insertions(+), 123 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts 
b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
index e5e1c24a7c..9c3a110fe4 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
@@ -28,7 +28,6 @@ import type {
   QueryFormData,
   QueryFormMetric,
   QueryResponse,
-  GenericDataType,
 } from '@superset-ui/core';
 import { sharedControls } from './shared-controls';
 import sharedControlComponents from './shared-controls/components';
@@ -67,7 +66,6 @@ export interface Dataset {
   id: number;
   type: DatasourceType;
   columns: ColumnMeta[];
-  column_types?: GenericDataType[];
   metrics: Metric[];
   column_format: Record<string, string>;
   verbose_map: Record<string, string>;
@@ -81,7 +79,6 @@ export interface Dataset {
   description: string | null;
   uid?: string;
   owners?: Owner[];
-  table_name?: string;
 }
 
 export interface ControlPanelState {
diff --git a/superset-frontend/spec/helpers/reducerIndex.ts 
b/superset-frontend/spec/helpers/reducerIndex.ts
index 52e49e741e..edfaf7bb5c 100644
--- a/superset-frontend/spec/helpers/reducerIndex.ts
+++ b/superset-frontend/spec/helpers/reducerIndex.ts
@@ -22,7 +22,7 @@ import dashboardInfo from 
'src/dashboard/reducers/dashboardInfo';
 import dashboardState from 'src/dashboard/reducers/dashboardState';
 import dashboardFilters from 'src/dashboard/reducers/dashboardFilters';
 import nativeFilters from 'src/dashboard/reducers/nativeFilters';
-import datasources from 'src/datasource/reducer';
+import datasources from 'src/dashboard/reducers/datasources';
 import sliceEntities from 'src/dashboard/reducers/sliceEntities';
 import dashboardLayout from 'src/dashboard/reducers/undoableDashboardLayout';
 import messageToasts from 'src/components/MessageToasts/reducers';
diff --git a/superset-frontend/src/components/Chart/chartReducer.ts 
b/superset-frontend/src/components/Chart/chartReducer.ts
index 3f15ab56eb..11b498290f 100644
--- a/superset-frontend/src/components/Chart/chartReducer.ts
+++ b/superset-frontend/src/components/Chart/chartReducer.ts
@@ -19,7 +19,7 @@
 /* eslint camelcase: 0 */
 import { t } from '@superset-ui/core';
 import { HYDRATE_DASHBOARD } from 'src/dashboard/actions/hydrate';
-import { DatasourcesActionType } from 'src/datasource/actions';
+import { DatasourcesAction } from 'src/dashboard/actions/datasources';
 import { ChartState } from 'src/explore/types';
 import { getFormDataFromControls } from 'src/explore/controlUtils';
 import { HYDRATE_EXPLORE } from 'src/explore/actions/hydrateExplore';
@@ -198,7 +198,7 @@ export default function chartReducer(
   if (action.type === HYDRATE_DASHBOARD || action.type === HYDRATE_EXPLORE) {
     return { ...action.data.charts };
   }
-  if (action.type === DatasourcesActionType.SET_DATASOURCES) {
+  if (action.type === DatasourcesAction.SET_DATASOURCES) {
     return Object.fromEntries(
       Object.entries(charts).map(([chartId, chart]) => [
         chartId,
diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js 
b/superset-frontend/src/dashboard/actions/dashboardState.js
index fa58336eb8..1b9224a3da 100644
--- a/superset-frontend/src/dashboard/actions/dashboardState.js
+++ b/superset-frontend/src/dashboard/actions/dashboardState.js
@@ -43,13 +43,13 @@ import serializeFilterScopes from 
'src/dashboard/util/serializeFilterScopes';
 import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
 import { safeStringify } from 'src/utils/safeStringify';
 import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
-import { fetchDatasourceMetadata } from 
'src/dashboard/util/fetchDatasourceMetadata';
 import { UPDATE_COMPONENTS_PARENTS_LIST } from './dashboardLayout';
 import {
   setChartConfiguration,
   dashboardInfoChanged,
   SET_CHART_CONFIG_COMPLETE,
 } from './dashboardInfo';
+import { fetchDatasourceMetadata } from './datasources';
 import {
   addFilter,
   removeFilter,
diff --git a/superset-frontend/src/dashboard/util/fetchDatasourceMetadata.ts 
b/superset-frontend/src/dashboard/actions/datasources.ts
similarity index 57%
rename from superset-frontend/src/dashboard/util/fetchDatasourceMetadata.ts
rename to superset-frontend/src/dashboard/actions/datasources.ts
index a70972a892..42004272cc 100644
--- a/superset-frontend/src/dashboard/util/fetchDatasourceMetadata.ts
+++ b/superset-frontend/src/dashboard/actions/datasources.ts
@@ -18,9 +18,39 @@
  */
 import { Dispatch } from 'redux';
 import { SupersetClient } from '@superset-ui/core';
-import { Dataset } from '@superset-ui/chart-controls';
-import { RootState } from 'src/dashboard/types';
-import { setDatasource } from 'src/datasource/actions';
+import { Datasource, RootState } from 'src/dashboard/types';
+
+// update datasources index for Dashboard
+export enum DatasourcesAction {
+  SET_DATASOURCES = 'SET_DATASOURCES',
+  SET_DATASOURCE = 'SET_DATASOURCE',
+}
+
+export type DatasourcesActionPayload =
+  | {
+      type: DatasourcesAction.SET_DATASOURCES;
+      datasources: Datasource[] | null;
+    }
+  | {
+      type: DatasourcesAction.SET_DATASOURCE;
+      key: Datasource['uid'];
+      datasource: Datasource;
+    };
+
+export function setDatasources(datasources: Datasource[] | null) {
+  return {
+    type: DatasourcesAction.SET_DATASOURCES,
+    datasources,
+  };
+}
+
+export function setDatasource(datasource: Datasource, key: string) {
+  return {
+    type: DatasourcesAction.SET_DATASOURCE,
+    key,
+    datasource,
+  };
+}
 
 export function fetchDatasourceMetadata(key: string) {
   return (dispatch: Dispatch, getState: () => RootState) => {
@@ -28,11 +58,11 @@ export function fetchDatasourceMetadata(key: string) {
     const datasource = datasources[key];
 
     if (datasource) {
-      return dispatch(setDatasource(datasource));
+      return dispatch(setDatasource(datasource, key));
     }
 
     return SupersetClient.get({
       endpoint: `/superset/fetch_datasource_metadata?datasourceKey=${key}`,
-    }).then(({ json }) => dispatch(setDatasource(json as Dataset)));
+    }).then(({ json }) => dispatch(setDatasource(json as Datasource, key)));
   };
 }
diff --git 
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts
 
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts
index 1d13d0606a..2a0b7fcad8 100644
--- 
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts
+++ 
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils.ts
@@ -88,7 +88,9 @@ export const datasetToSelectOption = (
 
 // TODO: add column_types field to Dataset
 // We return true if column_types is undefined or empty as a precaution 
against backend failing to return column_types
-export const hasTemporalColumns = (dataset: Dataset) => {
+export const hasTemporalColumns = (
+  dataset: Dataset & { column_types: GenericDataType[] },
+) => {
   const columnTypes = ensureIsArray(dataset?.column_types);
   return (
     columnTypes.length === 0 || columnTypes.includes(GenericDataType.TEMPORAL)
diff --git a/superset-frontend/src/dashboard/constants.ts 
b/superset-frontend/src/dashboard/constants.ts
index dc1a28ea66..ab9d9b5967 100644
--- a/superset-frontend/src/dashboard/constants.ts
+++ b/superset-frontend/src/dashboard/constants.ts
@@ -1,6 +1,6 @@
 /* eslint-disable import/prefer-default-export */
 import { DatasourceType } from '@superset-ui/core';
-import { Dataset } from '@superset-ui/chart-controls';
+import { Datasource } from 'src/dashboard/types';
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,7 +19,7 @@ import { Dataset } from '@superset-ui/chart-controls';
  * specific language governing permissions and limitations
  * under the License.
  */
-export const PLACEHOLDER_DATASOURCE: Dataset = {
+export const PLACEHOLDER_DATASOURCE: Datasource = {
   id: 0,
   type: DatasourceType.Table,
   uid: '_placeholder_',
diff --git a/superset-frontend/src/dashboard/containers/Dashboard.ts 
b/superset-frontend/src/dashboard/containers/Dashboard.ts
index 0930782629..647d774f48 100644
--- a/superset-frontend/src/dashboard/containers/Dashboard.ts
+++ b/superset-frontend/src/dashboard/containers/Dashboard.ts
@@ -24,7 +24,7 @@ import {
   addSliceToDashboard,
   removeSliceFromDashboard,
 } from 'src/dashboard/actions/dashboardState';
-import { setDatasources } from 'src/datasource/actions';
+import { setDatasources } from 'src/dashboard/actions/datasources';
 
 import { triggerQuery } from 'src/components/Chart/chartAction';
 import { logEvent } from 'src/logger/actions';
diff --git a/superset-frontend/src/dashboard/containers/DashboardPage.tsx 
b/superset-frontend/src/dashboard/containers/DashboardPage.tsx
index f219463070..27e17e0f51 100644
--- a/superset-frontend/src/dashboard/containers/DashboardPage.tsx
+++ b/superset-frontend/src/dashboard/containers/DashboardPage.tsx
@@ -36,7 +36,7 @@ import {
   useDashboardDatasets,
 } from 'src/hooks/apiResources';
 import { hydrateDashboard } from 'src/dashboard/actions/hydrate';
-import { setDatasources } from 'src/datasource/actions';
+import { setDatasources } from 'src/dashboard/actions/datasources';
 import injectCustomCss from 'src/dashboard/util/injectCustomCss';
 import setupPlugins from 'src/setup/setupPlugins';
 import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
diff --git a/superset-frontend/src/datasource/reducer.ts 
b/superset-frontend/src/dashboard/reducers/datasources.ts
similarity index 66%
copy from superset-frontend/src/datasource/reducer.ts
copy to superset-frontend/src/dashboard/reducers/datasources.ts
index 476ed750be..864641645e 100644
--- a/superset-frontend/src/datasource/reducer.ts
+++ b/superset-frontend/src/dashboard/reducers/datasources.ts
@@ -17,30 +17,26 @@
  * under the License.
  */
 import { keyBy } from 'lodash';
-import { getDatasourceUid } from 'src/utils/getDatasourceUid';
+import { DatasourcesState } from 'src/dashboard/types';
 import {
+  DatasourcesActionPayload,
   DatasourcesAction,
-  DatasourcesActionType,
-} from 'src/datasource/actions';
-import { Dataset } from '@superset-ui/chart-controls';
+} from '../actions/datasources';
 
 export default function datasourcesReducer(
-  datasources: { [key: string]: Dataset } | undefined,
-  action: DatasourcesAction,
+  datasources: DatasourcesState | undefined,
+  action: DatasourcesActionPayload,
 ) {
-  if (action.type === DatasourcesActionType.INIT_DATASOURCES) {
-    return { ...action.datasources };
-  }
-  if (action.type === DatasourcesActionType.SET_DATASOURCES) {
+  if (action.type === DatasourcesAction.SET_DATASOURCES) {
     return {
       ...datasources,
       ...keyBy(action.datasources, 'uid'),
     };
   }
-  if (action.type === DatasourcesActionType.SET_DATASOURCE) {
+  if (action.type === DatasourcesAction.SET_DATASOURCE) {
     return {
       ...datasources,
-      [getDatasourceUid(action.datasource)]: action.datasource,
+      [action.key]: action.datasource,
     };
   }
   return datasources || {};
diff --git a/superset-frontend/src/dashboard/types.ts 
b/superset-frontend/src/dashboard/types.ts
index 3d60b15995..160d62564d 100644
--- a/superset-frontend/src/dashboard/types.ts
+++ b/superset-frontend/src/dashboard/types.ts
@@ -20,6 +20,7 @@ import {
   ChartProps,
   DataMaskStateWithId,
   ExtraFormData,
+  GenericDataType,
   JsonObject,
   NativeFiltersState,
 } from '@superset-ui/core';
@@ -83,8 +84,13 @@ export type DashboardInfo = {
 
 export type ChartsState = { [key: string]: Chart };
 
+export type Datasource = Dataset & {
+  uid: string;
+  column_types: GenericDataType[];
+  table_name: string;
+};
 export type DatasourcesState = {
-  [key: string]: Dataset;
+  [key: string]: Datasource;
 };
 
 /** Root state of redux */
diff --git a/superset-frontend/src/explore/actions/datasourcesActions.test.ts 
b/superset-frontend/src/explore/actions/datasourcesActions.test.ts
new file mode 100644
index 0000000000..a51d8576f8
--- /dev/null
+++ b/superset-frontend/src/explore/actions/datasourcesActions.test.ts
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { DatasourceType } from '@superset-ui/core';
+import {
+  setDatasource,
+  changeDatasource,
+} from 'src/explore/actions/datasourcesActions';
+import datasourcesReducer from '../reducers/datasourcesReducer';
+import { updateFormDataByDatasource } from './exploreActions';
+
+const CURRENT_DATASOURCE = {
+  id: 1,
+  uid: '1__table',
+  type: DatasourceType.Table,
+  columns: [],
+  metrics: [],
+  column_format: {},
+  verbose_map: {},
+  main_dttm_col: '__timestamp',
+  // eg. ['["ds", true]', 'ds [asc]']
+  datasource_name: 'test datasource',
+  description: null,
+};
+
+const NEW_DATASOURCE = {
+  id: 2,
+  type: DatasourceType.Table,
+  columns: [],
+  metrics: [],
+  column_format: {},
+  verbose_map: {},
+  main_dttm_col: '__timestamp',
+  // eg. ['["ds", true]', 'ds [asc]']
+  datasource_name: 'test datasource',
+  description: null,
+};
+
+const defaultDatasourcesReducerState = {
+  [CURRENT_DATASOURCE.uid]: CURRENT_DATASOURCE,
+};
+
+test('sets new datasource', () => {
+  const newState = datasourcesReducer(
+    defaultDatasourcesReducerState,
+    setDatasource(NEW_DATASOURCE),
+  );
+  expect(newState).toEqual({
+    ...defaultDatasourcesReducerState,
+    '2__table': NEW_DATASOURCE,
+  });
+});
+
+test('change datasource action', () => {
+  const dispatch = jest.fn();
+  const getState = jest.fn(() => ({
+    explore: {
+      datasource: CURRENT_DATASOURCE,
+    },
+  }));
+  // ignore getState type check - we dont need explore.datasource field for 
this test
+  // @ts-ignore
+  changeDatasource(NEW_DATASOURCE)(dispatch, getState);
+  expect(dispatch).toHaveBeenCalledTimes(2);
+  expect(dispatch).toHaveBeenNthCalledWith(1, setDatasource(NEW_DATASOURCE));
+  expect(dispatch).toHaveBeenNthCalledWith(
+    2,
+    updateFormDataByDatasource(CURRENT_DATASOURCE, NEW_DATASOURCE),
+  );
+});
diff --git a/superset-frontend/src/datasource/actions.ts 
b/superset-frontend/src/explore/actions/datasourcesActions.ts
similarity index 52%
rename from superset-frontend/src/datasource/actions.ts
rename to superset-frontend/src/explore/actions/datasourcesActions.ts
index 2a5a2ce48d..4fc3bce96a 100644
--- a/superset-frontend/src/datasource/actions.ts
+++ b/superset-frontend/src/explore/actions/datasourcesActions.ts
@@ -16,39 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Dataset } from '@superset-ui/chart-controls';
-
-export enum DatasourcesActionType {
-  INIT_DATASOURCES = 'INIT_DATASOURCES',
-  SET_DATASOURCE = 'SET_DATASOURCE',
-  SET_DATASOURCES = 'SET_DATASOURCES',
-}
 
-export type DatasourcesAction =
-  | {
-      type: DatasourcesActionType.INIT_DATASOURCES;
-      datasources: { [key: string]: Dataset };
-    }
-  | {
-      type: DatasourcesActionType.SET_DATASOURCES;
-      datasources: Dataset[] | null;
-    }
-  | {
-      type: DatasourcesActionType.SET_DATASOURCE;
-      datasource: Dataset;
-    };
+import { Dispatch } from 'redux';
+import { Dataset } from '@superset-ui/chart-controls';
+import { updateFormDataByDatasource } from './exploreActions';
+import { ExplorePageState } from '../types';
 
-export function initDatasources(datasources: { [key: string]: Dataset }) {
-  return { type: DatasourcesActionType.INIT_DATASOURCES, datasources };
+export const SET_DATASOURCE = 'SET_DATASOURCE';
+export interface SetDatasource {
+  type: string;
+  datasource: Dataset;
 }
-
 export function setDatasource(datasource: Dataset) {
-  return { type: DatasourcesActionType.SET_DATASOURCE, datasource };
+  return { type: SET_DATASOURCE, datasource };
 }
 
-export function setDatasources(datasources: Dataset[] | null) {
-  return {
-    type: DatasourcesActionType.SET_DATASOURCES,
-    datasources,
+export function changeDatasource(newDatasource: Dataset) {
+  return function (dispatch: Dispatch, getState: () => ExplorePageState) {
+    const {
+      explore: { datasource: prevDatasource },
+    } = getState();
+    dispatch(setDatasource(newDatasource));
+    dispatch(updateFormDataByDatasource(prevDatasource, newDatasource));
   };
 }
+
+export const datasourcesActions = {
+  setDatasource,
+  changeDatasource,
+};
+
+export type AnyDatasourcesAction = SetDatasource;
diff --git a/superset-frontend/src/explore/actions/exploreActions.ts 
b/superset-frontend/src/explore/actions/exploreActions.ts
index f393c74850..2ec0d086cd 100644
--- a/superset-frontend/src/explore/actions/exploreActions.ts
+++ b/superset-frontend/src/explore/actions/exploreActions.ts
@@ -25,8 +25,6 @@ import {
   toastActions,
 } from 'src/components/MessageToasts/actions';
 import { Slice } from 'src/types/Chart';
-import { setDatasource } from 'src/datasource/actions';
-import { ExplorePageState } from 'src/explore/types';
 
 const FAVESTAR_BASE_URL = '/superset/favstar/slice';
 
@@ -142,24 +140,6 @@ export function setForceQuery(force: boolean) {
   };
 }
 
-export const SAVE_DATASOURCE = 'SAVE_DATASOURCE';
-export function saveDatasource(datasource: Dataset) {
-  return function (dispatch: Dispatch) {
-    dispatch(setDatasource(datasource));
-    dispatch({ type: SAVE_DATASOURCE, datasource });
-  };
-}
-
-export function changeDatasource(newDatasource: Dataset) {
-  return function (dispatch: Dispatch, getState: () => ExplorePageState) {
-    const {
-      explore: { datasource: prevDatasource },
-    } = getState();
-    dispatch(setDatasource(newDatasource));
-    dispatch(updateFormDataByDatasource(prevDatasource, newDatasource));
-  };
-}
-
 export const exploreActions = {
   ...toastActions,
   fetchDatasourcesStarted,
@@ -173,7 +153,6 @@ export const exploreActions = {
   createNewSlice,
   sliceUpdated,
   setForceQuery,
-  changeDatasource,
 };
 
 export type ExploreActions = typeof exploreActions;
diff --git a/superset-frontend/src/explore/actions/hydrateExplore.test.ts 
b/superset-frontend/src/explore/actions/hydrateExplore.test.ts
index 3b3963f9f5..9cc7b883e9 100644
--- a/superset-frontend/src/explore/actions/hydrateExplore.test.ts
+++ b/superset-frontend/src/explore/actions/hydrateExplore.test.ts
@@ -64,6 +64,9 @@ test('creates hydrate action from initial data', () => {
             lastRendered: 0,
           },
         },
+        datasources: {
+          '8__table': exploreInitialData.dataset,
+        },
         saveModal: {
           dashboards: [],
           saveModalAlert: null,
diff --git a/superset-frontend/src/explore/actions/hydrateExplore.ts 
b/superset-frontend/src/explore/actions/hydrateExplore.ts
index b16ac30a7b..2479a8c978 100644
--- a/superset-frontend/src/explore/actions/hydrateExplore.ts
+++ b/superset-frontend/src/explore/actions/hydrateExplore.ts
@@ -35,7 +35,6 @@ import { getDatasourceUid } from 'src/utils/getDatasourceUid';
 import { getUrlParam } from 'src/utils/urlUtils';
 import { URL_PARAMS } from 'src/constants';
 import { findPermission } from 'src/utils/findPermission';
-import { initDatasources } from 'src/datasource/actions';
 
 export const HYDRATE_EXPLORE = 'HYDRATE_EXPLORE';
 export const hydrateExplore =
@@ -121,13 +120,6 @@ export const hydrateExplore =
       lastRendered: 0,
     };
 
-    dispatch(
-      initDatasources({
-        ...datasources,
-        [getDatasourceUid(initialDatasource)]: initialDatasource,
-      }),
-    );
-
     return dispatch({
       type: HYDRATE_EXPLORE,
       data: {
@@ -135,6 +127,10 @@ export const hydrateExplore =
           ...charts,
           [chartKey]: chart,
         },
+        datasources: {
+          ...datasources,
+          [getDatasourceUid(initialDatasource)]: initialDatasource,
+        },
         saveModal: {
           dashboards: [],
           saveModalAlert: null,
diff --git 
a/superset-frontend/src/explore/components/ExploreViewContainer/index.jsx 
b/superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
index ab4e0c91aa..82443fc3ab 100644
--- a/superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
+++ b/superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
@@ -46,10 +46,11 @@ import {
 import { getUrlParam } from 'src/utils/urlUtils';
 import cx from 'classnames';
 import * as chartActions from 'src/components/Chart/chartAction';
-import { fetchDatasourceMetadata } from 
'src/dashboard/util/fetchDatasourceMetadata';
+import { fetchDatasourceMetadata } from 'src/dashboard/actions/datasources';
 import { chartPropShape } from 'src/dashboard/util/propShapes';
 import { mergeExtraFormData } from 
'src/dashboard/components/nativeFilters/utils';
 import { postFormData, putFormData } from 'src/explore/exploreUtils/formData';
+import { datasourcesActions } from 'src/explore/actions/datasourcesActions';
 import { mountExploreUrl } from 'src/explore/exploreUtils';
 import { getFormDataFromControls } from 'src/explore/controlUtils';
 import * as exploreActions from 'src/explore/actions/exploreActions';
@@ -753,6 +754,7 @@ function mapStateToProps(state) {
 function mapDispatchToProps(dispatch) {
   const actions = {
     ...exploreActions,
+    ...datasourcesActions,
     ...saveModalActions,
     ...chartActions,
     ...logActions,
diff --git a/superset-frontend/src/datasource/reducer.ts 
b/superset-frontend/src/explore/reducers/datasourcesReducer.ts
similarity index 68%
rename from superset-frontend/src/datasource/reducer.ts
rename to superset-frontend/src/explore/reducers/datasourcesReducer.ts
index 476ed750be..50393dbd24 100644
--- a/superset-frontend/src/datasource/reducer.ts
+++ b/superset-frontend/src/explore/reducers/datasourcesReducer.ts
@@ -16,32 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { keyBy } from 'lodash';
+import { Dataset } from '@superset-ui/chart-controls';
 import { getDatasourceUid } from 'src/utils/getDatasourceUid';
 import {
-  DatasourcesAction,
-  DatasourcesActionType,
-} from 'src/datasource/actions';
-import { Dataset } from '@superset-ui/chart-controls';
+  AnyDatasourcesAction,
+  SET_DATASOURCE,
+} from '../actions/datasourcesActions';
+import { HYDRATE_EXPLORE, HydrateExplore } from '../actions/hydrateExplore';
 
 export default function datasourcesReducer(
-  datasources: { [key: string]: Dataset } | undefined,
-  action: DatasourcesAction,
+  // TODO: change type to include other datasource types
+  datasources: { [key: string]: Dataset },
+  action: AnyDatasourcesAction | HydrateExplore,
 ) {
-  if (action.type === DatasourcesActionType.INIT_DATASOURCES) {
-    return { ...action.datasources };
-  }
-  if (action.type === DatasourcesActionType.SET_DATASOURCES) {
-    return {
-      ...datasources,
-      ...keyBy(action.datasources, 'uid'),
-    };
-  }
-  if (action.type === DatasourcesActionType.SET_DATASOURCE) {
+  if (action.type === SET_DATASOURCE) {
     return {
       ...datasources,
       [getDatasourceUid(action.datasource)]: action.datasource,
     };
   }
+  if (action.type === HYDRATE_EXPLORE) {
+    return { ...(action as HydrateExplore).data.datasources };
+  }
   return datasources || {};
 }
diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js 
b/superset-frontend/src/explore/reducers/exploreReducer.js
index 93743285c6..f99ab9437c 100644
--- a/superset-frontend/src/explore/reducers/exploreReducer.js
+++ b/superset-frontend/src/explore/reducers/exploreReducer.js
@@ -50,19 +50,6 @@ export default function exploreReducer(state = {}, action) {
         isDatasourceMetaLoading: true,
       };
     },
-    [actions.SAVE_DATASOURCE]() {
-      return {
-        ...state,
-        datasource: action.datasource,
-        controls: {
-          ...state.controls,
-          datasource: {
-            ...state.controls.datasource,
-            datasource: action.datasource,
-          },
-        },
-      };
-    },
     [actions.UPDATE_FORM_DATA_BY_DATASOURCE]() {
       const newFormData = { ...state.form_data };
       const { prevDatasource, newDatasource } = action;
diff --git a/superset-frontend/src/hooks/apiResources/dashboards.ts 
b/superset-frontend/src/hooks/apiResources/dashboards.ts
index 7292194c7c..b21cc668c0 100644
--- a/superset-frontend/src/hooks/apiResources/dashboards.ts
+++ b/superset-frontend/src/hooks/apiResources/dashboards.ts
@@ -17,8 +17,7 @@
  * under the License.
  */
 
-import { Dashboard, EmbeddedDashboard } from 'src/dashboard/types';
-import { Dataset } from '@superset-ui/chart-controls';
+import { Dashboard, Datasource, EmbeddedDashboard } from 'src/dashboard/types';
 import { Chart } from 'src/types/Chart';
 import { useApiV1Resource, useTransformedResource } from './apiResources';
 
@@ -43,7 +42,7 @@ export const useDashboardCharts = (idOrSlug: string | number) 
=>
 // important: this endpoint only returns the fields in the dataset
 // that are necessary for rendering the given dashboard
 export const useDashboardDatasets = (idOrSlug: string | number) =>
-  useApiV1Resource<Dataset[]>(`/api/v1/dashboard/${idOrSlug}/datasets`);
+  useApiV1Resource<Datasource[]>(`/api/v1/dashboard/${idOrSlug}/datasets`);
 
 export const useEmbeddedDashboard = (idOrSlug: string | number) =>
   
useApiV1Resource<EmbeddedDashboard>(`/api/v1/dashboard/${idOrSlug}/embedded`);
diff --git a/superset-frontend/src/views/store.ts 
b/superset-frontend/src/views/store.ts
index 284a8d966b..251feeec51 100644
--- a/superset-frontend/src/views/store.ts
+++ b/superset-frontend/src/views/store.ts
@@ -33,17 +33,26 @@ import dashboardInfo from 
'src/dashboard/reducers/dashboardInfo';
 import dashboardState from 'src/dashboard/reducers/dashboardState';
 import dashboardFilters from 'src/dashboard/reducers/dashboardFilters';
 import nativeFilters from 'src/dashboard/reducers/nativeFilters';
-import datasources from 'src/datasource/reducer';
+import dashboardDatasources from 'src/dashboard/reducers/datasources';
 import sliceEntities from 'src/dashboard/reducers/sliceEntities';
 import dashboardLayout from 'src/dashboard/reducers/undoableDashboardLayout';
 import logger from 'src/middleware/loggerMiddleware';
 import saveModal from 'src/explore/reducers/saveModalReducer';
 import explore from 'src/explore/reducers/exploreReducer';
+import exploreDatasources from 'src/explore/reducers/datasourcesReducer';
+import { DatasourcesState } from 'src/dashboard/types';
+import {
+  DatasourcesActionPayload,
+  DatasourcesAction,
+} from 'src/dashboard/actions/datasources';
 import shortid from 'shortid';
 import {
   BootstrapUser,
   UserWithPermissionsAndRoles,
 } from 'src/types/bootstrapTypes';
+import { AnyDatasourcesAction } from 'src/explore/actions/datasourcesActions';
+import { HydrateExplore } from 'src/explore/actions/hydrateExplore';
+import { Dataset } from '@superset-ui/chart-controls';
 
 // Some reducers don't do anything, and redux is just used to reference the 
initial "state".
 // This may change later, as the client application takes on more 
responsibilities.
@@ -72,6 +81,26 @@ const userReducer = (
   return user;
 };
 
+// TODO: This reducer is a combination of the Dashboard and Explore reducers.
+// The correct way of handling this is to unify the actions and reducers from 
both
+// modules in shared files. This involves a big refactor to unify the 
parameter types
+// and move files around. We should tackle this in a specific PR.
+const CombinedDatasourceReducers = (
+  datasources: DatasourcesState | undefined | { [key: string]: Dataset },
+  action: DatasourcesActionPayload | AnyDatasourcesAction | HydrateExplore,
+) => {
+  if (action.type === DatasourcesAction.SET_DATASOURCES) {
+    return dashboardDatasources(
+      datasources as DatasourcesState | undefined,
+      action as DatasourcesActionPayload,
+    );
+  }
+  return exploreDatasources(
+    datasources as { [key: string]: Dataset },
+    action as AnyDatasourcesAction | HydrateExplore,
+  );
+};
+
 // exported for tests
 export const rootReducer = combineReducers({
   messageToasts: messageToastReducer,
@@ -79,7 +108,7 @@ export const rootReducer = combineReducers({
   user: userReducer,
   impressionId: noopReducer(shortid.generate()),
   charts,
-  datasources,
+  datasources: CombinedDatasourceReducers,
   dashboardInfo,
   dashboardFilters,
   dataMask,

Reply via email to