refactor: Replace react-bootstrap MenuItems with Antd Menu (#11555)

* Remove MenuItem from SubMenu

* Fix tests

* Refactor PopoverDropdown

* Refactor Button

* Remove redundant Menu import
This commit is contained in:
Kamil Gabryjelski 2020-11-04 23:32:38 +01:00 committed by GitHub
parent ef7087adb6
commit 3e35ddd609
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 78 additions and 38 deletions

View File

@ -19,7 +19,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { shallow } from 'enzyme';
import { Navbar, MenuItem } from 'react-bootstrap';
import { Navbar } from 'react-bootstrap';
import SubMenu from 'src/components/Menu/SubMenu';
const defaultProps = {
@ -66,7 +66,7 @@ describe('SubMenu', () => {
});
it('renders 3 MenuItems (when usesRouter === false)', () => {
expect(wrapper.find(MenuItem)).toHaveLength(3);
expect(wrapper.find('li')).toHaveLength(3);
});
it('renders the menu title', () => {
@ -83,7 +83,7 @@ describe('SubMenu', () => {
expect(routerWrapper.find(Link)).toExist();
expect(routerWrapper.find(Link)).toHaveLength(2);
expect(routerWrapper.find(MenuItem)).toHaveLength(1);
expect(routerWrapper.find('li.no-router')).toHaveLength(1);
});
it('renders buttons in the right nav of the submenu', () => {

View File

@ -18,7 +18,7 @@
*/
import React from 'react';
import { Provider } from 'react-redux';
import { mount } from 'enzyme';
import { styledMount as mount } from 'spec/helpers/theming';
import sinon from 'sinon';
import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton';

View File

@ -18,7 +18,7 @@
*/
import { Provider } from 'react-redux';
import React from 'react';
import { mount } from 'enzyme';
import { styledMount as mount } from 'spec/helpers/theming';
import sinon from 'sinon';
import ReactMarkdown from 'react-markdown';

View File

@ -69,10 +69,10 @@ describe('DashboardTable', () => {
it('render a submenu with clickable tabs and buttons', async () => {
expect(wrapper.find(SubMenu)).toExist();
expect(wrapper.find('MenuItem')).toHaveLength(2);
expect(wrapper.find('li')).toHaveLength(2);
expect(wrapper.find('Button')).toHaveLength(4);
act(() => {
wrapper.find('MenuItem').at(1).simulate('click');
wrapper.find('li').at(1).simulate('click');
});
await waitForComponentToPaint(wrapper);
expect(fetchMock.calls(/dashboard\/\?q/)).toHaveLength(1);

View File

@ -89,10 +89,10 @@ describe('SavedQueries', () => {
it('it renders a submenu with clickable tables and buttons', async () => {
expect(wrapper.find(SubMenu)).toExist();
expect(wrapper.find('MenuItem')).toHaveLength(2);
expect(wrapper.find('li')).toHaveLength(2);
expect(wrapper.find('button')).toHaveLength(2);
act(() => {
wrapper.find('MenuItem').at(1).simulate('click');
wrapper.find('li').at(1).simulate('click');
});
await waitForComponentToPaint(wrapper);

View File

@ -24,9 +24,9 @@ import {
Button as BootstrapButton,
Tooltip,
OverlayTrigger,
MenuItem,
} from 'react-bootstrap';
import { styled } from '@superset-ui/core';
import { Menu } from 'src/common/components';
export type OnClickHandler = React.MouseEventHandler<BootstrapButton>;
@ -285,12 +285,16 @@ export default function Button({
{children}
</SupersetButton>
<ul className="dropdown-menu">
{dropdownItems.map((dropdownItem: DropdownItemProps) => (
<MenuItem key={`${dropdownItem.label}`} href={dropdownItem.url}>
<i className={`fa ${dropdownItem.icon}`} />
&nbsp; {dropdownItem.label}
</MenuItem>
))}
<Menu>
{dropdownItems.map((dropdownItem: DropdownItemProps) => (
<Menu.Item key={`${dropdownItem.label}`}>
<a href={dropdownItem.url}>
<i className={`fa ${dropdownItem.icon}`} />
&nbsp; {dropdownItem.label}
</a>
</Menu.Item>
))}
</Menu>
</ul>
</div>
);

View File

@ -19,7 +19,8 @@
import React, { ReactNode } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { styled } from '@superset-ui/core';
import { Nav, Navbar, MenuItem } from 'react-bootstrap';
import cx from 'classnames';
import { Nav, Navbar } from 'react-bootstrap';
import Button, { OnClickHandler } from 'src/components/Button';
const StyledHeader = styled.header`
@ -139,15 +140,16 @@ const SubMenu: React.FunctionComponent<SubMenuProps> = props => {
}
return (
<MenuItem
className="no-router"
active={tab.name === props.activeChild}
<li
className={cx('no-router', {
active: tab.name === props.activeChild,
})}
key={`${tab.label}`}
href={tab.url}
onClick={tab.onClick}
>
{tab.label}
</MenuItem>
<a href={tab.url} onClick={tab.onClick}>
{tab.label}
</a>
</li>
);
})}
</Nav>

View File

@ -18,7 +18,10 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { DropdownButton, MenuItem } from 'react-bootstrap';
import cx from 'classnames';
import { styled } from '@superset-ui/core';
import { DropdownButton } from 'react-bootstrap';
import { Menu } from 'src/common/components';
const propTypes = {
id: PropTypes.string.isRequired,
@ -42,14 +45,44 @@ const defaultProps = {
),
};
const MenuItem = styled(Menu.Item)`
&.ant-menu-item {
height: auto;
line-height: 1.4;
padding-top: ${({ theme }) => theme.gridUnit}px;
padding-bottom: ${({ theme }) => theme.gridUnit}px;
margin-top: 0;
margin-bottom: 0;
&:not(:last-child) {
margin-bottom: 0;
}
&:hover {
background: ${({ theme }) => theme.colors.grayscale.light3};
}
&.active {
font-weight: ${({ theme }) => theme.typography.weights.bold};
background: ${({ theme }) => theme.colors.grayscale.light2};
}
}
&.ant-menu-item-selected {
color: unset;
}
`;
class PopoverDropdown extends React.PureComponent {
constructor(props) {
super(props);
this.handleSelect = this.handleSelect.bind(this);
}
handleSelect(nextValue) {
this.props.onChange(nextValue);
handleSelect({ key }) {
this.props.onChange(key);
}
render() {
@ -62,17 +95,18 @@ class PopoverDropdown extends React.PureComponent {
title={renderButton(selected)}
className="popover-dropdown"
>
{options.map(option => (
<MenuItem
key={option.value}
eventKey={option.value}
active={option.value === value}
onSelect={this.handleSelect}
className="dropdown-item"
>
{renderOption(option)}
</MenuItem>
))}
<Menu onClick={this.handleSelect}>
{options.map(option => (
<MenuItem
key={option.value}
className={cx('dropdown-item', {
active: option.value === value,
})}
>
{renderOption(option)}
</MenuItem>
))}
</Menu>
</DropdownButton>
);
}