This is an automated email from the ASF dual-hosted git repository. enzomartellucci pushed a commit to branch enxdev/refactor/antd5/create-wrappers in repository https://gitbox.apache.org/repos/asf/superset.git
commit 87ef71f9daa1be0d60b2c38c700e9d5e05c5a647 Author: Enzo Martellucci <[email protected]> AuthorDate: Mon Mar 17 18:54:14 2025 +0100 refactor(Layout): add wrapper, tests, and story for Ant Design 5 Layout component --- .../src/SqlLab/components/SaveQuery/index.tsx | 2 +- .../components/ScheduleQueryButton/index.tsx | 2 +- .../AutoComplete/AutoComplete.stories.tsx | 195 +++++++++++++++------ .../src/components/AutoComplete/index.tsx | 2 +- .../components/ErrorMessage/ErrorAlert.stories.tsx | 4 +- superset-frontend/src/components/Grid/index.tsx | 7 +- .../src/components/Layout/Layout.stories.tsx | 153 ++++++++++++++++ .../src/components/Layout/Layout.test.tsx | 94 ++++++++++ superset-frontend/src/components/Layout/index.tsx | 5 + superset-frontend/src/components/index.ts | 11 +- .../dashboard/components/PropertiesModal/index.tsx | 3 +- .../explore/components/PropertiesModal/index.tsx | 3 +- .../FormattingPopoverContent.tsx | 2 +- .../ContourControl/ContourPopoverControl.tsx | 2 +- .../DateFilterControl/components/CustomFrame.tsx | 2 +- .../databases/DatabaseModal/SSHTunnelForm.tsx | 3 +- .../features/databases/UploadDataModel/index.tsx | 10 +- superset-frontend/src/features/home/Menu.tsx | 2 +- superset-frontend/src/features/home/SubMenu.tsx | 2 +- superset-frontend/src/views/App.tsx | 2 +- 20 files changed, 422 insertions(+), 84 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx b/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx index b5793f11d3..3857e89873 100644 --- a/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx +++ b/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx @@ -19,7 +19,7 @@ import { useState, useEffect, useMemo, ChangeEvent } from 'react'; import type { DatabaseObject } from 'src/features/databases/types'; -import { Row, Col } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import { Input } from 'src/components/Input'; import { t, styled } from '@superset-ui/core'; import Button from 'src/components/Button'; diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx index 0a68ac3ce6..39c1f86133 100644 --- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx +++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx @@ -21,7 +21,7 @@ import { FunctionComponent, useState, useRef, ChangeEvent } from 'react'; import SchemaForm, { FormProps } from '@rjsf/core'; import { FormValidation } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; -import { Row, Col } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import { Input } from 'src/components/Input'; import { t, styled } from '@superset-ui/core'; import { parseDate } from 'chrono-node'; diff --git a/superset-frontend/src/components/AutoComplete/AutoComplete.stories.tsx b/superset-frontend/src/components/AutoComplete/AutoComplete.stories.tsx index 053e189b03..79b0b372cc 100644 --- a/superset-frontend/src/components/AutoComplete/AutoComplete.stories.tsx +++ b/superset-frontend/src/components/AutoComplete/AutoComplete.stories.tsx @@ -1,12 +1,131 @@ import { useState } from 'react'; -import { StoryFn } from '@storybook/react'; -import AutoComplete, { AntAutoCompleteProps } from './index'; -import { Input } from '../Input'; +import { Meta, StoryFn } from '@storybook/react'; +import AutoComplete, { + AntAutoCompleteProps, +} from 'src/components/AutoComplete'; export default { title: 'Components/AutoComplete', component: AutoComplete, -}; + argTypes: { + style: { + control: 'object', + description: 'Custom styles for AutoComplete', + }, + placeholder: { + control: 'text', + description: 'Placeholder text for AutoComplete', + }, + disabled: { + control: 'boolean', + description: 'Disable the AutoComplete', + defaultValue: false, + }, + popupMatchSelectWidth: { + control: 'number', + description: 'Width of the dropdown', + defaultValue: 252, + }, + children: { + control: 'text', + description: 'Custom input inside AutoComplete', + }, + allowClear: { + control: 'boolean', + description: 'Show clear button', + defaultValue: false, + }, + autoFocus: { + control: 'boolean', + description: 'If get focus when component mounted', + defaultValue: false, + }, + backfill: { + control: 'boolean', + description: 'If backfill selected item the input when using keyboard', + defaultValue: false, + }, + childrenInput: { + control: 'text', + description: 'Customize input element', + }, + defaultActiveFirstOption: { + control: 'boolean', + description: 'Whether active first option by default', + defaultValue: true, + }, + defaultOpen: { + control: 'boolean', + description: 'Initial open state of dropdown', + }, + defaultValue: { + control: 'text', + description: 'Initial selected option', + }, + dropdownRender: { + control: false, + description: 'Customize dropdown content', + }, + popupClassName: { + control: 'text', + description: 'The className of dropdown menu', + }, + filterOption: { + control: 'boolean', + description: 'If true, filter options by input', + defaultValue: true, + }, + getPopupContainer: { + control: false, + description: 'Parent node of the dropdown.', + defaultValue: () => document.body, + }, + notFoundContent: { + control: 'text', + description: 'Specify content to show when no result matches', + }, + open: { + control: 'boolean', + description: 'Controlled open state of dropdown', + }, + options: { + control: 'object', + description: 'Select options. Will get better perf than JSX definition', + }, + status: { + control: 'select', + options: ['error', 'warning'], + description: 'Set validation status', + }, + size: { + control: 'select', + options: ['large', 'middle', 'small'], + description: 'The size of the input box', + }, + value: { + control: 'text', + description: 'Selected option', + }, + variant: { + control: 'select', + options: ['outlined', 'borderless', 'filled'], + description: 'Variants of input', + defaultValue: 'outlined', + }, + virtual: { + control: 'boolean', + description: 'Disable virtual scroll when set to false', + defaultValue: true, + }, + }, + parameters: { + docs: { + description: { + component: 'AutoComplete component for search functionality.', + }, + }, + }, +} as Meta; const getRandomInt = (max: number, min = 0) => Math.floor(Math.random() * (max - min + 1)) + min; @@ -34,7 +153,7 @@ const searchResult = (query: string) => }; }); -const Template: StoryFn<AntAutoCompleteProps> = args => { +const AutoCompleteWithOptions = (args: AntAutoCompleteProps) => { const [options, setOptions] = useState<AntAutoCompleteProps['options']>([]); const handleSearch = (value: string) => { @@ -44,52 +163,26 @@ const Template: StoryFn<AntAutoCompleteProps> = args => { return <AutoComplete {...args} options={options} onSearch={handleSearch} />; }; -export const Default = Template.bind({}); -Default.args = { - style: { width: 300 }, - placeholder: 'Type to search...', -}; - -export const WithInputSearch = () => { - const [options, setOptions] = useState<AntAutoCompleteProps['options']>([]); +export const AutoCompleteStory: StoryFn<AntAutoCompleteProps> = args => ( + <div style={{ margin: '20px' }}> + <AutoCompleteWithOptions {...args} /> + </div> +); - const handleSearch = (value: string) => { - setOptions(value ? searchResult(value) : []); - }; - - return ( - <AutoComplete - popupMatchSelectWidth={252} - style={{ width: 300 }} - options={options} - onSearch={handleSearch} - > - <Input.Search size="large" placeholder="input here" enterButton /> - </AutoComplete> - ); -}; - -export const Disabled = Template.bind({}); -Disabled.args = { +AutoCompleteStory.args = { style: { width: 300 }, - placeholder: 'Disabled AutoComplete', - disabled: true, -}; - -export const CustomRender = () => { - const [options, setOptions] = useState<AntAutoCompleteProps['options']>([]); - - const handleSearch = (value: string) => { - setOptions(value ? searchResult(value) : []); - }; - - return ( - <AutoComplete - style={{ width: 300 }} - options={options} - onSearch={handleSearch} - > - <Input placeholder="Custom Render" /> - </AutoComplete> - ); + placeholder: 'Type to search...', + disabled: false, + allowClear: false, + autoFocus: false, + backfill: false, + defaultActiveFirstOption: true, + defaultOpen: false, + defaultValue: '', + filterOption: true, + notFoundContent: 'No results found', + open: false, + size: 'middle', + variant: 'outlined', + virtual: true, }; diff --git a/superset-frontend/src/components/AutoComplete/index.tsx b/superset-frontend/src/components/AutoComplete/index.tsx index 708c0acccb..8db93ca105 100644 --- a/superset-frontend/src/components/AutoComplete/index.tsx +++ b/superset-frontend/src/components/AutoComplete/index.tsx @@ -18,7 +18,7 @@ */ import AutoComplete, { AutoCompleteProps as AntAutoCompleteProps, -} from 'antd-v5'; +} from 'antd-v5/lib/auto-complete'; export type { AntAutoCompleteProps }; diff --git a/superset-frontend/src/components/ErrorMessage/ErrorAlert.stories.tsx b/superset-frontend/src/components/ErrorMessage/ErrorAlert.stories.tsx index b7595c00fa..4ae49ac22f 100644 --- a/superset-frontend/src/components/ErrorMessage/ErrorAlert.stories.tsx +++ b/superset-frontend/src/components/ErrorMessage/ErrorAlert.stories.tsx @@ -17,7 +17,9 @@ * under the License. */ import { Meta, StoryFn } from '@storybook/react'; -import { Layout, Row, Col, Card } from 'antd-v5'; +import Layout from 'src/components/Layout'; +import { Row, Col } from 'src/components/Grid'; +import Card from 'src/components/Card'; import ErrorAlert from './ErrorAlert'; const { Content } = Layout; diff --git a/superset-frontend/src/components/Grid/index.tsx b/superset-frontend/src/components/Grid/index.tsx index 21eb5b8f07..acd9f2d316 100644 --- a/superset-frontend/src/components/Grid/index.tsx +++ b/superset-frontend/src/components/Grid/index.tsx @@ -1,8 +1,11 @@ -import Grid, { Row, Col } from 'antd-v5'; +import { Row, Col } from 'antd-v5'; +import useBreakpoint from 'antd-v5/es/grid/hooks/useBreakpoint'; import type { ColProps, ColSize } from 'antd-v5/es/col'; import type { RowProps } from 'antd-v5/es/row'; export type { ColProps, ColSize, RowProps }; -export default Grid; export { Row, Col }; + +const Grid = { useBreakpoint }; +export default Grid; diff --git a/superset-frontend/src/components/Layout/Layout.stories.tsx b/superset-frontend/src/components/Layout/Layout.stories.tsx new file mode 100644 index 0000000000..2a5496d95c --- /dev/null +++ b/superset-frontend/src/components/Layout/Layout.stories.tsx @@ -0,0 +1,153 @@ +import { useState } from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import Layout from 'src/components/Layout'; +import { Menu } from 'src/components/Menu'; +import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; + +const { Header, Footer, Sider, Content } = Layout; + +export default { + title: 'Components/Layout', + component: Layout, + subcomponents: { Header, Footer, Sider, Content }, + argTypes: { + hasSider: { + control: 'boolean', + description: 'Include a sider', + defaultValue: false, + }, + // Layout.Sider props + breakpoint: { + control: 'select', + options: ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'], + description: 'Breakpoints of the responsive layout', + }, + collapsed: { + control: 'boolean', + description: 'Set the current collapsed status', + defaultValue: false, + }, + collapsedWidth: { + control: 'number', + description: 'Width of collapsed sidebar', + defaultValue: 80, + }, + collapsible: { + control: 'boolean', + description: 'Whether the sidebar can be collapsed', + defaultValue: false, + }, + defaultCollapsed: { + control: 'boolean', + description: 'Set the initial collapsed status', + defaultValue: false, + }, + reverseArrow: { + control: 'boolean', + description: 'Reverse the direction of the collapse arrow', + defaultValue: false, + }, + theme: { + control: 'select', + options: ['light', 'dark'], + description: 'Sidebar theme', + defaultValue: 'dark', + }, + width: { + control: 'number', + description: 'Width of the sidebar', + defaultValue: 200, + }, + headerVisible: { + control: 'boolean', + description: 'Show Header', + defaultValue: true, + }, + footerVisible: { + control: 'boolean', + description: 'Show Footer', + defaultValue: true, + }, + }, + parameters: { + docs: { + description: { + component: + 'Ant Design Layout component with configurable Sider, Header, Footer, and Content.', + }, + }, + }, +} as Meta; + +export const LayoutStory: StoryFn = args => { + const [collapsed, setCollapsed] = useState(false); + return ( + <Layout style={{ minHeight: '100vh' }}> + {args.hasSider && ( + <Sider + collapsible={args.collapsible} + collapsed={collapsed} + onCollapse={value => setCollapsed(value)} + theme={args.theme} + width={args.width} + collapsedWidth={args.collapsedWidth} + > + <div + className="logo" + style={{ height: '32px', margin: '16px', background: '#ffffff30' }} + /> + <Menu theme={args.theme} defaultSelectedKeys={['1']} mode="inline"> + <Menu.Item key="1" icon={<MenuUnfoldOutlined />}> + Option 1 + </Menu.Item> + <Menu.Item key="2" icon={<MenuFoldOutlined />}> + Option 2 + </Menu.Item> + </Menu> + </Sider> + )} + <Layout> + {args.headerVisible && ( + <Header + style={{ + background: '#fff', + padding: '0 16px', + textAlign: 'center', + }} + > + Header + </Header> + )} + <Content + style={{ + margin: '16px', + padding: '24px', + background: '#fff', + textAlign: 'center', + }} + > + Content Area + </Content> + {args.footerVisible && ( + <Footer style={{ textAlign: 'center' }}> + Ant Design Layout Footer + </Footer> + )} + </Layout> + </Layout> + ); +}; + +LayoutStory.args = { + hasSider: true, + theme: 'dark', + collapsible: true, + collapsed: false, + defaultCollapsed: false, + collapsedWidth: 80, + width: 200, + reverseArrow: false, + breakpoint: 'md', + headerVisible: true, + footerVisible: true, +}; diff --git a/superset-frontend/src/components/Layout/Layout.test.tsx b/superset-frontend/src/components/Layout/Layout.test.tsx new file mode 100644 index 0000000000..c4c01e03a1 --- /dev/null +++ b/superset-frontend/src/components/Layout/Layout.test.tsx @@ -0,0 +1,94 @@ +import { useState, ReactElement } from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import Layout from 'src/components/Layout'; +import Button from 'src/components/Button'; +import { ThemeProvider, supersetTheme } from '@superset-ui/core'; + +describe('Layout Component', () => { + const renderWithTheme = (ui: ReactElement) => + render(<ThemeProvider theme={supersetTheme}>{ui}</ThemeProvider>); + + test('renders Layout with Header, Content, and Footer', () => { + render( + <Layout hasSider={false}> + <Layout.Header>Header</Layout.Header> + <Layout.Content>Content Area</Layout.Content> + <Layout.Footer>Ant Design Layout Footer</Layout.Footer> + </Layout>, + ); + + expect(screen.getByText('Header')).toBeInTheDocument(); + expect(screen.getByText('Content Area')).toBeInTheDocument(); + expect(screen.getByText('Ant Design Layout Footer')).toBeInTheDocument(); + }); + + test('renders Layout with Sider when hasSider is true', () => { + render( + <Layout hasSider> + <Layout.Sider>Sider Content</Layout.Sider> + </Layout>, + ); + + expect(screen.getByText('Sider Content')).toBeInTheDocument(); + }); + + test('hides Header when headerVisible is false', () => { + render( + <Layout> + {false && <Layout.Header>Header</Layout.Header>} + <Layout.Content>Content Area</Layout.Content> + <Layout.Footer>Ant Design Layout Footer</Layout.Footer> + </Layout>, + ); + + expect(screen.queryByText('Header')).not.toBeInTheDocument(); + }); + + test('hides Footer when footerVisible is false', () => { + render( + <Layout> + <Layout.Header>Header</Layout.Header> + <Layout.Content>Content Area</Layout.Content> + {false && <Layout.Footer>Ant Design Layout Footer</Layout.Footer>} + </Layout>, + ); + + expect( + screen.queryByText('Ant Design Layout Footer'), + ).not.toBeInTheDocument(); + }); + test('collapses Sider when clicked', () => { + const TestLayout = () => { + const [collapsed, setCollapsed] = useState(false); + + return ( + <Layout hasSider> + <Layout.Sider + collapsible + collapsed={collapsed} + collapsedWidth={80} + width={200} + > + <Button onClick={() => setCollapsed(!collapsed)}>Toggle</Button> + Sider Content + </Layout.Sider> + </Layout> + ); + }; + + renderWithTheme(<TestLayout />); + + const toggleButton = screen.getByRole('button', { name: 'Toggle' }); + + expect(screen.getByText('Sider Content').parentElement).toHaveStyle({ + width: '200px', + }); + + fireEvent.click(toggleButton); + + expect(screen.getByText('Sider Content').parentElement).toHaveStyle({ + width: '80px', + }); + }); +}); diff --git a/superset-frontend/src/components/Layout/index.tsx b/superset-frontend/src/components/Layout/index.tsx new file mode 100644 index 0000000000..17f3746716 --- /dev/null +++ b/superset-frontend/src/components/Layout/index.tsx @@ -0,0 +1,5 @@ +import Layout from 'antd-v5/lib/layout'; +import type { LayoutProps, SiderProps } from 'antd-v5/lib/layout'; + +export type { LayoutProps, SiderProps }; +export default Layout; diff --git a/superset-frontend/src/components/index.ts b/superset-frontend/src/components/index.ts index e2f5997a16..42f56cf6b6 100644 --- a/superset-frontend/src/components/index.ts +++ b/superset-frontend/src/components/index.ts @@ -28,16 +28,7 @@ export { default as Button } from './Button'; export { default as Card } from './Card'; // Vanilla Ant Design components from v5 -export { - Col, - Grid, - Layout, - Row, - Skeleton, - Tag, - TreeSelect, - Typography, -} from 'antd-v5'; +export { Skeleton, Tag, TreeSelect, Typography } from 'antd-v5'; // Vanilla Ant Design components from v4 that require migration export { Upload } from 'antd'; diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx index 4831ece8a5..8cbb4a1278 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx @@ -22,7 +22,8 @@ import { Input } from 'src/components/Input'; import { FormItem } from 'src/components/Form'; import jsonStringify from 'json-stringify-pretty-compact'; import Button from 'src/components/Button'; -import { AntdForm, AsyncSelect, Col, Row } from 'src/components'; +import { AntdForm, AsyncSelect } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import rison from 'rison'; import { ensureIsArray, diff --git a/superset-frontend/src/explore/components/PropertiesModal/index.tsx b/superset-frontend/src/explore/components/PropertiesModal/index.tsx index b5c8cd8d64..4eb4537593 100644 --- a/superset-frontend/src/explore/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/explore/components/PropertiesModal/index.tsx @@ -21,7 +21,8 @@ import { ChangeEvent, useMemo, useState, useCallback, useEffect } from 'react'; import Modal from 'src/components/Modal'; import { Input } from 'src/components/Input'; import Button from 'src/components/Button'; -import { AsyncSelect, Row, Col, AntdForm } from 'src/components'; +import { AsyncSelect, AntdForm } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import { SelectValue } from 'antd/lib/select'; import rison from 'rison'; import { diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx index 8e68bc0209..69ef6a661f 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx @@ -25,7 +25,7 @@ import { } from '@superset-ui/chart-controls'; import { Form, FormItem, FormProps } from 'src/components/Form'; import Select from 'src/components/Select/Select'; -import { Col, Row } from 'src/components'; +import { Col, Row } from 'src/components/Grid'; import { InputNumber } from 'src/components/Input'; import Button from 'src/components/Button'; import { ConditionalFormattingConfig } from './types'; diff --git a/superset-frontend/src/explore/components/controls/ContourControl/ContourPopoverControl.tsx b/superset-frontend/src/explore/components/controls/ContourControl/ContourPopoverControl.tsx index fc9c1bfd78..17bd35011a 100644 --- a/superset-frontend/src/explore/components/controls/ContourControl/ContourPopoverControl.tsx +++ b/superset-frontend/src/explore/components/controls/ContourControl/ContourPopoverControl.tsx @@ -17,7 +17,7 @@ * under the License. */ import { useState, useEffect } from 'react'; -import { Row, Col } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import Button from 'src/components/Button'; import Tabs from 'src/components/Tabs'; import { legacyValidateInteger, styled, t } from '@superset-ui/core'; diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx index 969b46855e..1164d246fd 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx @@ -18,7 +18,7 @@ */ import { t, customTimeRangeDecode } from '@superset-ui/core'; import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls'; -import { Col, Row } from 'src/components'; +import { Col, Row } from 'src/components/Grid'; import { InputNumber } from 'src/components/Input'; import { DatePicker } from 'src/components/DatePicker'; import { Radio } from 'src/components/Radio'; diff --git a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx index fd496b4026..96c4b78bca 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx @@ -18,7 +18,8 @@ */ import { useState } from 'react'; import { t, styled } from '@superset-ui/core'; -import { AntdForm, Col, Row } from 'src/components'; +import { AntdForm } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import { Form, FormLabel } from 'src/components/Form'; import { Radio } from 'src/components/Radio'; import { Input } from 'src/components/Input'; diff --git a/superset-frontend/src/features/databases/UploadDataModel/index.tsx b/superset-frontend/src/features/databases/UploadDataModel/index.tsx index eccfe3da37..dc7e7fc599 100644 --- a/superset-frontend/src/features/databases/UploadDataModel/index.tsx +++ b/superset-frontend/src/features/databases/UploadDataModel/index.tsx @@ -35,14 +35,8 @@ import Modal from 'src/components/Modal'; import Button from 'src/components/Button'; import { Switch, SwitchProps } from 'src/components/Switch'; import Collapse from 'src/components/Collapse'; -import { - AntdForm, - AsyncSelect, - Col, - Row, - Select, - Upload, -} from 'src/components'; +import { AntdForm, AsyncSelect, Select, Upload } from 'src/components'; +import { Row, Col } from 'src/components/Grid'; import { UploadOutlined } from '@ant-design/icons'; import { Input, InputNumber } from 'src/components/Input'; import rison from 'rison'; diff --git a/superset-frontend/src/features/home/Menu.tsx b/superset-frontend/src/features/home/Menu.tsx index ebcff4a023..08ca7fe919 100644 --- a/superset-frontend/src/features/home/Menu.tsx +++ b/superset-frontend/src/features/home/Menu.tsx @@ -20,7 +20,7 @@ import { useState, useEffect } from 'react'; import { styled } from '@superset-ui/core'; import { debounce } from 'lodash'; import { getUrlParam } from 'src/utils/urlUtils'; -import { Row, Col, Grid } from 'src/components'; +import Grid, { Row, Col } from 'src/components/Grid'; import { MainNav, MenuMode } from 'src/components/Menu'; import { Tooltip } from 'src/components/Tooltip'; import { NavLink, useLocation } from 'react-router-dom'; diff --git a/superset-frontend/src/features/home/SubMenu.tsx b/superset-frontend/src/features/home/SubMenu.tsx index af1df5a59a..c450271354 100644 --- a/superset-frontend/src/features/home/SubMenu.tsx +++ b/superset-frontend/src/features/home/SubMenu.tsx @@ -23,7 +23,7 @@ import { styled, SupersetTheme, css, t } from '@superset-ui/core'; import cx from 'classnames'; import { Tooltip } from 'src/components/Tooltip'; import { debounce } from 'lodash'; -import { Row } from 'src/components'; +import { Row } from 'src/components/Grid'; import { Menu, MenuMode, MainNav } from 'src/components/Menu'; import Button, { OnClickHandler } from 'src/components/Button'; import Icons from 'src/components/Icons'; diff --git a/superset-frontend/src/views/App.tsx b/superset-frontend/src/views/App.tsx index 970ad95870..486b8548e5 100644 --- a/superset-frontend/src/views/App.tsx +++ b/superset-frontend/src/views/App.tsx @@ -29,7 +29,7 @@ import { css } from '@superset-ui/core'; import { GlobalStyles } from 'src/GlobalStyles'; import ErrorBoundary from 'src/components/ErrorBoundary'; import Loading from 'src/components/Loading'; -import { Layout } from 'src/components'; +import Layout from 'src/components/Layout'; import Menu from 'src/features/home/Menu'; import getBootstrapData from 'src/utils/getBootstrapData'; import ToastContainer from 'src/components/MessageToasts/ToastContainer';
