diff --git a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts index 674974d761..70acb8d95d 100644 --- a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts @@ -34,13 +34,13 @@ describe('Datasource control', () => { cy.visitChartByName('Num Births Trend'); cy.verifySliceSuccess({ waitAlias: '@postJson' }); - cy.get('#datasource_menu').click(); + cy.get('[data-test="datasource-menu-trigger"]').click(); cy.get('script').then(nodes => { numScripts = nodes.length; }); - cy.get('a').contains('Edit Dataset').click(); + cy.get('[data-test="edit-dataset"]').click(); // should load additional scripts for the modal cy.get('script').then(nodes => { @@ -65,8 +65,8 @@ describe('Datasource control', () => { .focus() .type(newMetricName, { force: true }); // delete metric - cy.get('#datasource_menu').click(); - cy.get('a').contains('Edit Dataset').click(); + cy.get('[data-test="datasource-menu-trigger"]').click(); + cy.get('[data-test="edit-dataset"]').click(); cy.get('.modal-content').within(() => { cy.get('a[role="tab"]').contains('Metrics').click(); }); diff --git a/superset-frontend/spec/javascripts/explore/components/DatasourceControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/DatasourceControl_spec.jsx index 592fb975e7..8f6b8e9492 100644 --- a/superset-frontend/spec/javascripts/explore/components/DatasourceControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/DatasourceControl_spec.jsx @@ -20,7 +20,7 @@ import React from 'react'; import sinon from 'sinon'; import configureStore from 'redux-mock-store'; import { shallow } from 'enzyme'; -import { MenuItem } from 'react-bootstrap'; +import { Menu } from 'src/common/components'; import DatasourceModal from 'src/datasource/DatasourceModal'; import ChangeDatasourceModal from 'src/datasource/ChangeDatasourceModal'; import DatasourceControl from 'src/explore/components/controls/DatasourceControl'; @@ -72,17 +72,23 @@ describe('DatasourceControl', () => { it('show or hide Edit Datasource option', () => { let wrapper = setup(); - expect(wrapper.find('#datasource_menu')).toExist(); - expect(wrapper.find('#datasource_menu').dive().find(MenuItem)).toHaveLength( - 3, + expect(wrapper.find('[data-test="datasource-menu"]')).toExist(); + let menuWrapper = shallow( +
+ {wrapper.find('[data-test="datasource-menu"]').prop('overlay')} +
, ); + expect(menuWrapper.find(Menu.Item)).toHaveLength(3); wrapper = setup({ isEditable: false, }); - expect(wrapper.find('#datasource_menu')).toExist(); - expect(wrapper.find('#datasource_menu').dive().find(MenuItem)).toHaveLength( - 2, + expect(wrapper.find('[data-test="datasource-menu"]')).toExist(); + menuWrapper = shallow( +
+ {wrapper.find('[data-test="datasource-menu"]').prop('overlay')} +
, ); + expect(menuWrapper.find(Menu.Item)).toHaveLength(2); }); }); diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl.less b/superset-frontend/src/common/components/Tooltip.tsx similarity index 60% rename from superset-frontend/src/explore/components/controls/DatasourceControl.less rename to superset-frontend/src/common/components/Tooltip.tsx index 571577ab75..7e3c2a2f4d 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl.less +++ b/superset-frontend/src/common/components/Tooltip.tsx @@ -16,33 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -@import '../../../../stylesheets/less/variables.less'; +import React from 'react'; +import { Tooltip as BaseTooltip } from 'src/common/components'; +import { TooltipProps } from 'antd/lib/tooltip'; -#datasource_menu { - border-radius: @border-radius-normal; - padding: 0px; - border: none; -} +const Tooltip = (props: TooltipProps) => ( + +); -#datasource_menu .caret { - position: relative; - padding-right: 8px; - margin-left: 4px; - color: @lightest; - top: -8px; -} - -#datasource_menu .caret { - display: none; -} -#datasource_menu:hover { - background-color: transparent; -} -.DatasourceControl svg { - vertical-align: middle; - color: @brand-primary; - cursor: pointer; -} -.DatasourceControl .angle { - color: @brand-primary; -} +export default Tooltip; diff --git a/superset-frontend/src/common/components/common.stories.tsx b/superset-frontend/src/common/components/common.stories.tsx index d142f2ac18..36dd7c51a0 100644 --- a/superset-frontend/src/common/components/common.stories.tsx +++ b/superset-frontend/src/common/components/common.stories.tsx @@ -19,12 +19,13 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; import { withKnobs, boolean, select } from '@storybook/addon-knobs'; +import Button from 'src/components/Button'; import Modal from './Modal'; import Tabs, { EditableTabs } from './Tabs'; import AntdPopover from './Popover'; +import AntdTooltip from './Tooltip'; import { Menu } from '.'; import { Dropdown } from './Dropdown'; -import Button from '../../components/Button'; export default { title: 'Common Components', @@ -146,3 +147,31 @@ export const Popover = () => ( ); + +export const Tooltip = () => ( + + + +); diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl.jsx index 932f1c0f80..709a927c58 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl.jsx +++ b/superset-frontend/src/explore/components/controls/DatasourceControl.jsx @@ -18,28 +18,18 @@ */ import React from 'react'; import PropTypes from 'prop-types'; -import { - Col, - Collapse, - DropdownButton, - MenuItem, - OverlayTrigger, - Row, - Tooltip, - Well, -} from 'react-bootstrap'; +import { Col, Collapse, Row, Well } from 'react-bootstrap'; import { t, styled } from '@superset-ui/core'; import { ColumnOption, MetricOption } from '@superset-ui/chart-controls'; -import TooltipWrapper from 'src/components/TooltipWrapper'; - +import { Dropdown, Menu } from 'src/common/components'; +import Tooltip from 'src/common/components/Tooltip'; import Icon from 'src/components/Icon'; import ChangeDatasourceModal from 'src/datasource/ChangeDatasourceModal'; import DatasourceModal from 'src/datasource/DatasourceModal'; import Label from 'src/components/Label'; import ControlHeader from '../ControlHeader'; -import './DatasourceControl.less'; const propTypes = { actions: PropTypes.object.isRequired, @@ -58,19 +48,30 @@ const defaultProps = { }; const Styles = styled.div` - #datasource_menu { + .ant-dropdown-trigger { margin-left: ${({ theme }) => theme.gridUnit}px; box-shadow: none; &:active { box-shadow: none; } } + .btn-group .open .dropdown-toggle { box-shadow: none; &.button-default { background: none; } } + + i.angle { + color: ${({ theme }) => theme.colors.primary.base}; + } + + svg.datasource-modal-trigger { + color: ${({ theme }) => theme.colors.primary.base}; + vertical-align: middle; + cursor: pointer; + } `; /** @@ -84,6 +85,10 @@ const ColumnsCol = styled(Col)` } `; +const CHANGE_DATASET = 'change_dataset'; +const EXPLORE_IN_SQL_LAB = 'explore_in_sql_lab'; +const EDIT_DATASET = 'edit_dataset'; + class DatasourceControl extends React.PureComponent { constructor(props) { super(props); @@ -98,6 +103,7 @@ class DatasourceControl extends React.PureComponent { this.toggleEditDatasourceModal = this.toggleEditDatasourceModal.bind(this); this.toggleShowDatasource = this.toggleShowDatasource.bind(this); this.renderDatasource = this.renderDatasource.bind(this); + this.handleMenuItemClick = this.handleMenuItemClick.bind(this); } onDatasourceSave(datasource) { @@ -125,6 +131,15 @@ class DatasourceControl extends React.PureComponent { })); } + handleMenuItemClick({ key }) { + if (key === CHANGE_DATASET) { + this.toggleChangeDatasourceModal(); + } + if (key === EDIT_DATASET) { + this.toggleEditDatasourceModal(); + } + } + renderDatasource() { const { datasource } = this.props; const { showDatasource } = this.state; @@ -176,18 +191,32 @@ class DatasourceControl extends React.PureComponent { showDatasource, } = this.state; const { datasource, onChange, value } = this.props; + + const datasourceMenu = ( + + {t('Change Dataset')} + + + {t('Explore in SQL Lab')} + + + {this.props.isEditable && ( + + {t('Edit Dataset')} + + )} + + ); + return (
- - {t('Expand/collapse dataset configuration')} - - } - > + - - + - } - className="" - bsSize="sm" - id="datasource_menu" - data-test="datasource-menu" - > - - {t('Change Dataset')} - - {datasource.type === 'table' && ( - - {t('Explore in SQL Lab')} - - )} - {this.props.isEditable && ( - - {t('Edit Dataset')} - - )} - - + + + +
{this.renderDatasource()}