You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/05/07 08:57:12 UTC
[superset] branch master updated: feat(explore): collapse time
section if no ts columns (#14493)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 680c96e feat(explore): collapse time section if no ts columns (#14493)
680c96e is described below
commit 680c96ec541b8db7316042c919d269aa979f6ac3
Author: Ville Brofeldt <33...@users.noreply.github.com>
AuthorDate: Fri May 7 11:55:54 2021 +0300
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
---
.../cypress/integration/explore/control.test.ts | 2 +-
.../explore/components/ControlPanelsContainer.tsx | 178 +++++++++++++++------
2 files changed, 133 insertions(+), 47 deletions(-)
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 c65b5df..e6d8b56 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts
@@ -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();
diff --git a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
index 9181a56..a0d1f44 100644
--- a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
+++ b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
@@ -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>
)}