This is an automated email from the ASF dual-hosted git repository.
tai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 7301a36 feat: setup react page with submenu for datasources listview
(#10642)
7301a36 is described below
commit 7301a363c1de9f865945f53cc9c11df3f2c1253c
Author: ʈᵃᵢ <[email protected]>
AuthorDate: Thu Aug 20 11:42:17 2020 -0700
feat: setup react page with submenu for datasources listview (#10642)
---
.../CRUD/data/database/DatabaseList_spec.jsx} | 24 +++++++++++++++---
.../CRUD/{ => data}/dataset/DatasetList_spec.jsx | 9 +++----
.../CRUD}/welcome/DashboardTable_spec.tsx | 2 +-
.../{ => views/CRUD}/welcome/Welcome_spec.tsx | 2 +-
.../src/components/ErrorMessage/ErrorAlert.tsx | 2 +-
superset-frontend/src/components/Modal.tsx | 2 +-
superset-frontend/src/{welcome => views}/App.tsx | 20 +++++++++------
.../index.tsx => views/CRUD/data/common.ts} | 25 ++++++++++++++++---
.../CRUD/data/database/DatabaseList.tsx} | 29 +++++++++++++++++++---
.../CRUD/{ => data}/dataset/AddDatasetModal.tsx | 0
.../src/views/CRUD/{ => data}/dataset/Button.tsx | 0
.../views/CRUD/{ => data}/dataset/DatasetList.tsx | 16 ++----------
.../{ => views/CRUD}/welcome/DashboardTable.tsx | 0
.../src/{ => views/CRUD}/welcome/Welcome.tsx | 4 +--
superset-frontend/src/{welcome => views}/index.tsx | 0
superset-frontend/webpack.config.js | 2 +-
superset/config.py | 1 +
.../superset/{welcome.html => crud_views.html} | 2 +-
superset/views/base.py | 4 +--
superset/views/core.py | 4 +--
superset/views/database/views.py | 16 +++++++++++-
21 files changed, 114 insertions(+), 50 deletions(-)
diff --git a/superset-frontend/src/welcome/index.tsx
b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx
similarity index 56%
copy from superset-frontend/src/welcome/index.tsx
copy to
superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx
index c257009..c85ab82 100644
--- a/superset-frontend/src/welcome/index.tsx
+++
b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx
@@ -17,7 +17,25 @@
* under the License.
*/
import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
+import thunk from 'redux-thunk';
+import configureStore from 'redux-mock-store';
+import { styledMount as mount } from 'spec/helpers/theming';
-ReactDOM.render(<App />, document.getElementById('app'));
+import DatabaseList from 'src/views/CRUD/data/database/DatabaseList';
+import SubMenu from 'src/components/Menu/SubMenu';
+
+// store needed for withToasts(DatabaseList)
+const mockStore = configureStore([thunk]);
+const store = mockStore({});
+
+describe('DatabaseList', () => {
+ const wrapper = mount(<DatabaseList />, { context: { store } });
+
+ it('renders', () => {
+ expect(wrapper.find(DatabaseList)).toExist();
+ });
+
+ it('renders a SubMenu', () => {
+ expect(wrapper.find(SubMenu)).toExist();
+ });
+});
diff --git
a/superset-frontend/spec/javascripts/views/CRUD/dataset/DatasetList_spec.jsx
b/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx
similarity index 94%
rename from
superset-frontend/spec/javascripts/views/CRUD/dataset/DatasetList_spec.jsx
rename to
superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx
index 53de35d..db49a0f 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/dataset/DatasetList_spec.jsx
+++
b/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx
@@ -17,20 +17,19 @@
* under the License.
*/
import React from 'react';
-import { mount } from 'enzyme';
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';
import fetchMock from 'fetch-mock';
-import { supersetTheme, ThemeProvider } from '@superset-ui/style';
+import { styledMount as mount } from 'spec/helpers/theming';
-import DatasetList from 'src/views/CRUD/dataset/DatasetList';
+import DatasetList from 'src/views/CRUD/data/dataset/DatasetList';
import ListView from 'src/components/ListView';
import Button from 'src/components/Button';
import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import { act } from 'react-dom/test-utils';
-// store needed for withToasts(datasetTable)
+// store needed for withToasts(DatasetList)
const mockStore = configureStore([thunk]);
const store = mockStore({});
@@ -69,8 +68,6 @@ fetchMock.get(databaseEndpoint, {
async function mountAndWait(props) {
const mounted = mount(<DatasetList {...props} />, {
context: { store },
- wrappingComponent: ThemeProvider,
- wrappingComponentProps: { theme: supersetTheme },
});
await waitForComponentToPaint(mounted);
diff --git a/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
b/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
similarity index 97%
rename from superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
rename to
superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
index b612fbb..135613a 100644
--- a/superset-frontend/spec/javascripts/welcome/DashboardTable_spec.tsx
+++
b/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
@@ -24,7 +24,7 @@ import fetchMock from 'fetch-mock';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';
import ListView from 'src/components/ListView';
-import DashboardTable from 'src/welcome/DashboardTable';
+import DashboardTable from 'src/views/CRUD/welcome/DashboardTable';
// store needed for withToasts(DashboardTable)
const mockStore = configureStore([thunk]);
diff --git a/superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
b/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
similarity index 96%
rename from superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
rename to superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
index 0e7e5e1..bf23ef1 100644
--- a/superset-frontend/spec/javascripts/welcome/Welcome_spec.tsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
@@ -20,7 +20,7 @@ import React from 'react';
import { Panel, Row, Tab } from 'react-bootstrap';
import { shallow } from 'enzyme';
-import Welcome from 'src/welcome/Welcome';
+import Welcome from 'src/views/CRUD/welcome/Welcome';
describe('Welcome', () => {
const mockedProps = {
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
index e96d08c..b176457 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
@@ -21,7 +21,7 @@ import { Modal } from 'react-bootstrap';
import { styled, supersetTheme } from '@superset-ui/style';
import { t } from '@superset-ui/translation';
import { noOp } from 'src/utils/common';
-import Button from 'src/views/CRUD/dataset/Button';
+import Button from 'src/views/CRUD/data/dataset/Button';
import Icon from '../Icon';
import { ErrorLevel, ErrorSource } from './types';
diff --git a/superset-frontend/src/components/Modal.tsx
b/superset-frontend/src/components/Modal.tsx
index fb7edb5..eed1215 100644
--- a/superset-frontend/src/components/Modal.tsx
+++ b/superset-frontend/src/components/Modal.tsx
@@ -20,7 +20,7 @@ import React from 'react';
import styled from '@superset-ui/style';
import { Modal as BaseModal } from 'react-bootstrap';
import { t } from '@superset-ui/translation';
-import Button from 'src/views/CRUD/dataset/Button';
+import Button from 'src/views/CRUD/data/dataset/Button';
interface ModalProps {
children: React.ReactNode;
diff --git a/superset-frontend/src/welcome/App.tsx
b/superset-frontend/src/views/App.tsx
similarity index 83%
rename from superset-frontend/src/welcome/App.tsx
rename to superset-frontend/src/views/App.tsx
index 5bc624d..bf642bb 100644
--- a/superset-frontend/src/welcome/App.tsx
+++ b/superset-frontend/src/views/App.tsx
@@ -30,14 +30,15 @@ import Menu from 'src/components/Menu/Menu';
import FlashProvider from 'src/components/FlashProvider';
import DashboardList from 'src/views/CRUD/dashboard/DashboardList';
import ChartList from 'src/views/CRUD/chart/ChartList';
-import DatasetList from 'src/views/CRUD/dataset/DatasetList';
+import DatasetList from 'src/views/CRUD/data/dataset/DatasetList';
+import DatasourceList from 'src/views/CRUD/data/database/DatabaseList';
-import messageToastReducer from '../messageToasts/reducers';
-import { initEnhancer } from '../reduxUtils';
-import setupApp from '../setup/setupApp';
-import setupPlugins from '../setup/setupPlugins';
-import Welcome from './Welcome';
-import ToastPresenter from '../messageToasts/containers/ToastPresenter';
+import messageToastReducer from 'src/messageToasts/reducers';
+import { initEnhancer } from 'src/reduxUtils';
+import setupApp from 'src/setup/setupApp';
+import setupPlugins from 'src/setup/setupPlugins';
+import Welcome from 'src/views/CRUD/welcome/Welcome';
+import ToastPresenter from 'src/messageToasts/containers/ToastPresenter';
setupApp();
setupPlugins();
@@ -85,6 +86,11 @@ const App = () => (
<DatasetList user={user} />
</ErrorBoundary>
</Route>
+ <Route path="/databaseview/list/">
+ <ErrorBoundary>
+ <DatasourceList user={user} />
+ </ErrorBoundary>
+ </Route>
</Switch>
<ToastPresenter />
</QueryParamProvider>
diff --git a/superset-frontend/src/welcome/index.tsx
b/superset-frontend/src/views/CRUD/data/common.ts
similarity index 65%
copy from superset-frontend/src/welcome/index.tsx
copy to superset-frontend/src/views/CRUD/data/common.ts
index c257009..b2c1940 100644
--- a/superset-frontend/src/welcome/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/common.ts
@@ -16,8 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
+import { t } from '@superset-ui/translation';
-ReactDOM.render(<App />, document.getElementById('app'));
+export const commonMenuData = {
+ name: t('Data'),
+ children: [
+ {
+ name: 'Datasets',
+ label: t('Datasets'),
+ url: '/tablemodelview/list/',
+ },
+ {
+ name: 'Databases',
+ label: t('Databases'),
+ url: '/databaseview/list/',
+ },
+ {
+ name: 'Saved Queries',
+ label: t('Saved Queries'),
+ url: '/sqllab/my_queries/',
+ },
+ ],
+};
diff --git a/superset-frontend/src/welcome/index.tsx
b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
similarity index 58%
copy from superset-frontend/src/welcome/index.tsx
copy to superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
index c257009..b13c211 100644
--- a/superset-frontend/src/welcome/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
@@ -17,7 +17,30 @@
* under the License.
*/
import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
-ReactDOM.render(<App />, document.getElementById('app'));
+import withToasts from 'src/messageToasts/enhancers/withToasts';
+import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
+import { commonMenuData } from 'src/views/CRUD/data/common';
+
+interface DatasourceListProps {
+ addDangerToast: (msg: string) => void;
+ addSuccessToast: (msg: string) => void;
+}
+
+function DatasourceList({
+ addDangerToast,
+ addSuccessToast,
+}: DatasourceListProps) {
+ const menuData: SubMenuProps = {
+ activeChild: 'Databases',
+ ...commonMenuData,
+ };
+
+ return (
+ <>
+ <SubMenu {...menuData} />
+ </>
+ );
+}
+
+export default withToasts(DatasourceList);
diff --git a/superset-frontend/src/views/CRUD/dataset/AddDatasetModal.tsx
b/superset-frontend/src/views/CRUD/data/dataset/AddDatasetModal.tsx
similarity index 100%
rename from superset-frontend/src/views/CRUD/dataset/AddDatasetModal.tsx
rename to superset-frontend/src/views/CRUD/data/dataset/AddDatasetModal.tsx
diff --git a/superset-frontend/src/views/CRUD/dataset/Button.tsx
b/superset-frontend/src/views/CRUD/data/dataset/Button.tsx
similarity index 100%
rename from superset-frontend/src/views/CRUD/dataset/Button.tsx
rename to superset-frontend/src/views/CRUD/data/dataset/Button.tsx
diff --git a/superset-frontend/src/views/CRUD/dataset/DatasetList.tsx
b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx
similarity index 98%
rename from superset-frontend/src/views/CRUD/dataset/DatasetList.tsx
rename to superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx
index 8ee1e5f..f7a5ab0 100644
--- a/superset-frontend/src/views/CRUD/dataset/DatasetList.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx
@@ -35,6 +35,7 @@ import ListView, {
Filters,
} from 'src/components/ListView';
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
+import { commonMenuData } from 'src/views/CRUD/data/common';
import AvatarIcon from 'src/components/AvatarIcon';
import Owner from 'src/types/Owner';
import withToasts from 'src/messageToasts/enhancers/withToasts';
@@ -441,20 +442,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
const menuData: SubMenuProps = {
activeChild: 'Datasets',
- name: t('Data'),
- children: [
- {
- name: 'Datasets',
- label: t('Datasets'),
- url: '/tablemodelview/list/',
- },
- { name: 'Databases', label: t('Databases'), url: '/databaseview/list/' },
- {
- name: 'Saved Queries',
- label: t('Saved Queries'),
- url: '/sqllab/my_queries/',
- },
- ],
+ ...commonMenuData,
};
if (canCreate) {
diff --git a/superset-frontend/src/welcome/DashboardTable.tsx
b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx
similarity index 100%
rename from superset-frontend/src/welcome/DashboardTable.tsx
rename to superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx
diff --git a/superset-frontend/src/welcome/Welcome.tsx
b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx
similarity index 96%
rename from superset-frontend/src/welcome/Welcome.tsx
rename to superset-frontend/src/views/CRUD/welcome/Welcome.tsx
index 3ec66e1..0b53ae6 100644
--- a/superset-frontend/src/welcome/Welcome.tsx
+++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx
@@ -21,8 +21,8 @@ import { Panel, Row, Col, Tabs, Tab, FormControl } from
'react-bootstrap';
import { t } from '@superset-ui/translation';
import { useQueryParam, StringParam, QueryParamConfig } from
'use-query-params';
import { User } from 'src/types/bootstrapTypes';
-import RecentActivity from '../profile/components/RecentActivity';
-import Favorites from '../profile/components/Favorites';
+import RecentActivity from 'src/profile/components/RecentActivity';
+import Favorites from 'src/profile/components/Favorites';
import DashboardTable from './DashboardTable';
interface WelcomeProps {
diff --git a/superset-frontend/src/welcome/index.tsx
b/superset-frontend/src/views/index.tsx
similarity index 100%
rename from superset-frontend/src/welcome/index.tsx
rename to superset-frontend/src/views/index.tsx
diff --git a/superset-frontend/webpack.config.js
b/superset-frontend/webpack.config.js
index 66b04d0..84d0479 100644
--- a/superset-frontend/webpack.config.js
+++ b/superset-frontend/webpack.config.js
@@ -180,7 +180,7 @@ const config = {
explore: addPreamble('/src/explore/index.jsx'),
dashboard: addPreamble('/src/dashboard/index.jsx'),
sqllab: addPreamble('/src/SqlLab/index.tsx'),
- welcome: addPreamble('/src/welcome/index.tsx'),
+ crudViews: addPreamble('/src/views/index.tsx'),
profile: addPreamble('/src/profile/index.tsx'),
showSavedQuery: [path.join(APP_DIR, '/src/showSavedQuery/index.jsx')],
},
diff --git a/superset/config.py b/superset/config.py
index a974f85..db5aa6e 100644
--- a/superset/config.py
+++ b/superset/config.py
@@ -309,6 +309,7 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = {
"SIP_38_VIZ_REARCHITECTURE": False,
"TAGGING_SYSTEM": False,
"SQLLAB_BACKEND_PERSISTENCE": False,
+ "SIP_34_DATABASE_UI": False,
}
# This is merely a default.
diff --git a/superset/templates/superset/welcome.html
b/superset/templates/superset/crud_views.html
similarity index 96%
rename from superset/templates/superset/welcome.html
rename to superset/templates/superset/crud_views.html
index 35c2570..57c49ae 100644
--- a/superset/templates/superset/welcome.html
+++ b/superset/templates/superset/crud_views.html
@@ -22,5 +22,5 @@
{% endblock %}
{% block tail_js %}
- {{ js_bundle("welcome") }}
+ {{ js_bundle("crudViews") }}
{% endblock %}
diff --git a/superset/views/base.py b/superset/views/base.py
index 692f289..e139df0 100644
--- a/superset/views/base.py
+++ b/superset/views/base.py
@@ -333,8 +333,8 @@ class SupersetModelView(ModelView):
"common": common_bootstrap_payload(),
}
return self.render_template(
- "superset/welcome.html",
- entry="welcome",
+ "superset/crud_views.html",
+ entry="crudViews",
bootstrap_data=json.dumps(
payload, default=utils.pessimistic_json_iso_dttm_ser
),
diff --git a/superset/views/core.py b/superset/views/core.py
index cee8a61..d6ee690 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -2539,8 +2539,8 @@ class Superset(BaseSupersetView): # pylint:
disable=too-many-public-methods
}
return self.render_template(
- "superset/welcome.html",
- entry="welcome",
+ "superset/crud_views.html",
+ entry="crudViews",
bootstrap_data=json.dumps(
payload, default=utils.pessimistic_json_iso_dttm_ser
),
diff --git a/superset/views/database/views.py b/superset/views/database/views.py
index 654d2a2..6987de9 100644
--- a/superset/views/database/views.py
+++ b/superset/views/database/views.py
@@ -19,8 +19,9 @@ import tempfile
from typing import TYPE_CHECKING
from flask import flash, g, redirect
-from flask_appbuilder import SimpleFormView
+from flask_appbuilder import expose, SimpleFormView
from flask_appbuilder.models.sqla.interface import SQLAInterface
+from flask_appbuilder.security.decorators import has_access
from flask_babel import lazy_gettext as _
from werkzeug.wrappers import Response
from wtforms.fields import StringField
@@ -31,7 +32,9 @@ from superset import app, db
from superset.connectors.sqla.models import SqlaTable
from superset.constants import RouteMethod
from superset.exceptions import CertificateException
+from superset.extensions import feature_flag_manager
from superset.sql_parse import Table
+from superset.typing import FlaskResponse
from superset.utils import core as utils
from superset.views.base import DeleteMixin, SupersetModelView, YamlExportMixin
@@ -93,6 +96,17 @@ class DatabaseView(
def _delete(self, pk: int) -> None:
DeleteMixin._delete(self, pk)
+ @expose("/list/")
+ @has_access
+ def list(self) -> FlaskResponse:
+ if not (
+ app.config["ENABLE_REACT_CRUD_VIEWS"]
+ and feature_flag_manager.is_feature_enabled("SIP_34_DATABASE_UI")
+ ):
+ return super().list()
+
+ return super().render_app_template()
+
class CsvToDatabaseView(SimpleFormView):
form = CsvToDatabaseForm