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/08/24 21:40:15 UTC

[superset] 01/01: Created blank header component

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

lyndsi pushed a commit to branch lyndsi/create-dataset-header
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 13c652e93d7865b5feba5dc4576c252984f9652a
Author: lyndsiWilliams <kc...@gmail.com>
AuthorDate: Wed Aug 24 16:35:53 2022 -0500

    Created blank header component
---
 .../src/components/PageHeaderWithActions/index.tsx |  8 +++
 .../data/dataset/AddDataset/AddDataset.test.tsx    | 19 +++--
 .../data/dataset/AddDataset/Header/Header.test.tsx | 28 ++++++--
 .../CRUD/data/dataset/AddDataset/Header/index.tsx  | 80 +++++++++++++++++++++-
 .../dataset/DatasetLayout/DatasetLayout.test.tsx   | 20 ++++--
 .../src/views/CRUD/data/dataset/styles.ts          |  5 +-
 6 files changed, 146 insertions(+), 14 deletions(-)

diff --git a/superset-frontend/src/components/PageHeaderWithActions/index.tsx b/superset-frontend/src/components/PageHeaderWithActions/index.tsx
index e85ccdfc82..b06a7b5c9e 100644
--- a/superset-frontend/src/components/PageHeaderWithActions/index.tsx
+++ b/superset-frontend/src/components/PageHeaderWithActions/index.tsx
@@ -19,6 +19,7 @@
 import React, { ReactNode, ReactElement } from 'react';
 import { css, SupersetTheme, t, useTheme } from '@superset-ui/core';
 import { AntdDropdown, AntdDropdownProps } from 'src/components';
