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

stephenlyz 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 8345eb4644 fix: A newly connected database doesn't appear in the 
databases list if user connected database using the 'plus' button (#19967)
8345eb4644 is described below

commit 8345eb4644947180e3c84ed26498abb7fa194de9
Author: Diego Medina <[email protected]>
AuthorDate: Sun Jun 12 11:21:30 2022 -0300

    fix: A newly connected database doesn't appear in the databases list if 
user connected database using the 'plus' button (#19967)
    
    * fix: A newly connected database doesn't appear in the databases list if 
user connected database using the 'plus' button
    
    * include onDatabaseAdd on successful import
---
 .../src/views/CRUD/data/database/DatabaseList.tsx  | 13 +++++++
 .../CRUD/data/database/DatabaseModal/index.tsx     |  2 +-
 .../src/views/components/Menu.test.tsx             | 43 ++++++++++++----------
 .../src/views/components/MenuRight.tsx             |  9 +++++
 4 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx 
b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
index df4ef3cf02..b9c5b4a846 100644
--- a/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseList.tsx
@@ -20,6 +20,8 @@ import { SupersetClient, t, styled } from '@superset-ui/core';
 import React, { useState, useMemo, useEffect } from 'react';
 import rison from 'rison';
 import { useSelector } from 'react-redux';
+import { useQueryParams, BooleanParam } from 'use-query-params';
+
 import Loading from 'src/components/Loading';
 import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
 import { useListViewResource } from 'src/views/CRUD/hooks';
@@ -91,6 +93,10 @@ function DatabaseList({ addDangerToast, addSuccessToast }: 
DatabaseListProps) {
     state => state.user,
   );
 
+  const [query, setQuery] = useQueryParams({
+    databaseAdded: BooleanParam,
+  });
+
   const [databaseModalOpen, setDatabaseModalOpen] = useState<boolean>(false);
   const [databaseCurrentlyDeleting, setDatabaseCurrentlyDeleting] =
     useState<DatabaseDeleteObject | null>(null);
@@ -110,6 +116,13 @@ function DatabaseList({ addDangerToast, addSuccessToast }: 
DatabaseListProps) {
     ALLOWED_EXTENSIONS,
   } = useSelector<any, ExtentionConfigs>(state => state.common.conf);
 
+  useEffect(() => {
+    if (query?.databaseAdded) {
+      setQuery({ databaseAdded: undefined });
+      refreshData();
+    }
+  }, [query, setQuery, refreshData]);
+
   const openDatabaseDeleteModal = (database: DatabaseObject) =>
     SupersetClient.get({
       endpoint: `/api/v1/database/${database.id}/related_objects/`,
diff --git 
a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx 
b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
index 392df834dd..2b97ed791b 100644
--- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
@@ -519,7 +519,6 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> 
= ({
     setImportingModal(false);
     setPasswords({});
     setConfirmedOverwrite(false);
-    if (onDatabaseAdd) onDatabaseAdd();
     onHide();
   };
 
@@ -652,6 +651,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> 
= ({
         confirmedOverwrite,
       );
       if (dbId) {
+        if (onDatabaseAdd) onDatabaseAdd();
         onClose();
         addSuccessToast(t('Database connected'));
       }
diff --git a/superset-frontend/src/views/components/Menu.test.tsx 
b/superset-frontend/src/views/components/Menu.test.tsx
index a80a43a22f..0d84d2c663 100644
--- a/superset-frontend/src/views/components/Menu.test.tsx
+++ b/superset-frontend/src/views/components/Menu.test.tsx
@@ -248,13 +248,16 @@ beforeEach(() => {
 
 test('should render', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  const { container } = render(<Menu {...mockedProps} />, { useRedux: true });
+  const { container } = render(<Menu {...mockedProps} />, {
+    useRedux: true,
+    useQueryParams: true,
+  });
   expect(container).toBeInTheDocument();
 });
 
 test('should render the navigation', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.getByRole('navigation')).toBeInTheDocument();
 });
 
@@ -265,7 +268,7 @@ test('should render the brand', () => {
       brand: { alt, icon },
     },
   } = mockedProps;
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   const image = screen.getByAltText(alt);
   expect(image).toHaveAttribute('src', icon);
 });
@@ -275,7 +278,7 @@ test('should render all the top navbar menu items', () => {
   const {
     data: { menu },
   } = mockedProps;
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   menu.forEach(item => {
     expect(screen.getByText(item.label)).toBeInTheDocument();
   });
@@ -286,7 +289,7 @@ test('should render the top navbar child menu items', async 
() => {
   const {
     data: { menu },
   } = mockedProps;
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   const sources = screen.getByText('Sources');
   userEvent.hover(sources);
   const datasets = await screen.findByText('Datasets');
@@ -300,7 +303,7 @@ test('should render the top navbar child menu items', async 
() => {
 
 test('should render the dropdown items', async () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...notanonProps} />, { useRedux: true });
+  render(<Menu {...notanonProps} />, { useRedux: true, useQueryParams: true });
   const dropdown = screen.getByTestId('new-dropdown-icon');
   userEvent.hover(dropdown);
   // todo (philip): test data submenu
@@ -326,14 +329,14 @@ test('should render the dropdown items', async () => {
 
 test('should render the Settings', async () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   const settings = await screen.findByText('Settings');
   expect(settings).toBeInTheDocument();
 });
 
 test('should render the Settings menu item', async () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   userEvent.hover(screen.getByText('Settings'));
   const label = await screen.findByText('Security');
   expect(label).toBeInTheDocument();
@@ -344,7 +347,7 @@ test('should render the Settings dropdown child menu 
items', async () => {
   const {
     data: { settings },
   } = mockedProps;
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   userEvent.hover(screen.getByText('Settings'));
   const listUsers = await screen.findByText('List Users');
   expect(listUsers).toHaveAttribute('href', settings[0].childs[0].url);
@@ -352,13 +355,13 @@ test('should render the Settings dropdown child menu 
items', async () => {
 
 test('should render the plus menu (+) when user is not anonymous', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...notanonProps} />, { useRedux: true });
+  render(<Menu {...notanonProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.getByTestId('new-dropdown')).toBeInTheDocument();
 });
 
 test('should NOT render the plus menu (+) when user is anonymous', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument();
 });
 
@@ -370,7 +373,7 @@ test('should render the user actions when user is not 
anonymous', async () => {
     },
   } = mockedProps;
 
-  render(<Menu {...notanonProps} />, { useRedux: true });
+  render(<Menu {...notanonProps} />, { useRedux: true, useQueryParams: true });
   userEvent.hover(screen.getByText('Settings'));
   const user = await screen.findByText('User');
   expect(user).toBeInTheDocument();
@@ -384,7 +387,7 @@ test('should render the user actions when user is not 
anonymous', async () => {
 
 test('should NOT render the user actions when user is anonymous', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.queryByText('User')).not.toBeInTheDocument();
 });
 
@@ -396,7 +399,7 @@ test('should render the Profile link when available', async 
() => {
     },
   } = mockedProps;
 
-  render(<Menu {...notanonProps} />, { useRedux: true });
+  render(<Menu {...notanonProps} />, { useRedux: true, useQueryParams: true });
 
   userEvent.hover(screen.getByText('Settings'));
   const profile = await screen.findByText('Profile');
@@ -411,7 +414,7 @@ test('should render the About section and version_string, 
sha or build_number wh
     },
   } = mockedProps;
 
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   userEvent.hover(screen.getByText('Settings'));
   const about = await screen.findByText('About');
   const version = await screen.findByText(`Version: ${version_string}`);
@@ -430,7 +433,7 @@ test('should render the Documentation link when available', 
async () => {
       navbar_right: { documentation_url },
     },
   } = mockedProps;
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   userEvent.hover(screen.getByText('Settings'));
   const doc = await screen.findByTitle('Documentation');
   expect(doc).toHaveAttribute('href', documentation_url);
@@ -444,7 +447,7 @@ test('should render the Bug Report link when available', 
async () => {
     },
   } = mockedProps;
 
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   const bugReport = await screen.findByTitle('Report a bug');
   expect(bugReport).toHaveAttribute('href', bug_report_url);
 });
@@ -457,19 +460,19 @@ test('should render the Login link when user is 
anonymous', () => {
     },
   } = mockedProps;
 
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   const login = screen.getByText('Login');
   expect(login).toHaveAttribute('href', user_login_url);
 });
 
 test('should render the Language Picker', () => {
   useSelectorMock.mockReturnValue({ roles: user.roles });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.getByLabelText('Languages')).toBeInTheDocument();
 });
 
 test('should hide create button without proper roles', () => {
   useSelectorMock.mockReturnValue({ roles: [] });
-  render(<Menu {...mockedProps} />, { useRedux: true });
+  render(<Menu {...mockedProps} />, { useRedux: true, useQueryParams: true });
   expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument();
 });
