Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Explore popovers issues (#11428) #35

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ describe('AdhocFilters', () => {
});

it('Set simple adhoc filter', () => {
cy.get('#filter-edit-popover').within(() => {
cy.get('[data-test=adhoc-filter-simple-value]').within(() => {
cy.get('.Select__control').click();
cy.get('input[type=text]').focus().type('Any{enter}');
});
cy.get('button').contains('Save').click();
});
cy.get('[data-test=adhoc-filter-simple-value] .Select__control').click();
cy.get('[data-test=adhoc-filter-simple-value] input[type=text]')
.focus()
.type('Jack{enter}', { delay: 20 });

cy.get('[data-test="adhoc-filter-edit-popover-save-button"]').click();

cy.get(
'[data-test=adhoc_filters] .Select__control span.option-label',
).contains('name = Jack');

cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
waitAlias: '@postJson',
Expand All @@ -65,25 +69,35 @@ describe('AdhocFilters', () => {
});

it('Set custom adhoc filter', () => {
cy.visitChartByName('Num Births Trend');
cy.verifySliceSuccess({ waitAlias: '@postJson' });
const filterType = 'name';
const filterContent = "'Amy' OR name = 'Donald'";

cy.get('[data-test=adhoc_filters] .Select__control')
.scrollIntoView()
.click();

// remove previous input
cy.get('[data-test=adhoc_filters] input[type=text]')
.focus()
.type('name{enter}');
cy.get('.adhoc-filter-option').click();
.type('{backspace}');

cy.get('[data-test=adhoc_filters] input[type=text]')
.focus()
.type(`${filterType}{enter}`);

cy.wait('@filterValues');

// selecting a new filter should auto-open the popup,
// so the tabshould be visible by now
cy.get('#filter-edit-popover #adhoc-filter-edit-tabs-tab-SQL').click();
cy.get('#filter-edit-popover .ace_content').click();
cy.get('#filter-edit-popover .ace_text-input').type(
"'Amy' OR name = 'Bob'",
);
cy.get('#filter-edit-popover button').contains('Save').click();
cy.get('#filter-edit-popover .ace_text-input').type(filterContent);
cy.get('[data-test="adhoc-filter-edit-popover-save-button"]').click();

// check if the filter was saved correctly
cy.get(
'[data-test=adhoc_filters] .Select__control span.option-label',
).contains(`${filterType} = ${filterContent}`);

cy.get('button[data-test="run-query-button"]').click();
cy.verifySliceSuccess({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ describe('AdhocMetrics', () => {
.trigger('mousedown')
.click();

cy.get('[data-test="option-label"]').first().click();
cy.get('[data-test="AdhocMetricEditTitle#trigger"]').click();
cy.get('[data-test="AdhocMetricEditTitle#input"]').type(metricName);
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
import { styledShallow as shallow } from 'spec/helpers/theming';
import { shallow } from 'enzyme';
import Popover from 'src/common/components/Popover';

import Label from 'src/components/Label';
Expand All @@ -46,7 +46,7 @@ function setup(overrides) {
datasource: {},
...overrides,
};
const wrapper = shallow(<AdhocFilterOption {...props} />).dive();
const wrapper = shallow(<AdhocFilterOption {...props} />);
return { wrapper };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
import { styledShallow as shallow } from 'spec/helpers/theming';
import { shallow } from 'enzyme';

import Popover from 'src/common/components/Popover';
import Label from 'src/components/Label';
Expand All @@ -46,7 +46,7 @@ function setup(overrides) {
columns,
...overrides,
};
const wrapper = shallow(<AdhocMetricOption {...props} />).dive();
const wrapper = shallow(<AdhocMetricOption {...props} />);
return { wrapper, onMetricEdit };
}

Expand All @@ -73,11 +73,13 @@ describe('AdhocMetricOption', () => {

it('returns to default labels when the custom label is cleared', () => {
const { wrapper } = setup();
expect(wrapper.state('title').label).toBe('SUM(value)');

wrapper.instance().onLabelChange({ target: { value: 'new label' } });
expect(wrapper.state('title').label).toBe('new label');

wrapper.instance().onLabelChange({ target: { value: '' } });
// close and open the popover
wrapper.instance().closeMetricEditOverlay();
wrapper.instance().onOverlayEntered();

expect(wrapper.state('title').label).toBe('SUM(value)');
expect(wrapper.state('title').hasCustomLabel).toBe(false);
});
Expand Down
3 changes: 1 addition & 2 deletions superset-frontend/src/common/components/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
* under the License.
*/
import { Popover as AntdPopover } from 'src/common/components';
import { styled } from '@superset-ui/core';

const SupersetPopover = styled(AntdPopover)``;
const SupersetPopover = AntdPopover;

export default SupersetPopover;
85 changes: 43 additions & 42 deletions superset-frontend/src/explore/components/AdhocFilterOption.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import Popover from 'src/common/components/Popover';
import { t, withTheme } from '@superset-ui/core';
import { t } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';

import Popover from 'src/common/components/Popover';
import Label from 'src/components/Label';
import AdhocFilterEditPopover from './AdhocFilterEditPopover';
import AdhocFilter from '../AdhocFilter';
Expand All @@ -44,57 +44,63 @@ const propTypes = {
class AdhocFilterOption extends React.PureComponent {
constructor(props) {
super(props);
this.closeFilterEditOverlay = this.closeFilterEditOverlay.bind(this);
this.onPopoverResize = this.onPopoverResize.bind(this);
this.onOverlayEntered = this.onOverlayEntered.bind(this);
this.onOverlayExited = this.onOverlayExited.bind(this);
this.handleVisibleChange = this.handleVisibleChange.bind(this);
this.state = { overlayShown: false };
this.closePopover = this.closePopover.bind(this);
this.togglePopover = this.togglePopover.bind(this);
this.state = {
// automatically open the popover the the metric is new
popoverVisible: !!props.adhocFilter.isNew,
};
}

onPopoverResize() {
this.forceUpdate();
}

onOverlayEntered() {
// isNew is used to indicate whether to automatically open the overlay
// once the overlay has been opened, the metric/filter will never be
// considered new again.
this.props.adhocFilter.isNew = false;
this.setState({ overlayShown: true });
componentDidMount() {
const { adhocFilter } = this.props;
// isNew is used to auto-open the popup. Once popup is opened, it's not
// considered new anymore.
// put behind setTimeout so in case consequetive re-renderings are triggered
// for some reason, the popup can still show up.
setTimeout(() => {
adhocFilter.isNew = false;
});
}

onOverlayExited() {
this.setState({ overlayShown: false });
onPopoverResize() {
this.forceUpdate();
}

closeFilterEditOverlay() {
this.setState({ overlayShown: false });
closePopover() {
this.setState({ popoverVisible: false });
}

handleVisibleChange(visible) {
if (visible) {
this.onOverlayEntered();
} else {
this.onOverlayExited();
}
togglePopover(visible) {
this.setState(({ popoverVisible }) => {
return {
popoverVisible: visible === undefined ? !popoverVisible : visible,
};
});
}

render() {
const { adhocFilter } = this.props;
const content = (
const overlayContent = (
<AdhocFilterEditPopover
onResize={this.onPopoverResize}
adhocFilter={adhocFilter}
onChange={this.props.onFilterEdit}
onClose={this.closeFilterEditOverlay}
options={this.props.options}
datasource={this.props.datasource}
partitionColumn={this.props.partitionColumn}
onResize={this.onPopoverResize}
onClose={this.closePopover}
onChange={this.props.onFilterEdit}
/>
);

return (
<div role="button" tabIndex={0} onMouseDown={e => e.stopPropagation()}>
<div
role="button"
tabIndex={0}
onMouseDown={e => e.stopPropagation()}
onKeyDown={e => e.stopPropagation()}
>
{adhocFilter.isExtra && (
<InfoTooltipWithTrigger
icon="exclamation-triangle"
Expand All @@ -109,26 +115,21 @@ class AdhocFilterOption extends React.PureComponent {
<Popover
placement="right"
trigger="click"
disabled
content={content}
content={overlayContent}
defaultVisible={adhocFilter.isNew}
visible={this.state.overlayShown}
onVisibleChange={this.handleVisibleChange}
visible={this.state.popoverVisible}
onVisibleChange={this.togglePopover}
>
<Label className="option-label adhoc-option adhoc-filter-option">
{adhocFilter.getDefaultLabel()}
<i
className={`fa fa-caret-${
this.state.overlayShown ? 'left' : 'right'
} adhoc-label-arrow`}
/>
<i className="fa fa-caret-right adhoc-label-arrow" />
</Label>
</Popover>
</div>
);
}
}

export default withTheme(AdhocFilterOption);
export default AdhocFilterOption;

AdhocFilterOption.propTypes = propTypes;
Loading