+import { TooltipPlacement } from 'antd/es/tooltip';
 import {
   DynamicEditableTitle,
   DynamicEditableTitleProps,
@@ -112,6 +113,10 @@ export type PageHeaderWithActionsProps = {
   rightPanelAdditionalItems: ReactNode;
   additionalActionsMenu: ReactElement;
   menuDropdownProps: Omit<AntdDropdownProps, 'overlay'>;
+  tooltipProps?: {
+    text: string;
+    placement: TooltipPlacement;
+  };
 };
 
 export const PageHeaderWithActions = ({
@@ -124,6 +129,7 @@ export const PageHeaderWithActions = ({
   rightPanelAdditionalItems,
   additionalActionsMenu,
   menuDropdownProps,
+  tooltipProps,
 }: PageHeaderWithActionsProps) => {
   const theme = useTheme();
   return (
@@ -152,6 +158,8 @@ export const PageHeaderWithActions = ({
               css={menuTriggerStyles}
               buttonStyle="tertiary"
               aria-label={t('Menu actions trigger')}
+              tooltip={tooltipProps?.text ?? undefined}
+              placement={tooltipProps?.placement ?? undefined}
             >
               <Icons.MoreHoriz
                 iconColor={theme.colors.primary.dark2}
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/AddDataset.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/AddDataset.test.tsx
index 23c5c3b471..0341fe256e 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/AddDataset.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/AddDataset.test.tsx
@@ -17,17 +17,28 @@
  * under the License.
  */
 import React from 'react';
-import { render, screen } from 'spec/helpers/testing-library';
+import { render, screen, act } from 'spec/helpers/testing-library';
 import AddDataset from 'src/views/CRUD/data/dataset/AddDataset';
 
 describe('AddDataset', () => {
-  it('renders a blank state AddDataset', () => {
-    render(<AddDataset />);
+  const renderAndWait = async () => {
+    const mounted = act(async () => {
+      render(<AddDataset />);
+    });
+
+    return mounted;
+  };
+  it('renders a blank state AddDataset', async () => {
+    await renderAndWait();
 
     const blankeStateImgs = screen.getAllByRole('img', { name: /empty/i });
 
     // Header
-    expect(screen.getByText(/header/i)).toBeVisible();
+    expect(
+      screen.getByRole('textbox', {
+        name: /dataset name/i,
+      }),
+    ).toBeVisible();
     // Left panel
     expect(blankeStateImgs[0]).toBeVisible();
     expect(screen.getByText(/no database tables found/i)).toBeVisible();
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/Header.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/Header.test.tsx
index c913dbc86a..a66b373825 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/Header.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/Header.test.tsx
@@ -17,13 +17,33 @@
  * under the License.
  */
 import React from 'react';
-import { render, screen } from 'spec/helpers/testing-library';
+import { render, screen, act } from 'spec/helpers/testing-library';
 import Header from 'src/views/CRUD/data/dataset/AddDataset/Header';
 
 describe('Header', () => {
-  it('renders a blank state Header', () => {
-    render(<Header />);
+  const renderAndWait = async () => {
+    const mounted = act(async () => {
+      render(<Header />);
+    });
 
-    expect(screen.getByText(/header/i)).toBeVisible();
+    return mounted;
+  };
+
+  it('renders a blank state Header', async () => {
+    await renderAndWait();
+
+    const datasetNameTextbox = screen.getByRole('textbox', {
+      name: /dataset name/i,
+    });
+    const saveButton = screen.getByRole('button', {
+      name: /save save/i,
+    });
+    const menuButton = screen.getByRole('button', {
+      name: /menu actions trigger/i,
+    });
+
+    expect(datasetNameTextbox).toBeVisible();
+    expect(saveButton).toBeVisible();
+    expect(menuButton).toBeVisible();
   });
 });
diff --git a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/index.tsx b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/index.tsx
index 44f0e19f7b..f7e4b34df2 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/AddDataset/Header/index.tsx
@@ -17,7 +17,85 @@
  * under the License.
  */
 import React from 'react';
+import { t, styled, css, SupersetTheme } from '@superset-ui/core';
+import { PageHeaderWithActions } from 'src/components/PageHeaderWithActions';
+import Button from 'src/components/Button';
+import Icons from 'src/components/Icons';
+import { Menu } from 'src/components/Menu';
+import { TooltipPlacement } from 'antd/es/tooltip';
+
+const editableTitleProps = {
+  title: '',
+  placeholder: 'Add the name of the dataset',
+  onSave: () => {},
+  canEdit: true,
+  label: 'dataset name',
+};
+
+const tooltipProps: { text: string; placement: TooltipPlacement } = {
+  text: 'Select a database table and create dataset',
+  placement: 'bottomRight',
+};
+
+const Styles = styled.div`
+  .ant-btn {
+    span {
+      margin-right: 0;
+    }
+
+    &:disabled {
+      svg {
+        color: ${({ theme }) => theme.colors.grayscale.light1};
+      }
+    }
+  }
+`;
+
+const disabledSaveBtnStyles = (theme: SupersetTheme) => css`
+  width: ${theme.gridUnit * 21.5}px;
+
+  &:disabled {
+    background-color: ${theme.colors.grayscale.light3};
+    color: ${theme.colors.grayscale.light1};
+  }
+`;
+
+const renderDisabledSaveButton = () => (
+  <Button
+    buttonStyle="primary"
+    tooltip={tooltipProps?.text}
+    placement={tooltipProps?.placement}
+    disabled
+    css={disabledSaveBtnStyles}
+  >
+    <Icons.Save iconSize="m" />
+    {t('Save')}
+  </Button>
+);
+
+const renderOverlay = () => (
+  <Menu>
+    <Menu.Item>{t('Settings')}</Menu.Item>
+    <Menu.Item>{t('Delete')}</Menu.Item>
+  </Menu>
+);
 
 export default function Header() {
-  return <div>Header</div>;
+  return (
+    <Styles>
+      <PageHeaderWithActions
+        editableTitleProps={editableTitleProps}
+        showTitlePanelItems={false}
+        showFaveStar={false}
+        faveStarProps={{ itemId: 1, saveFaveStar: () => {} }}
+        titlePanelAdditionalItems={<></>}
+        rightPanelAdditionalItems={renderDisabledSaveButton()}
+        additionalActionsMenu={renderOverlay()}
+        menuDropdownProps={{
+          disabled: true,
+        }}
+        tooltipProps={tooltipProps}
+      />
+    </Styles>
+  );
 }
diff --git a/superset-frontend/src/views/CRUD/data/dataset/DatasetLayout/DatasetLayout.test.tsx b/superset-frontend/src/views/CRUD/data/dataset/DatasetLayout/DatasetLayout.test.tsx
index 59c3ee3ed1..d0b03dcac5 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/DatasetLayout/DatasetLayout.test.tsx
+++ b/superset-frontend/src/views/CRUD/data/dataset/DatasetLayout/DatasetLayout.test.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 import React from 'react';
-import { render, screen } from 'spec/helpers/testing-library';
+import { render, screen, act } from 'spec/helpers/testing-library';
 import DatasetLayout from 'src/views/CRUD/data/dataset/DatasetLayout';
 import Header from 'src/views/CRUD/data/dataset/AddDataset/Header';
 import LeftPanel from 'src/views/CRUD/data/dataset/AddDataset/LeftPanel';
@@ -33,10 +33,22 @@ describe('DatasetLayout', () => {
     expect(layoutWrapper).toHaveTextContent('');
   });
 
-  it('renders a Header when passed in', () => {
-    render(<DatasetLayout header={Header()} />);
+  const renderHeaderAndWait = async () => {
+    const mounted = act(async () => {
+      render(<Header />);
+    });
 
-    expect(screen.getByText(/header/i)).toBeVisible();
+    return mounted;
+  };
+
+  it('renders a Header when passed in', async () => {
+    await renderHeaderAndWait();
+
+    expect(
+      screen.getByRole('textbox', {
+        name: /dataset name/i,
+      }),
+    ).toBeVisible();
   });
 
   it('renders a LeftPanel when passed in', () => {
diff --git a/superset-frontend/src/views/CRUD/data/dataset/styles.ts b/superset-frontend/src/views/CRUD/data/dataset/styles.ts
index 8d9f771dce..196726d2df 100644
--- a/superset-frontend/src/views/CRUD/data/dataset/styles.ts
+++ b/superset-frontend/src/views/CRUD/data/dataset/styles.ts
@@ -68,7 +68,10 @@ export const StyledHeader = styled.div`
   flex: 0 0 auto;
   height: ${({ theme }) => theme.gridUnit * 16}px;
   border-bottom: 2px solid ${({ theme }) => theme.colors.grayscale.light2};
-  color: ${({ theme }) => theme.colors.error.base};
+
+  .header-with-actions {
+    height: ${({ theme }) => theme.gridUnit * 15.5}px;
+  }
 `;
 
 export const StyledLeftPanel = styled.div`