diff --git a/superset-frontend/src/views/components/MenuRight.tsx 
b/superset-frontend/src/views/components/MenuRight.tsx
index 4c34b88349..61bc6de0d6 100644
--- a/superset-frontend/src/views/components/MenuRight.tsx
+++ b/superset-frontend/src/views/components/MenuRight.tsx
@@ -20,6 +20,8 @@ import React, { Fragment, useState, useEffect } from 'react';
 import rison from 'rison';
 import { useSelector } from 'react-redux';
 import { Link } from 'react-router-dom';
+import { useQueryParams, BooleanParam } from 'use-query-params';
+
 import {
   t,
   styled,
@@ -94,6 +96,10 @@ const RightMenu = ({
     state => state.dashboardInfo?.id,
   );
 
+  const [, setQuery] = useQueryParams({
+    databaseAdded: BooleanParam,
+  });
+
   const { roles } = user;
   const {
     CSV_EXTENSIONS,
@@ -250,6 +256,8 @@ const RightMenu = ({
     return null;
   };
 
+  const handleDatabaseAdd = () => setQuery({ databaseAdded: true });
+
   return (
     <StyledDiv align={align}>
       {canDatabase && (
@@ -257,6 +265,7 @@ const RightMenu = ({
           onHide={handleOnHideModal}
           show={showModal}
           dbEngine={engine}
+          onDatabaseAdd={handleDatabaseAdd}
         />
       )}
       <Menu

Reply via email to