You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ly...@apache.org on 2022/11/16 00:06:42 UTC

[superset] branch lyndsi/tables-with-preexisting-datasets created (now 4281a00321)

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

lyndsi pushed a change to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 4281a00321 Hover styles added to info banner

This branch includes the following new commits:

     new f5b01d511a User is now notified if a table already has a dataset
     new 16f1f6e985 Tables with dataset flow complete, leftPanel tested
     new d697bbff47 Re-added banner to dataset panel post-rebase
     new 73c5950417 DatasetPanel and Footer tested
     new 4281a00321 Hover styles added to info banner

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[superset] 04/05: DatasetPanel and Footer tested

Posted by ly...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 73c595041750f6bac34d99c8813fba3ad681be09
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Tue Nov 15 17:44:19 2022 -0600

    DatasetPanel and Footer tested
---
 .../AddDataset/DatasetPanel/DatasetPanel.test.tsx  | 31 +++++++++++++++++-----
 .../dataset/AddDataset/DatasetPanel/fixtures.ts    | 14 ++++++++++
 .../data/dataset/AddDataset/Footer/Footer.test.tsx | 17 ++++++++++--
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.test.tsx
index 6800594bd8..5aa12a9c36 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.test.tsx
@@ -24,7 +24,7 @@ import DatasetPanel, {
   tableColumnDefinition,
   COLUMN_TITLE,
 } from './DatasetPanel';
