mirror of
https://github.com/apache/superset.git
synced 2024-09-06 13:57:40 -04:00
feat(explore): collapse time section if no ts columns (#14493)
* feat(explore): collapse time section if no ts columns * fix viz change bug * fix test
This commit is contained in:
parent
05c24056b5
commit
680c96ec54
@ -111,7 +111,7 @@ describe('VizType control', () => {
|
||||
// should load mathjs for line chart
|
||||
cy.get('script[src*="mathjs"]').should('have.length', 1);
|
||||
cy.get('script').then(nodes => {
|
||||
expect(nodes.length).to.eq(numScripts);
|
||||
expect(nodes.length).to.greaterThan(numScripts);
|
||||
});
|
||||
|
||||
cy.get('button[data-test="run-query-button"]').click();
|
||||
|
@ -21,6 +21,7 @@ import React from 'react';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
ensureIsArray,
|
||||
t,
|
||||
styled,
|
||||
getChartControlPanelRegistry,
|
||||
@ -31,8 +32,10 @@ import {
|
||||
ControlPanelSectionConfig,
|
||||
ControlState,
|
||||
CustomControlItem,
|
||||
DatasourceMeta,
|
||||
ExpandedControlItem,
|
||||
InfoTooltipWithTrigger,
|
||||
sections,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
import Collapse from 'src/components/Collapse';
|
||||
@ -102,29 +105,129 @@ const ControlPanelsTabs = styled(Tabs)`
|
||||
}
|
||||
`;
|
||||
|
||||
export class ControlPanelsContainer extends React.Component<ControlPanelsContainerProps> {
|
||||
type ControlPanelsContainerState = {
|
||||
expandedQuerySections: string[];
|
||||
expandedCustomizeSections: string[];
|
||||
querySections: ControlPanelSectionConfig[];
|
||||
customizeSections: ControlPanelSectionConfig[];
|
||||
};
|
||||
|
||||
const isTimeSection = (section: ControlPanelSectionConfig): boolean =>
|
||||
!!section.label &&
|
||||
(sections.legacyRegularTime.label === section.label ||
|
||||
sections.legacyTimeseriesTime.label === section.label);
|
||||
|
||||
const hasTimeColumn = (datasource: DatasourceMeta): boolean =>
|
||||
datasource?.columns?.some(c => c.is_dttm) ||
|
||||
datasource.type === DatasourceType.Druid;
|
||||
|
||||
const sectionsToExpand = (
|
||||
sections: ControlPanelSectionConfig[],
|
||||
datasource: DatasourceMeta,
|
||||
): string[] =>
|
||||
// avoid expanding time section if datasource doesn't include time column
|
||||
sections.reduce(
|
||||
(acc, section) =>
|
||||
section.expanded && (!isTimeSection(section) || hasTimeColumn(datasource))
|
||||
? [...acc, String(section.label)]
|
||||
: acc,
|
||||
[] as string[],
|
||||
);
|
||||
|
||||
function getState(
|
||||
props: ControlPanelsContainerProps,
|
||||
): ControlPanelsContainerState {
|
||||
const {
|
||||
exploreState: { datasource },
|
||||
} = props;
|
||||
|
||||
const querySections: ControlPanelSectionConfig[] = [];
|
||||
const customizeSections: ControlPanelSectionConfig[] = [];
|
||||
|
||||
getSectionsToRender(props.form_data.viz_type, props.datasource_type).forEach(
|
||||
section => {
|
||||
// if at least one control in the section is not `renderTrigger`
|
||||
// or asks to be displayed at the Data tab
|
||||
if (
|
||||
section.tabOverride === 'data' ||
|
||||
section.controlSetRows.some(rows =>
|
||||
rows.some(
|
||||
control =>
|
||||
control &&
|
||||
typeof control === 'object' &&
|
||||
'config' in control &&
|
||||
control.config &&
|
||||
(!control.config.renderTrigger ||
|
||||
control.config.tabOverride === 'data'),
|
||||
),
|
||||
)
|
||||
) {
|
||||
querySections.push(section);
|
||||
} else {
|
||||
customizeSections.push(section);
|
||||
}
|
||||
},
|
||||
);
|
||||
const expandedQuerySections: string[] = sectionsToExpand(
|
||||
querySections,
|
||||
datasource,
|
||||
);
|
||||
const expandedCustomizeSections: string[] = sectionsToExpand(
|
||||
customizeSections,
|
||||
datasource,
|
||||
);
|
||||
return {
|
||||
expandedQuerySections,
|
||||
expandedCustomizeSections,
|
||||
querySections,
|
||||
customizeSections,
|
||||
};
|
||||
}
|
||||
|
||||
export class ControlPanelsContainer extends React.Component<
|
||||
ControlPanelsContainerProps,
|
||||
ControlPanelsContainerState
|
||||
> {
|
||||
// trigger updates to the component when async plugins load
|
||||
static contextType = PluginContext;
|
||||
|
||||
constructor(props: ControlPanelsContainerProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
expandedQuerySections: [],
|
||||
expandedCustomizeSections: [],
|
||||
querySections: [],
|
||||
customizeSections: [],
|
||||
};
|
||||
this.renderControl = this.renderControl.bind(this);
|
||||
this.renderControlPanelSection = this.renderControlPanelSection.bind(this);
|
||||
}
|
||||
|
||||
sectionsToRender(): ExpandedControlPanelSectionConfig[] {
|
||||
return getSectionsToRender(
|
||||
this.props.form_data.viz_type,
|
||||
this.props.datasource_type,
|
||||
);
|
||||
static getDerivedStateFromProps(
|
||||
props: ControlPanelsContainerProps,
|
||||
state: ControlPanelsContainerState,
|
||||
): ControlPanelsContainerState {
|
||||
// only update the sections, not the expanded/collapsed state
|
||||
const newState = getState(props);
|
||||
return {
|
||||
...state,
|
||||
customizeSections: newState.customizeSections,
|
||||
querySections: newState.querySections,
|
||||
};
|
||||
}
|
||||
|
||||
sectionsToExpand(sections: ControlPanelSectionConfig[]) {
|
||||
return sections.reduce(
|
||||
(acc, section) =>
|
||||
section.expanded ? [...acc, String(section.label)] : acc,
|
||||
[] as string[],
|
||||
);
|
||||
componentDidUpdate(prevProps: ControlPanelsContainerProps) {
|
||||
if (
|
||||
this.props.form_data.datasource !== prevProps.form_data.datasource ||
|
||||
this.props.form_data.viz_type !== prevProps.form_data.viz_type
|
||||
) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState(getState(this.props));
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState(getState(this.props));
|
||||
}
|
||||
|
||||
renderControl({ name, config }: CustomControlItem) {
|
||||
@ -260,36 +363,7 @@ export class ControlPanelsContainer extends React.Component<ControlPanelsContain
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
const querySectionsToRender: ExpandedControlPanelSectionConfig[] = [];
|
||||
const displaySectionsToRender: ExpandedControlPanelSectionConfig[] = [];
|
||||
this.sectionsToRender().forEach(section => {
|
||||
// if at least one control in the section is not `renderTrigger`
|
||||
// or asks to be displayed at the Data tab
|
||||
if (
|
||||
section.tabOverride === 'data' ||
|
||||
section.controlSetRows.some(rows =>
|
||||
rows.some(
|
||||
control =>
|
||||
control &&
|
||||
typeof control === 'object' &&
|
||||
'config' in control &&
|
||||
control.config &&
|
||||
(!control.config.renderTrigger ||
|
||||
control.config.tabOverride === 'data'),
|
||||
),
|
||||
)
|
||||
) {
|
||||
querySectionsToRender.push(section);
|
||||
} else {
|
||||
displaySectionsToRender.push(section);
|
||||
}
|
||||
});
|
||||
|
||||
const showCustomizeTab = displaySectionsToRender.length > 0;
|
||||
const expandedQuerySections = this.sectionsToExpand(querySectionsToRender);
|
||||
const expandedCustomSections = this.sectionsToExpand(
|
||||
displaySectionsToRender,
|
||||
);
|
||||
const showCustomizeTab = this.state.customizeSections.length > 0;
|
||||
return (
|
||||
<Styles>
|
||||
<ControlPanelsTabs
|
||||
@ -300,22 +374,34 @@ export class ControlPanelsContainer extends React.Component<ControlPanelsContain
|
||||
<Tabs.TabPane key="query" tab={t('Data')}>
|
||||
<Collapse
|
||||
bordered
|
||||
defaultActiveKey={expandedQuerySections}
|
||||
activeKey={this.state.expandedQuerySections}
|
||||
expandIconPosition="right"
|
||||
onChange={selection => {
|
||||
this.setState({
|
||||
expandedQuerySections: ensureIsArray(selection),
|
||||
});
|
||||
}}
|
||||
ghost
|
||||
>
|
||||
{querySectionsToRender.map(this.renderControlPanelSection)}
|
||||
{this.state.querySections.map(this.renderControlPanelSection)}
|
||||
</Collapse>
|
||||
</Tabs.TabPane>
|
||||
{showCustomizeTab && (
|
||||
<Tabs.TabPane key="display" tab={t('Customize')}>
|
||||
<Collapse
|
||||
bordered
|
||||
defaultActiveKey={expandedCustomSections}
|
||||
activeKey={this.state.expandedCustomizeSections}
|
||||
expandIconPosition="right"
|
||||
onChange={selection => {
|
||||
this.setState({
|
||||
expandedCustomizeSections: ensureIsArray(selection),
|
||||
});
|
||||
}}
|
||||
ghost
|
||||
>
|
||||
{displaySectionsToRender.map(this.renderControlPanelSection)}
|
||||
{this.state.customizeSections.map(
|
||||
this.renderControlPanelSection,
|
||||
)}
|
||||
</Collapse>
|
||||
</Tabs.TabPane>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user