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 ec2eb3ddf8 refactor: Renders addSlice in SPA (#20675)
ec2eb3ddf8 is described below
commit ec2eb3ddf883505fb9681a5783602181a1aea747
Author: Michael S. Molina <[email protected]>
AuthorDate: Wed Jul 13 08:50:58 2022 -0300
refactor: Renders addSlice in SPA (#20675)
* refactor: Renders addSlice in SPA
* Removes unused imports
* Fixes test imports
* Removes unnecessary imports
---
.../src/addSlice/AddSliceContainer.test.tsx | 22 +++++---
.../src/addSlice/AddSliceContainer.tsx | 9 +--
superset-frontend/src/addSlice/App.tsx | 66 ----------------------
superset-frontend/src/addSlice/index.tsx | 23 --------
.../src/views/CRUD/chart/ChartList.tsx | 6 +-
.../src/views/components/RightMenu.tsx | 24 +++++---
superset-frontend/src/views/routes.tsx | 10 ++++
superset-frontend/webpack.config.js | 1 -
superset/templates/superset/add_slice.html | 35 ------------
superset/views/chart/views.py | 14 +----
10 files changed, 52 insertions(+), 158 deletions(-)
diff --git a/superset-frontend/src/addSlice/AddSliceContainer.test.tsx
b/superset-frontend/src/addSlice/AddSliceContainer.test.tsx
index b26ac9a4a7..e5f62fd258 100644
--- a/superset-frontend/src/addSlice/AddSliceContainer.test.tsx
+++ b/superset-frontend/src/addSlice/AddSliceContainer.test.tsx
@@ -17,7 +17,8 @@
* under the License.
*/
import React from 'react';
-import { ReactWrapper, mount } from 'enzyme';
+import { ReactWrapper } from 'enzyme';
+import { styledMount as mount } from 'spec/helpers/theming';
import Button from 'src/components/Button';
import { AsyncSelect } from 'src/components';
import {
@@ -28,8 +29,6 @@ import {
import VizTypeGallery from
'src/explore/components/controls/VizTypeControl/VizTypeGallery';
import { act } from 'spec/helpers/testing-library';
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
-import { ThemeProvider } from '@emotion/react';
-import { supersetTheme } from '@superset-ui/core';
const datasource = {
value: '1',
@@ -62,13 +61,20 @@ const mockUserWithDatasetWrite: UserWithPermissionsAndRoles
= {
isAnonymous: false,
};
+// We don't need the actual implementation for the tests
+const routeProps = {
+ history: {} as any,
+ location: {} as any,
+ match: {} as any,
+};
+
async function getWrapper(user = mockUser) {
const wrapper = mount(
- <AddSliceContainer user={user} addSuccessToast={() => null} />,
- {
- wrappingComponent: ThemeProvider,
- wrappingComponentProps: { theme: supersetTheme },
- },
+ <AddSliceContainer
+ user={user}
+ addSuccessToast={() => null}
+ {...routeProps}
+ />,
) as unknown as ReactWrapper<
AddSliceContainerProps,
AddSliceContainerState,
diff --git a/superset-frontend/src/addSlice/AddSliceContainer.tsx
b/superset-frontend/src/addSlice/AddSliceContainer.tsx
index 98821c71a1..9507327776 100644
--- a/superset-frontend/src/addSlice/AddSliceContainer.tsx
+++ b/superset-frontend/src/addSlice/AddSliceContainer.tsx
@@ -23,6 +23,7 @@ import { styled, t, SupersetClient, JsonResponse } from
'@superset-ui/core';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
import { isNullish } from 'src/utils/common';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
import Button from 'src/components/Button';
import { AsyncSelect, Steps } from 'src/components';
import { Tooltip } from 'src/components/Tooltip';
@@ -42,10 +43,10 @@ type Dataset = {
datasource_type: string;
};
-export type AddSliceContainerProps = {
+export interface AddSliceContainerProps extends RouteComponentProps {
user: UserWithPermissionsAndRoles;
addSuccessToast: (arg: string) => void;
-};
+}
export type AddSliceContainerState = {
datasource?: { label: string; value: string };
@@ -254,7 +255,7 @@ export class AddSliceContainer extends React.PureComponent<
}
gotoSlice() {
- window.location.href = this.exploreUrl();
+ this.props.history.push(this.exploreUrl());
}
changeDatasource(datasource: { label: string; value: string }) {
@@ -418,4 +419,4 @@ export class AddSliceContainer extends React.PureComponent<
}
}
-export default withToasts(AddSliceContainer);
+export default withRouter(withToasts(AddSliceContainer));
diff --git a/superset-frontend/src/addSlice/App.tsx
b/superset-frontend/src/addSlice/App.tsx
deleted file mode 100644
index 11adbb30a2..0000000000
--- a/superset-frontend/src/addSlice/App.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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 React from 'react';
-import { hot } from 'react-hot-loader/root';
-import thunk from 'redux-thunk';
-import { createStore, compose, applyMiddleware, combineReducers } from 'redux';
-import { Provider } from 'react-redux';
-import { ThemeProvider } from '@superset-ui/core';
-import { GlobalStyles } from 'src/GlobalStyles';
-import messageToastReducer from 'src/components/MessageToasts/reducers';
-import { initEnhancer } from 'src/reduxUtils';
-import ToastContainer from 'src/components/MessageToasts/ToastContainer';
-import setupApp from '../setup/setupApp';
-import setupPlugins from '../setup/setupPlugins';
-import { DynamicPluginProvider } from '../components/DynamicPlugins';
-import AddSliceContainer from './AddSliceContainer';
-import { initFeatureFlags } from '../featureFlags';
-import { theme } from '../preamble';
-
-setupApp();
-setupPlugins();
-
-const addSliceContainer = document.getElementById('app');
-const bootstrapData = JSON.parse(
- addSliceContainer?.getAttribute('data-bootstrap') || '{}',
-);
-
-const store = createStore(
- combineReducers({
- messageToasts: messageToastReducer,
- }),
- {},
- compose(applyMiddleware(thunk), initEnhancer(false)),
-);
-
-initFeatureFlags(bootstrapData.common.feature_flags);
-
-const App = () => (
- <Provider store={store}>
- <ThemeProvider theme={theme}>
- <GlobalStyles />
- <DynamicPluginProvider>
- <AddSliceContainer user={bootstrapData.user} />
- <ToastContainer />
- </DynamicPluginProvider>
- </ThemeProvider>
- </Provider>
-);
-
-export default hot(App);
diff --git a/superset-frontend/src/addSlice/index.tsx
b/superset-frontend/src/addSlice/index.tsx
deleted file mode 100644
index c257009e64..0000000000
--- a/superset-frontend/src/addSlice/index.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * 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 React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
-
-ReactDOM.render(<App />, document.getElementById('app'));
diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx
b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
index c2ffcf0284..8173b73c06 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
@@ -41,7 +41,7 @@ import handleResourceExport from 'src/utils/export';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
import SubMenu, { SubMenuProps } from 'src/views/components/SubMenu';
import FaveStar from 'src/components/FaveStar';
-import { Link } from 'react-router-dom';
+import { Link, useHistory } from 'react-router-dom';
import ListView, {
Filter,
FilterOperator,
@@ -153,6 +153,8 @@ function ChartList(props: ChartListProps) {
user: { userId },
} = props;
+ const history = useHistory();
+
const {
state: {
loading,
@@ -653,7 +655,7 @@ function ChartList(props: ChartListProps) {
),
buttonStyle: 'primary',
onClick: () => {
- window.location.assign('/chart/add');
+ history.push('/chart/add');
},
});
diff --git a/superset-frontend/src/views/components/RightMenu.tsx
b/superset-frontend/src/views/components/RightMenu.tsx
index e1e2dd1ae7..5473fa069c 100644
--- a/superset-frontend/src/views/components/RightMenu.tsx
+++ b/superset-frontend/src/views/components/RightMenu.tsx
@@ -321,13 +321,23 @@ const RightMenu = ({
roles,
) && (
<Menu.Item key={menu.label}>
- <a href={menu.url}>
- <i
- data-test={`menu-item-${menu.label}`}
- className={`fa ${menu.icon}`}
- />{' '}
- {menu.label}
- </a>
+ {isFrontendRoute(menu.url) ? (
+ <Link to={menu.url || ''}>
+ <i
+ data-test={`menu-item-${menu.label}`}
+ className={`fa ${menu.icon}`}
+ />{' '}
+ {menu.label}
+ </Link>
+ ) : (
+ <a href={menu.url}>
+ <i
+ data-test={`menu-item-${menu.label}`}
+ className={`fa ${menu.icon}`}
+ />{' '}
+ {menu.label}
+ </a>
+ )}
</Menu.Item>
)
);
diff --git a/superset-frontend/src/views/routes.tsx
b/superset-frontend/src/views/routes.tsx
index e0d9d144bf..dbb9ca2fab 100644
--- a/superset-frontend/src/views/routes.tsx
+++ b/superset-frontend/src/views/routes.tsx
@@ -21,6 +21,12 @@ import React, { lazy } from 'react';
// not lazy loaded since this is the home page.
import Welcome from 'src/views/CRUD/welcome/Welcome';
+const AddSliceContainer = lazy(
+ () =>
+ import(
+ /* webpackChunkName: "AddSliceContainer" */
'src/addSlice/AddSliceContainer'
+ ),
+);
const AnnotationLayersList = lazy(
() =>
import(
@@ -117,6 +123,10 @@ export const routes: Routes = [
path: '/superset/dashboard/:idOrSlug/',
Component: DashboardRoute,
},
+ {
+ path: '/chart/add',
+ Component: AddSliceContainer,
+ },
{
path: '/chart/list/',
Component: ChartList,
diff --git a/superset-frontend/webpack.config.js
b/superset-frontend/webpack.config.js
index 450453a946..99d51a7d01 100644
--- a/superset-frontend/webpack.config.js
+++ b/superset-frontend/webpack.config.js
@@ -209,7 +209,6 @@ const config = {
menu: addPreamble('src/views/menu.tsx'),
spa: addPreamble('/src/views/index.tsx'),
embedded: addPreamble('/src/embedded/index.tsx'),
- addSlice: addPreamble('/src/addSlice/index.tsx'),
sqllab: addPreamble('/src/SqlLab/index.tsx'),
profile: addPreamble('/src/profile/index.tsx'),
showSavedQuery: [path.join(APP_DIR, '/src/showSavedQuery/index.jsx')],
diff --git a/superset/templates/superset/add_slice.html
b/superset/templates/superset/add_slice.html
deleted file mode 100644
index b287de64e8..0000000000
--- a/superset/templates/superset/add_slice.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{#
- 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.
-#}
-{% extends "superset/basic.html" %}
-
-{% block title %}
- Add new chart
-{% endblock %}
-
-{% block body %}
- <div
- id="app"
- data-bootstrap="{{ bootstrap_data }}"
- ></div>
-{% endblock %}
-
-{% block tail_js %}
- {{ super() }}
- {{ js_bundle("addSlice") }}
-{% endblock %}
diff --git a/superset/views/chart/views.py b/superset/views/chart/views.py
index 4d43e797d0..250fa901e9 100644
--- a/superset/views/chart/views.py
+++ b/superset/views/chart/views.py
@@ -14,9 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import json
-
-from flask import g
from flask_appbuilder import expose, has_access
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_babel import lazy_gettext as _
@@ -26,9 +23,8 @@ from superset.constants import
MODEL_VIEW_RW_METHOD_PERMISSION_MAP, RouteMethod
from superset.models.slice import Slice
from superset.superset_typing import FlaskResponse
from superset.utils import core as utils
-from superset.views.base import common_bootstrap_payload, DeleteMixin,
SupersetModelView
+from superset.views.base import DeleteMixin, SupersetModelView
from superset.views.chart.mixin import SliceMixin
-from superset.views.utils import bootstrap_user_data
class SliceModelView(
@@ -57,13 +53,7 @@ class SliceModelView(
@expose("/add", methods=["GET", "POST"])
@has_access
def add(self) -> FlaskResponse:
- payload = {
- "common": common_bootstrap_payload(),
- "user": bootstrap_user_data(g.user, include_perms=True),
- }
- return self.render_template(
- "superset/add_slice.html", bootstrap_data=json.dumps(payload)
- )
+ return super().render_app_template()
@expose("/list/")
@has_access