-import { exampleColumns } from './fixtures';
+import { exampleColumns, exampleDataset } from './fixtures';
 import {
   SELECT_MESSAGE,
   CREATE_MESSAGE,
@@ -44,7 +44,7 @@ jest.mock(
 );
 
 describe('DatasetPanel', () => {
-  it('renders a blank state DatasetPanel', () => {
+  test('renders a blank state DatasetPanel', () => {
     render(<DatasetPanel hasError={false} columnList={[]} loading={false} />);
 
     const blankDatasetImg = screen.getByRole('img', { name: /empty/i });
@@ -65,7 +65,7 @@ describe('DatasetPanel', () => {
     expect(sqlLabLink).toBeVisible();
   });
 
-  it('renders a no columns screen', () => {
+  test('renders a no columns screen', () => {
     render(
       <DatasetPanel
         tableName="Name"
@@ -83,7 +83,7 @@ describe('DatasetPanel', () => {
     expect(noColumnsDescription).toBeVisible();
   });
 
-  it('renders a loading screen', () => {
+  test('renders a loading screen', () => {
     render(
       <DatasetPanel
         tableName="Name"
@@ -99,7 +99,7 @@ describe('DatasetPanel', () => {
     expect(blankDatasetTitle).toBeVisible();
   });
 
-  it('renders an error screen', () => {
+  test('renders an error screen', () => {
     render(
       <DatasetPanel
         tableName="Name"
@@ -115,7 +115,7 @@ describe('DatasetPanel', () => {
     expect(errorDescription).toBeVisible();
   });
 
-  it('renders a table with columns displayed', async () => {
+  test('renders a table with columns displayed', async () => {
     const tableName = 'example_name';
     render(
       <DatasetPanel
@@ -138,4 +138,23 @@ describe('DatasetPanel', () => {
       expect(screen.getByText(row.type)).toBeInTheDocument();
     });
   });
+
+  test('renders an info banner if table already has a dataset', async () => {
+    render(
+      <DatasetPanel
+        tableName="example_table"
+        hasError={false}
+        columnList={exampleColumns}
+        loading={false}
+        linkedDatasets={exampleDataset}
+      />,
+    );
+
+    // This is text in the info banner
+    expect(
+      await screen.findByText(
+        /you can only associate one dataset with one table. this table already has a dataset associated with it in preset./i,
+      ),
+    ).toBeVisible();
+  });
 });
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/fixtures.ts b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/fixtures.ts
index 2199190c99..d3ee58da14 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/fixtures.ts
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/fixtures.ts
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
 import { ITableColumn } from './types';
 
 export const exampleColumns: ITableColumn[] = [
@@ -32,3 +33,16 @@ export const exampleColumns: ITableColumn[] = [
     type: 'DATE',
   },
 ];
+
+export const exampleDataset: DatasetObject[] = [
+  {
+    db: {
+      id: 1,
+      database_name: 'test_database',
+      owners: [1],
+    },
+    schema: 'test_schema',
+    dataset_name: 'example_dataset',
+    table_name: 'example_table',
+  },
+];
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/Footer.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/Footer.test.tsx
index bb51c4de86..d0ac88aade 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/Footer.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/Footer.test.tsx
@@ -40,7 +40,7 @@ const mockPropsWithDataset = {
 };
 
 describe('Footer', () => {
-  it('renders a Footer with a cancel button and a disabled create button', () => {
+  test('renders a Footer with a cancel button and a disabled create button', () => {
     render(<Footer {...mockedProps} />, { useRedux: true });
 
     const saveButton = screen.getByRole('button', {
@@ -55,7 +55,7 @@ describe('Footer', () => {
     expect(createButton).toBeDisabled();
   });
 
-  it('renders a Create Dataset button when a table is selected', () => {
+  test('renders a Create Dataset button when a table is selected', () => {
     render(<Footer {...mockPropsWithDataset} />, { useRedux: true });
 
     const createButton = screen.getByRole('button', {
@@ -64,4 +64,17 @@ describe('Footer', () => {
 
     expect(createButton).toBeEnabled();
   });
+
+  test('create button becomes disabled when table already has a dataset', () => {
+    render(
+      <Footer linkedDatasets={['real_info']} {...mockPropsWithDataset} />,
+      { useRedux: true },
+    );
+
+    const createButton = screen.getByRole('button', {
+      name: /Create/i,
+    });
+
+    expect(createButton).toBeDisabled();
+  });
 });


[superset] 05/05: Hover styles added to info banner

Posted by ly...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 4281a0032132f2827c98d4f83bfffa723dd68e04
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Tue Nov 15 18:06:15 2022 -0600

    Hover styles added to info banner
---
 .../views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
index cedbdb2c02..5571e4b773 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
@@ -138,6 +138,11 @@ const StyledAlert = styled(Alert)`
     top: ${supersetTheme.gridUnit * 4}px;
     right: ${supersetTheme.gridUnit * 4}px;
     font-weight: ${supersetTheme.typography.weights.normal};
+
+    &:hover {
+      color: ${supersetTheme.colors.secondary.dark1};
+      text-decoration: underline;
+    }
   }
 `;
 


[superset] 01/05: User is now notified if a table already has a dataset

Posted by ly...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git

commit f5b01d511a7f35e42dc48f1864d8495fae386b22
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Tue Nov 8 11:55:29 2022 -0600

    User is now notified if a table already has a dataset
---
 .../data/dataset/AddDataset/DatasetPanel/index.tsx |  1 +
 .../data/dataset/AddDataset/LeftPanel/index.tsx    | 41 ++++++++++++++++++----
 .../views/CRUD/data/dataset/AddDataset/index.tsx   | 38 +++++++++++++++++++-
 3 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
index e390c781fd..0889ae6132 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
@@ -53,6 +53,7 @@ export interface IDatasetPanelWrapperProps {
    */
   schema?: string | null;
   setHasColumns?: Function;
+  linkedDatasets?: string | undefined;
 }
 
 const DatasetPanelWrapper = ({
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
index 0a5e6ad298..d003eaa575 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
@@ -17,7 +17,13 @@
  * under the License.
  */
 import React, { useEffect, useState, SetStateAction, Dispatch } from 'react';
-import { SupersetClient, t, styled } from '@superset-ui/core';
+import {
+  SupersetClient,
+  t,
+  styled,
+  css,
+  supersetTheme,
+} from '@superset-ui/core';
 import { Input } from 'src/components/Input';
 import { Form } from 'src/components/Form';
 import Icons from 'src/components/Icons';
@@ -36,6 +42,7 @@ interface LeftPanelProps {
   setDataset: Dispatch<SetStateAction<object>>;
   schema?: string | null | undefined;
   dbId?: number;
+  linkedDatasets?: string | undefined;
 }
 
 const SearchIcon = styled(Icons.Search)`
@@ -78,6 +85,7 @@ const LeftPanelStyle = styled.div`
       top: ${theme.gridUnit * 92.25}px;
       left: ${theme.gridUnit * 3.25}px;
       right: 0;
+
       .options {
         cursor: pointer;
         padding: ${theme.gridUnit * 1.75}px;
@@ -86,6 +94,7 @@ const LeftPanelStyle = styled.div`
           background-color: ${theme.colors.grayscale.light4}
         }
       }
+
       .options-highlighted {
         cursor: pointer;
         padding: ${theme.gridUnit * 1.75}px;
@@ -93,6 +102,12 @@ const LeftPanelStyle = styled.div`
         background-color: ${theme.colors.primary.dark1};
         color: ${theme.colors.grayscale.light5};
       }
+
+      .options, .options-highlighted {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+      }
     }
     form > span[aria-label="refresh"] {
       position: absolute;
@@ -124,6 +139,7 @@ export default function LeftPanel({
   setDataset,
   schema,
   dbId,
+  linkedDatasets,
 }: LeftPanelProps) {
   const [tableOptions, setTableOptions] = useState<Array<TableOption>>([]);
   const [resetTables, setResetTables] = useState(false);
@@ -166,9 +182,7 @@ export default function LeftPanel({
         setResetTables(false);
         setRefresh(false);
       })
-      .catch(e => {
-        console.log('error', e);
-      });
+      .catch(error => console.log('There was an error fetching tables', error));
   };
 
   const setSchema = (schema: string) => {
@@ -214,7 +228,7 @@ export default function LeftPanel({
 
   return (
     <LeftPanelStyle>
-      <p className="section-title db-schema">Select database & schema</p>
+      <p className="section-title db-schema">{t('Select database & schema')}</p>
       <DatabaseSelector
         handleError={addDangerToast}
         onDbChange={setDatabase}
@@ -234,7 +248,7 @@ export default function LeftPanel({
       {schema && (tableOptions.length > 0 || searchVal.length > 0) && (
         <>
           <Form>
-            <p className="table-title">Select database table</p>
+            <p className="table-title">{t('Select database table')}</p>
             <RefreshLabel
               onClick={() => {
                 setLoadTables(true);
@@ -242,7 +256,7 @@ export default function LeftPanel({
               }}
               tooltipContent={t('Refresh table list')}
             />
-            {refresh && Loader('Refresh tables')}
+            {refresh && Loader(t('Refresh tables'))}
             {!refresh && (
               <Input
                 value={searchVal}
@@ -269,6 +283,19 @@ export default function LeftPanel({
                   onClick={() => setTable(option.value, i)}
                 >
                   {option.label}
+                  {linkedDatasets && option.value.includes(linkedDatasets) && (
+                    <Icons.Warning
+                      iconColor={
+                        selectedTable === i
+                          ? supersetTheme.colors.grayscale.light5
+                          : supersetTheme.colors.info.base
+                      }
+                      iconSize="m"
+                      css={css`
+                        margin-right: ${supersetTheme.gridUnit * 6}px;
+                      `}
+                    />
+                  )}
                 </div>
               ))}
           </div>
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
index 9696c45156..5357459ddc 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
@@ -16,7 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import React, { useReducer, Reducer, useState } from 'react';
+import React, { useReducer, Reducer, useEffect, useState } from 'react';
+import { SupersetClient } from '@superset-ui/core';
+import rison from 'rison';
 import Header from './Header';
 import DatasetPanel from './DatasetPanel';
 import LeftPanel from './LeftPanel';
@@ -73,6 +75,38 @@ export default function AddDataset() {
     Reducer<Partial<DatasetObject> | null, DSReducerActionType>
   >(datasetReducer, null);
   const [hasColumns, setHasColumns] = useState(false);
+  const [linkedDatasets, setLinkedDatasets] = useState<string>();
+
+  const encodedSchema = dataset?.schema
+    ? encodeURIComponent(dataset?.schema)
+    : undefined;
+
+  const queryParams = dataset?.schema
+    ? rison.encode_uri({
+        filters: [
+          { col: 'schema', opr: 'eq', value: encodedSchema },
+          { col: 'sql', opr: 'dataset_is_null_or_empty', value: '!t' },
+        ],
+      })
+    : undefined;
+
+  const getDatasetsList = () => {
+    SupersetClient.get({
+      endpoint: `/api/v1/dataset/?q=${queryParams}`,
+    })
+      .then(({ json }) => {
+        json.result.map((dataset: any) =>
+          setLinkedDatasets(dataset.table_name),
+        );
+      })
+      .catch(error =>
+        console.log('There was an error fetching dataset', error),
+      );
+  };
+
+  useEffect(() => {
+    if (dataset?.schema) getDatasetsList();
+  }, [dataset?.schema]);
 
   const HeaderComponent = () => (
     <Header setDataset={setDataset} title={dataset?.table_name} />
@@ -83,6 +117,7 @@ export default function AddDataset() {
       setDataset={setDataset}
       schema={dataset?.schema}
       dbId={dataset?.db?.id}
+      linkedDatasets={linkedDatasets}
     />
   );
 
@@ -92,6 +127,7 @@ export default function AddDataset() {
       dbId={dataset?.db?.id}
       schema={dataset?.schema}
       setHasColumns={setHasColumns}
+      linkedDatasets={linkedDatasets}
     />
   );
 


[superset] 03/05: Re-added banner to dataset panel post-rebase

Posted by ly...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git

commit d697bbff4704d9965b50ebd7627c49c7424fd876
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Tue Nov 15 17:11:04 2022 -0600

    Re-added banner to dataset panel post-rebase
---
 .../AddDataset/DatasetPanel/DatasetPanel.tsx       | 81 ++++++++++++++++++----
 .../data/dataset/AddDataset/DatasetPanel/index.tsx |  5 +-
 .../CRUD/data/dataset/AddDataset/Footer/index.tsx  |  8 ++-
 .../views/CRUD/data/dataset/AddDataset/index.tsx   |  7 +-
 4 files changed, 84 insertions(+), 17 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
index 2a5e12cea8..cedbdb2c02 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/DatasetPanel.tsx
@@ -19,10 +19,12 @@
 import React from 'react';
 import { supersetTheme, t, styled } from '@superset-ui/core';
 import Icons from 'src/components/Icons';
+import Alert from 'src/components/Alert';
 import Table, { ColumnsType, TableSize } from 'src/components/Table';
 import { alphabeticalSort } from 'src/components/Table/sorters';
 // @ts-ignore
 import LOADING_GIF from 'src/assets/images/loading.gif';
+import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
 import { ITableColumn } from './types';
 import MessageContent from './MessageContent';
 
@@ -54,8 +56,10 @@ const MARGIN_MULTIPLIER = 3;
 
 const StyledHeader = styled.div<StyledHeaderProps>`
   position: ${(props: StyledHeaderProps) => props.position};
-  margin: ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px;
-  margin-top: ${({ theme }) => theme.gridUnit * (MARGIN_MULTIPLIER + 1)}px;
+  margin: ${({ theme }) => theme.gridUnit * (MARGIN_MULTIPLIER + 1)}px
+    ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px
+    ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px
+    ${({ theme }) => theme.gridUnit * (MARGIN_MULTIPLIER + 3)}px;
   font-size: ${({ theme }) => theme.gridUnit * 6}px;
   font-weight: ${({ theme }) => theme.typography.weights.medium};
   padding-bottom: ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px;
@@ -74,7 +78,7 @@ const StyledHeader = styled.div<StyledHeaderProps>`
 `;
 
 const StyledTitle = styled.div`
-  margin-left: ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px;
+  margin-left: ${({ theme }) => theme.gridUnit * (MARGIN_MULTIPLIER + 3)}px;
   margin-bottom: ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px;
   font-weight: ${({ theme }) => theme.typography.weights.bold};
 `;
@@ -111,6 +115,7 @@ const StyledLoader = styled.div`
 const TableContainer = styled.div`
   position: relative;
   margin: ${({ theme }) => theme.gridUnit * MARGIN_MULTIPLIER}px;
+  margin-left: ${({ theme }) => theme.gridUnit * (MARGIN_MULTIPLIER + 3)}px;
   overflow: scroll;
   height: calc(100% - ${({ theme }) => theme.gridUnit * 36}px);
 `;
@@ -123,6 +128,19 @@ const StyledTable = styled(Table)`
   right: 0;
 `;
 
+const StyledAlert = styled(Alert)`
+  border: 1px solid ${supersetTheme.colors.info.base};
+  padding: ${supersetTheme.gridUnit * 4}px;
+  margin: ${supersetTheme.gridUnit * 6}px ${supersetTheme.gridUnit * 6}px
+    ${supersetTheme.gridUnit * 8}px;
+  .view-dataset-button {
+    position: absolute;
+    top: ${supersetTheme.gridUnit * 4}px;
+    right: ${supersetTheme.gridUnit * 4}px;
+    font-weight: ${supersetTheme.typography.weights.normal};
+  }
+`;
+
 export const REFRESHING = t('Refreshing columns');
 export const COLUMN_TITLE = t('Table columns');
 export const ALT_LOADING = t('Loading');
@@ -168,15 +186,44 @@ export interface IDatasetPanelProps {
    * Boolean indicating if the component is in a loading state
    */
   loading: boolean;
+  linkedDatasets?: DatasetObject[] | undefined;
 }
 
+const renderExistingDatasetAlert = (linkedDataset: any) => (
+  <StyledAlert
+    closable={false}
+    type="info"
+    showIcon
+    message={t('This table already has a dataset')}
+    description={
+      <>
+        {t(
+          'You can only associate one dataset with one table. This table already has a dataset associated with it in Preset.\n',
+        )}
+        <span
+          role="button"
+          onClick={() => {
+            window.location.href = linkedDataset.explore_url;
+          }}
+          tabIndex={0}
+          className="view-dataset-button"
+        >
+          {t('View Dataset')}
+        </span>
+      </>
+    }
+  />
+);
+
 const DatasetPanel = ({
   tableName,
   columnList,
   loading,
   hasError,
+  linkedDatasets,
 }: IDatasetPanelProps) => {
   const hasColumns = columnList?.length > 0 ?? false;
+  const linkedDatasetNames = linkedDatasets?.map(dataset => dataset.table_name);
 
   let component;
   if (loading) {
@@ -217,17 +264,23 @@ const DatasetPanel = ({
   return (
     <>
       {tableName && (
-        <StyledHeader
-          position={
-            !loading && hasColumns ? EPosition.RELATIVE : EPosition.ABSOLUTE
-          }
-          title={tableName || ''}
-        >
-          {tableName && (
-            <Icons.Table iconColor={supersetTheme.colors.grayscale.base} />
-          )}
-          {tableName}
-        </StyledHeader>
+        <>
+          {linkedDatasetNames?.includes(tableName) &&
+            renderExistingDatasetAlert(
+              linkedDatasets?.find(dataset => dataset.table_name === tableName),
+            )}
+          <StyledHeader
+            position={
+              !loading && hasColumns ? EPosition.RELATIVE : EPosition.ABSOLUTE
+            }
+            title={tableName || ''}
+          >
+            {tableName && (
+              <Icons.Table iconColor={supersetTheme.colors.grayscale.base} />
+            )}
+            {tableName}
+          </StyledHeader>
+        </>
       )}
       {component}
     </>
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
index 748bb0db6a..602d6ad9ee 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
@@ -18,6 +18,7 @@
  */
 import React, { useEffect, useState, useRef } from 'react';
 import { SupersetClient } from '@superset-ui/core';
+import { DatasetObject } from 'src/views/CRUD/data/dataset/AddDataset/types';
 import DatasetPanel from './DatasetPanel';
 import { ITableColumn, IDatabaseTable, isIDatabaseTable } from './types';
 
@@ -61,6 +62,7 @@ const DatasetPanelWrapper = ({
   dbId,
   schema,
   setHasColumns,
+  linkedDatasets,
 }: IDatasetPanelWrapperProps) => {
   const [columnList, setColumnList] = useState<ITableColumn[]>([]);
   const [loading, setLoading] = useState(false);
@@ -111,7 +113,7 @@ const DatasetPanelWrapper = ({
     if (tableName && schema && dbId) {
       getTableMetadata({ tableName, dbId, schema });
     }
-    // getTableMetadata is a const and should not be independency array
+    // getTableMetadata is a const and should not be in dependency array
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [tableName, dbId, schema]);
 
@@ -121,6 +123,7 @@ const DatasetPanelWrapper = ({
       hasError={hasError}
       loading={loading}
       tableName={tableName}
+      linkedDatasets={linkedDatasets}
     />
   );
 };
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/index.tsx
index 7e08f3b9df..5f2defd081 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Footer/index.tsx
@@ -37,6 +37,7 @@ interface FooterProps {
   datasetObject?: Partial<DatasetObject> | null;
   onDatasetAdd?: (dataset: DatasetObject) => void;
   hasColumns?: boolean;
+  linkedDatasets?: (string | null | undefined)[] | undefined;
 }
 
 const INPUT_FIELDS = ['db', 'schema', 'table_name'];
@@ -52,6 +53,7 @@ function Footer({
   datasetObject,
   addDangerToast,
   hasColumns = false,
+  linkedDatasets,
 }: FooterProps) {
   const { createResource } = useSingleViewResource<Partial<DatasetObject>>(
     'dataset',
@@ -113,7 +115,11 @@ function Footer({
       <Button onClick={cancelButtonOnClick}>Cancel</Button>
       <Button
         buttonStyle="primary"
-        disabled={!datasetObject?.table_name || !hasColumns}
+        disabled={
+          !datasetObject?.table_name ||
+          !hasColumns ||
+          linkedDatasets?.includes(datasetObject?.table_name)
+        }
         tooltip={!datasetObject?.table_name ? tooltipText : undefined}
         onClick={onSave}
       >
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
index 6c2d3dc7d5..bf62c2b4c8 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
@@ -132,7 +132,12 @@ export default function AddDataset() {
   );
 
   const FooterComponent = () => (
-    <Footer url={prevUrl} datasetObject={dataset} hasColumns={hasColumns} />
+    <Footer
+      url={prevUrl}
+      datasetObject={dataset}
+      hasColumns={hasColumns}
+      linkedDatasets={linkedDatasetNames}
+    />
   );
 
   return (


[superset] 02/05: Tables with dataset flow complete, leftPanel tested

Posted by ly...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/tables-with-preexisting-datasets
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 16f1f6e98587ab578a330464531d6e0afd9d0c29
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Mon Nov 14 20:42:25 2022 -0600

    Tables with dataset flow complete, leftPanel tested
---
 .../data/dataset/AddDataset/DatasetPanel/index.tsx |  2 +-
 .../AddDataset/LeftPanel/LeftPanel.test.tsx        | 45 ++++++++++++++++++++++
 .../data/dataset/AddDataset/LeftPanel/index.tsx    |  4 +-
 .../views/CRUD/data/dataset/AddDataset/index.tsx   |  8 ++--
 4 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
index 0889ae6132..748bb0db6a 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/DatasetPanel/index.tsx
@@ -53,7 +53,7 @@ export interface IDatasetPanelWrapperProps {
    */
   schema?: string | null;
   setHasColumns?: Function;
-  linkedDatasets?: string | undefined;
+  linkedDatasets?: DatasetObject[] | undefined;
 }
 
 const DatasetPanelWrapper = ({
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/LeftPanel.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/LeftPanel.test.tsx
index 3b2ef18181..5d5d5419e9 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/LeftPanel.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/LeftPanel.test.tsx
@@ -209,6 +209,7 @@ test('searches for a table name', async () => {
     useRedux: true,
   });
 
+  // Click 'test-postgres' database to access schemas
   const databaseSelect = screen.getByRole('combobox', {
     name: /select database or type database name/i,
   });
@@ -221,6 +222,7 @@ test('searches for a table name', async () => {
 
   await waitFor(() => expect(schemaSelect).toBeEnabled());
 
+  // Click 'public' schema to access tables
   userEvent.click(schemaSelect);
   userEvent.click(screen.getAllByText('public')[1]);
 
@@ -238,3 +240,46 @@ test('searches for a table name', async () => {
     expect(screen.queryByText('Sheet3')).not.toBeInTheDocument();
   });
 });
+
+test('renders a warning icon when a table name has a pre-existing dataset', async () => {
+  render(
+    <LeftPanel
+      setDataset={mockFun}
+      schema="schema_a"
+      dbId={1}
+      linkedDatasets={['Sheet2']}
+    />,
+    {
+      useRedux: true,
+    },
+  );
+
+  // Click 'test-postgres' database to access schemas
+  const databaseSelect = screen.getByRole('combobox', {
+    name: /select database or type database name/i,
+  });
+  userEvent.click(databaseSelect);
+  userEvent.click(await screen.findByText('test-postgres'));
+
+  const schemaSelect = screen.getByRole('combobox', {
+    name: /select schema or type schema name/i,
+  });
+
+  await waitFor(() => expect(schemaSelect).toBeEnabled());
+
+  // Warning icon should not show yet
+  expect(
+    screen.queryByRole('img', { name: 'warning' }),
+  ).not.toBeInTheDocument();
+
+  // Click 'public' schema to access tables
+  userEvent.click(schemaSelect);
+  userEvent.click(screen.getAllByText('public')[1]);
+
+  await waitFor(() => {
+    expect(screen.getByText('Sheet2')).toBeInTheDocument();
+  });
+
+  // Sheet2 should now show the warning icon
+  expect(screen.getByRole('img', { name: 'warning' })).toBeVisible();
+});
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
index d003eaa575..2602066bca 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/LeftPanel/index.tsx
@@ -42,7 +42,7 @@ interface LeftPanelProps {
   setDataset: Dispatch<SetStateAction<object>>;
   schema?: string | null | undefined;
   dbId?: number;
-  linkedDatasets?: string | undefined;
+  linkedDatasets?: (string | null | undefined)[] | undefined;
 }
 
 const SearchIcon = styled(Icons.Search)`
@@ -283,7 +283,7 @@ export default function LeftPanel({
                   onClick={() => setTable(option.value, i)}
                 >
                   {option.label}
-                  {linkedDatasets && option.value.includes(linkedDatasets) && (
+                  {linkedDatasets?.includes(option.value) && (
                     <Icons.Warning
                       iconColor={
                         selectedTable === i
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
index 5357459ddc..6c2d3dc7d5 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/index.tsx
@@ -75,8 +75,8 @@ export default function AddDataset() {
     Reducer<Partial<DatasetObject> | null, DSReducerActionType>
   >(datasetReducer, null);
   const [hasColumns, setHasColumns] = useState(false);
-  const [linkedDatasets, setLinkedDatasets] = useState<string>();
-
+  const [linkedDatasets, setLinkedDatasets] = useState<DatasetObject[]>([]);
+  const linkedDatasetNames = linkedDatasets.map(dataset => dataset.table_name);
   const encodedSchema = dataset?.schema
     ? encodeURIComponent(dataset?.schema)
     : undefined;
@@ -96,7 +96,7 @@ export default function AddDataset() {
     })
       .then(({ json }) => {
         json.result.map((dataset: any) =>
-          setLinkedDatasets(dataset.table_name),
+          setLinkedDatasets(linkedDatasets => [...linkedDatasets, dataset]),
         );
       })
       .catch(error =>
@@ -117,7 +117,7 @@ export default function AddDataset() {
       setDataset={setDataset}
       schema={dataset?.schema}
       dbId={dataset?.db?.id}
-      linkedDatasets={linkedDatasets}
+      linkedDatasets={linkedDatasetNames}
     />
   );