mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
chore: Select component refactoring - MetricControl - Iteration 5 (#16423)
* Refactor Select * Render saved metric option * Update tests * Fix Cypress and ariaLabels * Fix lint * Lint Cypress * Reconcile with latest Select changes
This commit is contained in:
parent
8ad03c4f25
commit
913df18075
@ -42,8 +42,12 @@ describe('AdhocMetrics', () => {
|
|||||||
cy.get('[data-test="AdhocMetricEditTitle#trigger"]').click();
|
cy.get('[data-test="AdhocMetricEditTitle#trigger"]').click();
|
||||||
cy.get('[data-test="AdhocMetricEditTitle#input"]').type(metricName);
|
cy.get('[data-test="AdhocMetricEditTitle#input"]').type(metricName);
|
||||||
|
|
||||||
cy.get('[name="select-column"]').click().type('num_girls{enter}');
|
cy.get('input[aria-label="Select column"]')
|
||||||
cy.get('[name="select-aggregate"]').click().type('sum{enter}');
|
.click()
|
||||||
|
.type('num_girls{enter}');
|
||||||
|
cy.get('input[aria-label="Select aggregate options"]')
|
||||||
|
.click()
|
||||||
|
.type('sum{enter}');
|
||||||
|
|
||||||
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
|
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
|
||||||
|
|
||||||
|
@ -45,8 +45,10 @@ describe('Visualization > Line', () => {
|
|||||||
// Title edit for saved metrics is disabled - switch to Simple
|
// Title edit for saved metrics is disabled - switch to Simple
|
||||||
cy.get('[id="adhoc-metric-edit-tabs-tab-SIMPLE"]').click();
|
cy.get('[id="adhoc-metric-edit-tabs-tab-SIMPLE"]').click();
|
||||||
|
|
||||||
cy.get('[name="select-column"]').click().type('num{enter}');
|
cy.get('input[aria-label="Select column"]').click().type('num{enter}');
|
||||||
cy.get('[name="select-aggregate"]').click().type('sum{enter}');
|
cy.get('input[aria-label="Select aggregate options"]')
|
||||||
|
.click()
|
||||||
|
.type('sum{enter}');
|
||||||
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
|
cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
|
||||||
|
|
||||||
cy.get('.text-danger').should('not.exist');
|
cy.get('.text-danger').should('not.exist');
|
||||||
|
@ -73,7 +73,7 @@ describe('AdhocMetricEditPopover', () => {
|
|||||||
|
|
||||||
it('overwrites the adhocMetric in state with onColumnChange', () => {
|
it('overwrites the adhocMetric in state with onColumnChange', () => {
|
||||||
const { wrapper } = setup();
|
const { wrapper } = setup();
|
||||||
wrapper.instance().onColumnChange(columns[0].id);
|
wrapper.instance().onColumnChange(columns[0].column_name);
|
||||||
expect(wrapper.state('adhocMetric')).toEqual(
|
expect(wrapper.state('adhocMetric')).toEqual(
|
||||||
sumValueAdhocMetric.duplicateWith({ column: columns[0] }),
|
sumValueAdhocMetric.duplicateWith({ column: columns[0] }),
|
||||||
);
|
);
|
||||||
@ -100,7 +100,7 @@ describe('AdhocMetricEditPopover', () => {
|
|||||||
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
||||||
wrapper.instance().onColumnChange(null);
|
wrapper.instance().onColumnChange(null);
|
||||||
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
||||||
wrapper.instance().onColumnChange(columns[0].id);
|
wrapper.instance().onColumnChange(columns[0].column_name);
|
||||||
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
expect(wrapper.find(Button).find({ disabled: true })).not.toExist();
|
||||||
wrapper.instance().onAggregateChange(null);
|
wrapper.instance().onAggregateChange(null);
|
||||||
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
expect(wrapper.find(Button).find({ disabled: true })).toExist();
|
||||||
@ -109,7 +109,7 @@ describe('AdhocMetricEditPopover', () => {
|
|||||||
it('highlights save if changes are present', () => {
|
it('highlights save if changes are present', () => {
|
||||||
const { wrapper } = setup();
|
const { wrapper } = setup();
|
||||||
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).not.toExist();
|
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).not.toExist();
|
||||||
wrapper.instance().onColumnChange(columns[1].id);
|
wrapper.instance().onColumnChange(columns[1].column_name);
|
||||||
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).toExist();
|
expect(wrapper.find(Button).find({ buttonStyle: 'primary' })).toExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Tabs from 'src/components/Tabs';
|
import Tabs from 'src/components/Tabs';
|
||||||
import Button from 'src/components/Button';
|
import Button from 'src/components/Button';
|
||||||
import { NativeSelect as Select } from 'src/components/Select';
|
import { Select } from 'src/components';
|
||||||
import { t, styled } from '@superset-ui/core';
|
import { t, styled } from '@superset-ui/core';
|
||||||
|
|
||||||
import { Form, FormItem } from 'src/components/Form';
|
import { Form, FormItem } from 'src/components/Form';
|
||||||
@ -162,8 +162,10 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onColumnChange(columnId) {
|
onColumnChange(columnName) {
|
||||||
const column = this.props.columns.find(column => column.id === columnId);
|
const column = this.props.columns.find(
|
||||||
|
column => column.column_name === columnName,
|
||||||
|
);
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
adhocMetric: prevState.adhocMetric.duplicateWith({
|
adhocMetric: prevState.adhocMetric.duplicateWith({
|
||||||
column,
|
column,
|
||||||
@ -184,9 +186,9 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
onSavedMetricChange(savedMetricId) {
|
onSavedMetricChange(savedMetricName) {
|
||||||
const savedMetric = this.props.savedMetricsOptions.find(
|
const savedMetric = this.props.savedMetricsOptions.find(
|
||||||
metric => metric.id === savedMetricId,
|
metric => metric.metric_name === savedMetricName,
|
||||||
);
|
);
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
savedMetric,
|
savedMetric,
|
||||||
@ -262,6 +264,10 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
|
|||||||
return <StyledColumnOption column={column} showType />;
|
return <StyledColumnOption column={column} showType />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderMetricOption(savedMetric) {
|
||||||
|
return <StyledMetricOption metric={savedMetric} showType />;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
adhocMetric: propsAdhocMetric,
|
adhocMetric: propsAdhocMetric,
|
||||||
@ -290,34 +296,30 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
|
|||||||
|
|
||||||
// autofocus on column if there's no value in column; otherwise autofocus on aggregate
|
// autofocus on column if there's no value in column; otherwise autofocus on aggregate
|
||||||
const columnSelectProps = {
|
const columnSelectProps = {
|
||||||
|
ariaLabel: t('Select column'),
|
||||||
placeholder: t('%s column(s)', columns.length),
|
placeholder: t('%s column(s)', columns.length),
|
||||||
value: columnValue,
|
value: columnValue,
|
||||||
onChange: this.onColumnChange,
|
onChange: this.onColumnChange,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
showSearch: true,
|
|
||||||
autoFocus: !columnValue,
|
autoFocus: !columnValue,
|
||||||
filterOption: (input, option) =>
|
|
||||||
option.filterBy.toLowerCase().indexOf(input.toLowerCase()) >= 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const aggregateSelectProps = {
|
const aggregateSelectProps = {
|
||||||
|
ariaLabel: t('Select aggregate options'),
|
||||||
placeholder: t('%s aggregates(s)', AGGREGATES_OPTIONS.length),
|
placeholder: t('%s aggregates(s)', AGGREGATES_OPTIONS.length),
|
||||||
value: adhocMetric.aggregate || adhocMetric.inferSqlExpressionAggregate(),
|
value: adhocMetric.aggregate || adhocMetric.inferSqlExpressionAggregate(),
|
||||||
onChange: this.onAggregateChange,
|
onChange: this.onAggregateChange,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
autoFocus: !!columnValue,
|
autoFocus: !!columnValue,
|
||||||
showSearch: true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const savedSelectProps = {
|
const savedSelectProps = {
|
||||||
|
ariaLabel: t('Select saved metrics'),
|
||||||
placeholder: t('%s saved metric(s)', savedMetricsOptions?.length ?? 0),
|
placeholder: t('%s saved metric(s)', savedMetricsOptions?.length ?? 0),
|
||||||
value: savedMetric?.verbose_name || savedMetric?.metric_name,
|
value: savedMetric?.metric_name,
|
||||||
onChange: this.onSavedMetricChange,
|
onChange: this.onSavedMetricChange,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
showSearch: true,
|
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
filterOption: (input, option) =>
|
|
||||||
option.filterBy.toLowerCase().indexOf(input.toLowerCase()) >= 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.props.datasourceType === 'druid' && aggregateSelectProps.options) {
|
if (this.props.datasourceType === 'druid' && aggregateSelectProps.options) {
|
||||||
@ -354,55 +356,41 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
|
|||||||
<Tabs.TabPane key={SAVED_TAB_KEY} tab={t('Saved')}>
|
<Tabs.TabPane key={SAVED_TAB_KEY} tab={t('Saved')}>
|
||||||
<FormItem label={t('Saved metric')}>
|
<FormItem label={t('Saved metric')}>
|
||||||
<StyledSelect
|
<StyledSelect
|
||||||
|
options={
|
||||||
|
Array.isArray(savedMetricsOptions)
|
||||||
|
? savedMetricsOptions.map(savedMetric => ({
|
||||||
|
value: savedMetric.metric_name,
|
||||||
|
label: savedMetric.metric_name,
|
||||||
|
customLabel: this.renderMetricOption(savedMetric),
|
||||||
|
key: savedMetric.id,
|
||||||
|
}))
|
||||||
|
: []
|
||||||
|
}
|
||||||
{...savedSelectProps}
|
{...savedSelectProps}
|
||||||
name="select-saved"
|
/>
|
||||||
getPopupContainer={triggerNode => triggerNode.parentNode}
|
|
||||||
>
|
|
||||||
{Array.isArray(savedMetricsOptions) &&
|
|
||||||
savedMetricsOptions.map(savedMetric => (
|
|
||||||
<Select.Option
|
|
||||||
value={savedMetric.id}
|
|
||||||
filterBy={
|
|
||||||
savedMetric.verbose_name || savedMetric.metric_name
|
|
||||||
}
|
|
||||||
key={savedMetric.id}
|
|
||||||
>
|
|
||||||
<StyledMetricOption metric={savedMetric} showType />
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</StyledSelect>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane key={EXPRESSION_TYPES.SIMPLE} tab={t('Simple')}>
|
<Tabs.TabPane key={EXPRESSION_TYPES.SIMPLE} tab={t('Simple')}>
|
||||||
<FormItem label={t('column')}>
|
<FormItem label={t('column')}>
|
||||||
<Select
|
<Select
|
||||||
|
options={columns.map(column => ({
|
||||||
|
value: column.column_name,
|
||||||
|
label: column.verbose_name || column.column_name,
|
||||||
|
key: column.id,
|
||||||
|
customLabel: this.renderColumnOption(column),
|
||||||
|
}))}
|
||||||
{...columnSelectProps}
|
{...columnSelectProps}
|
||||||
name="select-column"
|
/>
|
||||||
getPopupContainer={triggerNode => triggerNode.parentNode}
|
|
||||||
>
|
|
||||||
{columns.map(column => (
|
|
||||||
<Select.Option
|
|
||||||
value={column.id}
|
|
||||||
filterBy={column.verbose_name || column.column_name}
|
|
||||||
key={column.id}
|
|
||||||
>
|
|
||||||
{this.renderColumnOption(column)}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label={t('aggregate')}>
|
<FormItem label={t('aggregate')}>
|
||||||
<Select
|
<Select
|
||||||
|
options={AGGREGATES_OPTIONS.map(option => ({
|
||||||
|
value: option,
|
||||||
|
label: option,
|
||||||
|
key: option,
|
||||||
|
}))}
|
||||||
{...aggregateSelectProps}
|
{...aggregateSelectProps}
|
||||||
name="select-aggregate"
|
/>
|
||||||
getPopupContainer={triggerNode => triggerNode.parentNode}
|
|
||||||
>
|
|
||||||
{AGGREGATES_OPTIONS.map(option => (
|
|
||||||
<Select.Option value={option} key={option}>
|
|
||||||
{option}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
|
Loading…
Reference in New Issue
Block a user