mirror of https://github.com/apache/superset.git
Migrates DropdownButton component from Bootstrap to AntD (#13002)
This commit is contained in:
parent
9489f0b8f4
commit
9335b9c983
|
@ -38,7 +38,7 @@ describe('Test explore links', () => {
|
|||
cy.visitChartByName('Growth Rate');
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('button#query').click();
|
||||
cy.get('div#query').click();
|
||||
cy.get('span').contains('View query').parent().click();
|
||||
cy.wait('@chartData').then(() => {
|
||||
cy.get('code');
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import { Menu } from 'src/common/components';
|
||||
import ModalTrigger from 'src/components/ModalTrigger';
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import { DisplayQueryButton } from 'src/explore/components/DisplayQueryButton';
|
||||
|
||||
describe('DisplayQueryButton', () => {
|
||||
|
@ -43,14 +42,16 @@ describe('DisplayQueryButton', () => {
|
|||
true,
|
||||
);
|
||||
});
|
||||
it('renders a dropdown', () => {
|
||||
it('renders a dropdown with 3 itens', () => {
|
||||
const wrapper = mount(<DisplayQueryButton {...defaultProps} />, {
|
||||
wrappingComponent: ThemeProvider,
|
||||
wrappingComponentProps: {
|
||||
theme: supersetTheme,
|
||||
},
|
||||
});
|
||||
expect(wrapper.find(ModalTrigger)).toHaveLength(1);
|
||||
expect(wrapper.find(Menu.Item)).toHaveLength(3);
|
||||
const dropdown = wrapper.find(Dropdown);
|
||||
const menu = shallow(<div>{dropdown.prop('overlay')}</div>);
|
||||
const menuItems = menu.find(Menu.Item);
|
||||
expect(menuItems).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cx from 'classnames';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { DropdownButton } from 'react-bootstrap';
|
||||
import { Menu } from 'src/common/components';
|
||||
import { styled, withTheme } from '@superset-ui/core';
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import Icon from 'src/components/Icon';
|
||||
|
||||
const propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -78,6 +78,7 @@ const MenuItem = styled(Menu.Item)`
|
|||
class PopoverDropdown extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleSelect = this.handleSelect.bind(this);
|
||||
}
|
||||
|
||||
|
@ -86,28 +87,41 @@ class PopoverDropdown extends React.PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { id, value, options, renderButton, renderOption } = this.props;
|
||||
const {
|
||||
id,
|
||||
value,
|
||||
options,
|
||||
renderButton,
|
||||
renderOption,
|
||||
theme,
|
||||
} = this.props;
|
||||
const selected = options.find(opt => opt.value === value);
|
||||
return (
|
||||
<DropdownButton
|
||||
<Dropdown
|
||||
id={id}
|
||||
bsSize="small"
|
||||
title={renderButton(selected)}
|
||||
className="popover-dropdown"
|
||||
trigger="click"
|
||||
overlayStyle={{ zIndex: theme.zIndex.max }}
|
||||
overlay={
|
||||
<Menu onClick={this.handleSelect}>
|
||||
{options.map(option => (
|
||||
<MenuItem
|
||||
id="menu-item"
|
||||
key={option.value}
|
||||
className={cx('dropdown-item', {
|
||||
active: option.value === value,
|
||||
})}
|
||||
>
|
||||
{renderOption(option)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Menu onClick={this.handleSelect}>
|
||||
{options.map(option => (
|
||||
<MenuItem
|
||||
key={option.value}
|
||||
className={cx('dropdown-item', {
|
||||
active: option.value === value,
|
||||
})}
|
||||
>
|
||||
{renderOption(option)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</DropdownButton>
|
||||
<div role="button" css={{ display: 'flex', alignItems: 'center' }}>
|
||||
{renderButton(selected)}
|
||||
<Icon name="caret-down" css={{ marginTop: 4 }} />
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +129,4 @@ class PopoverDropdown extends React.PureComponent {
|
|||
PopoverDropdown.propTypes = propTypes;
|
||||
PopoverDropdown.defaultProps = defaultProps;
|
||||
|
||||
export default PopoverDropdown;
|
||||
export default withTheme(PopoverDropdown);
|
||||
|
|
|
@ -38,7 +38,9 @@ const defaultProps = {
|
|||
menuItems: [],
|
||||
isFocused: false,
|
||||
shouldFocus: (event, container) =>
|
||||
container && container.contains(event.target),
|
||||
container?.contains(event.target) ||
|
||||
event.target.id === 'menu-item' ||
|
||||
event.target.parentNode?.id === 'menu-item',
|
||||
style: null,
|
||||
};
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@
|
|||
.dragdroppable-row .dashboard-component-header {
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
||||
.header-style-option {
|
||||
font-weight: @font-weight-bold;
|
||||
color: @almost-black;
|
||||
}
|
||||
.header-style-option {
|
||||
font-weight: @font-weight-bold;
|
||||
color: @almost-black;
|
||||
}
|
||||
|
||||
.dashboard-header .dashboard-component-header {
|
||||
|
|
|
@ -66,13 +66,6 @@
|
|||
background: @gray-light;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.popover-dropdown.btn {
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
color: @almost-black;
|
||||
}
|
||||
}
|
||||
|
||||
/* the focus menu doesn't account for parent padding */
|
||||
|
@ -88,7 +81,6 @@
|
|||
left: -7px;
|
||||
}
|
||||
|
||||
.popover-menu .popover-dropdown.btn,
|
||||
.hover-dropdown .btn {
|
||||
&:hover,
|
||||
&:active,
|
||||
|
@ -113,12 +105,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.popover-dropdown .caret {
|
||||
/* without this the caret doesn't take up full width / is clipped */
|
||||
width: auto;
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
/* background style menu */
|
||||
.background-style-option {
|
||||
display: inline-block;
|
||||
|
|
|
@ -26,10 +26,9 @@ import markdownSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/mar
|
|||
import sqlSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql';
|
||||
import jsonSyntax from 'react-syntax-highlighter/dist/cjs/languages/hljs/json';
|
||||
import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
|
||||
import { DropdownButton } from 'react-bootstrap';
|
||||
import { styled, t } from '@superset-ui/core';
|
||||
|
||||
import { Menu } from 'src/common/components';
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import { getClientErrorObject } from '../../utils/getClientErrorObject';
|
||||
import CopyToClipboard from '../../components/CopyToClipboard';
|
||||
import { getChartDataRequest } from '../../chart/chartAction';
|
||||
|
@ -75,7 +74,6 @@ export const DisplayQueryButton = props => {
|
|||
const [sqlSupported] = useState(
|
||||
datasource && datasource.split('__')[1] === 'table',
|
||||
);
|
||||
const [menuVisible, setMenuVisible] = useState(false);
|
||||
|
||||
const beforeOpen = resultType => {
|
||||
setIsLoading(true);
|
||||
|
@ -103,7 +101,6 @@ export const DisplayQueryButton = props => {
|
|||
|
||||
const handleMenuClick = ({ key, domEvent }) => {
|
||||
const { chartHeight, slice, onOpenInEditor, latestQueryFormData } = props;
|
||||
setMenuVisible(false);
|
||||
switch (key) {
|
||||
case MENU_KEYS.EDIT_PROPERTIES:
|
||||
props.onOpenPropertiesModal();
|
||||
|
@ -156,48 +153,47 @@ export const DisplayQueryButton = props => {
|
|||
|
||||
const { slice } = props;
|
||||
return (
|
||||
<DropdownButton
|
||||
open={menuVisible}
|
||||
noCaret
|
||||
<Dropdown
|
||||
trigger="click"
|
||||
data-test="query-dropdown"
|
||||
title={
|
||||
<span>
|
||||
<i className="fa fa-bars" />
|
||||
|
||||
</span>
|
||||
overlay={
|
||||
<Menu onClick={handleMenuClick} selectable={false}>
|
||||
{slice && (
|
||||
<Menu.Item key={MENU_KEYS.EDIT_PROPERTIES}>
|
||||
{t('Edit properties')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item>
|
||||
<ModalTrigger
|
||||
triggerNode={
|
||||
<span data-test="view-query-menu-item">{t('View query')}</span>
|
||||
}
|
||||
modalTitle={t('View query')}
|
||||
beforeOpen={() => beforeOpen('query')}
|
||||
modalBody={renderQueryModalBody()}
|
||||
responsive
|
||||
/>
|
||||
</Menu.Item>
|
||||
{sqlSupported && (
|
||||
<Menu.Item key={MENU_KEYS.RUN_IN_SQL_LAB}>
|
||||
{t('Run in SQL Lab')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item key={MENU_KEYS.DOWNLOAD_AS_IMAGE}>
|
||||
{t('Download as image')}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
bsSize="sm"
|
||||
pullRight
|
||||
id="query"
|
||||
onToggle={setMenuVisible}
|
||||
>
|
||||
<Menu onClick={handleMenuClick} selectable={false}>
|
||||
{slice && (
|
||||
<Menu.Item key={MENU_KEYS.EDIT_PROPERTIES}>
|
||||
{t('Edit properties')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item>
|
||||
<ModalTrigger
|
||||
triggerNode={
|
||||
<span data-test="view-query-menu-item">{t('View query')}</span>
|
||||
}
|
||||
modalTitle={t('View query')}
|
||||
beforeOpen={() => beforeOpen('query')}
|
||||
modalBody={renderQueryModalBody()}
|
||||
responsive
|
||||
/>
|
||||
</Menu.Item>
|
||||
{sqlSupported && (
|
||||
<Menu.Item key={MENU_KEYS.RUN_IN_SQL_LAB}>
|
||||
{t('Run in SQL Lab')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item key={MENU_KEYS.DOWNLOAD_AS_IMAGE}>
|
||||
{t('Download as image')}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</DropdownButton>
|
||||
<div
|
||||
role="button"
|
||||
id="query"
|
||||
tabIndex={0}
|
||||
className="btn btn-default btn-sm"
|
||||
>
|
||||
<i className="fa fa-bars" />
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.btn:focus,
|
||||
.btn:active:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
.dropdown-toggle.btn,
|
||||
.btn-group.open .dropdown-toggle.btn {
|
||||
|
|
Loading…
Reference in New Issue