You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2022/02/14 15:15:44 UTC
[superset] branch master updated: feat(explore): Implement chart empty states (#18678)
This is an automated email from the ASF dual-hosted git repository.
kgabryje 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 167e18e feat(explore): Implement chart empty states (#18678)
167e18e is described below
commit 167e18e806799dede3aa56da98be11f4751f0272
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Mon Feb 14 16:14:20 2022 +0100
feat(explore): Implement chart empty states (#18678)
* feat(explore): Implement chart empty states
* Fix test
* Remove unused import
* Fix tests
---
.../cypress/integration/explore/chart.test.js | 4 +++-
.../explore/visualizations/line.test.ts | 8 +++++--
.../src/chart/components/SuperChart.tsx | 8 ++++++-
superset-frontend/src/chart/Chart.jsx | 27 ++++++++++++++++------
superset-frontend/src/chart/ChartRenderer.jsx | 12 +++++++++-
.../components/gridComponents/ChartHolder.test.tsx | 18 ++++++++-------
6 files changed, 57 insertions(+), 20 deletions(-)
diff --git a/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js b/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js
index acb8326..c9f4a1c 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/explore/chart.test.js
@@ -43,6 +43,8 @@ describe('No Results', () => {
cy.visitChartByParams(JSON.stringify(formData));
cy.wait('@getJson').its('response.statusCode').should('eq', 200);
- cy.get('div.chart-container').contains('No Results');
+ cy.get('div.chart-container').contains(
+ 'No results were returned for this query',
+ );
});
});
diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
index 63473a1..5dda1ab 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
@@ -29,13 +29,17 @@ describe('Visualization > Line', () => {
it('should show validator error when no metric', () => {
const formData = { ...LINE_CHART_DEFAULTS, metrics: [] };
cy.visitChartByParams(JSON.stringify(formData));
- cy.get('.ant-alert-warning').contains(`Metrics: cannot be empty`);
+ cy.get('.panel-body').contains(
+ `Add required control values to preview chart`,
+ );
});
it('should not show validator error when metric added', () => {
const formData = { ...LINE_CHART_DEFAULTS, metrics: [] };
cy.visitChartByParams(JSON.stringify(formData));
- cy.get('.ant-alert-warning').contains(`Metrics: cannot be empty`);
+ cy.get('.panel-body').contains(
+ `Add required control values to preview chart`,
+ );
cy.get('.text-danger').contains('Metrics');
cy.get('[data-test=metrics]')
diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx
index ac3f3ed..a8e5592 100644
--- a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx
@@ -77,6 +77,11 @@ export type Props = Omit<SuperChartCoreProps, 'chartProps'> &
* because it will clash with auto-sizing.
*/
Wrapper?: React.ComponentType<WrapperProps>;
+ /**
+ * Component to display when query returns no results.
+ * If not defined, NoResultsComponent is used
+ */
+ noResults?: ReactNode;
};
type PropsWithDefault = Props & Readonly<typeof defaultProps>;
@@ -148,6 +153,7 @@ export default class SuperChart extends React.PureComponent<Props, {}> {
Wrapper,
queriesData,
enableNoResults,
+ noResults,
...rest
} = this.props as PropsWithDefault;
@@ -167,7 +173,7 @@ export default class SuperChart extends React.PureComponent<Props, {}> {
({ data }) => !data || (Array.isArray(data) && data.length === 0),
));
if (noResultQueries) {
- chart = (
+ chart = noResults || (
<NoResultsComponent
id={id}
className={className}
diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx
index be74672..14657cc 100644
--- a/superset-frontend/src/chart/Chart.jsx
+++ b/superset-frontend/src/chart/Chart.jsx
@@ -18,17 +18,17 @@
*/
import PropTypes from 'prop-types';
import React from 'react';
-import Alert from 'src/components/Alert';
import { styled, logging, t } from '@superset-ui/core';
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants';
import Button from 'src/components/Button';
import Loading from 'src/components/Loading';
-import ErrorBoundary from '../components/ErrorBoundary';
+import { EmptyStateBig } from 'src/components/EmptyState';
+import ErrorBoundary from 'src/components/ErrorBoundary';
+import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
import ChartRenderer from './ChartRenderer';
import { ChartErrorMessage } from './ChartErrorMessage';
-import { Logger, LOG_ACTIONS_RENDER_CHART } from '../logger/LogUtils';
const propTypes = {
annotationData: PropTypes.object,
@@ -96,6 +96,10 @@ const Styles = styled.div`
opacity: 0.75;
font-size: ${({ theme }) => theme.typography.sizes.s}px;
}
+
+ .slice_container {
+ height: ${p => p.height}px;
+ }
`;
const RefreshOverlayWrapper = styled.div`
@@ -248,11 +252,20 @@ class Chart extends React.PureComponent {
}
if (errorMessage) {
+ const description = isFeatureEnabled(
+ FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP,
+ )
+ ? t(
+ 'Drag and drop values into highlighted field(s) on the left control panel and run query',
+ )
+ : t(
+ 'Select values in highlighted field(s) on the left control panel and run query',
+ );
return (
- <Alert
- data-test="alert-warning"
- message={errorMessage}
- type="warning"
+ <EmptyStateBig
+ title={t('Add required control values to preview chart')}
+ description={description}
+ image="chart.svg"
/>
);
}
diff --git a/superset-frontend/src/chart/ChartRenderer.jsx b/superset-frontend/src/chart/ChartRenderer.jsx
index 03e0b25..a5a20c6 100644
--- a/superset-frontend/src/chart/ChartRenderer.jsx
+++ b/superset-frontend/src/chart/ChartRenderer.jsx
@@ -19,8 +19,9 @@
import { snakeCase, isEqual } from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
-import { SuperChart, logging, Behavior } from '@superset-ui/core';
+import { SuperChart, logging, Behavior, t } from '@superset-ui/core';
import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
+import { EmptyStateBig } from 'src/components/EmptyState';
const propTypes = {
annotationData: PropTypes.object,
@@ -231,6 +232,15 @@ class ChartRenderer extends React.Component {
queriesData={queriesResponse}
onRenderSuccess={this.handleRenderSuccess}
onRenderFailure={this.handleRenderFailure}
+ noResults={
+ <EmptyStateBig
+ title={t('No results were returned for this query')}
+ description={t(
+ 'Make sure that the controls are configured properly and the datasource contains data for the selected time range',
+ )}
+ image="chart.svg"
+ />
+ }
/>
);
}
diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
index 6268e96..4b2b910 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
@@ -18,7 +18,6 @@
*/
import React from 'react';
-import { waitFor } from '@testing-library/react';
import { sliceId as chartId } from 'spec/fixtures/mockChartQueries';
import { nativeFiltersInfo } from 'src/dashboard/fixtures/mockNativeFilters';
import newComponentFactory from 'src/dashboard/util/newComponentFactory';
@@ -80,14 +79,17 @@ describe('ChartHolder', () => {
</Provider>,
);
- it('should render full size', async () => {
+ it('should render empty state', async () => {
renderWrapper();
- const chart = (
- screen.getByTestId('slice-container').firstChild as HTMLElement
- ).style;
-
- await waitFor(() => expect(chart?.width).toBe('992px'));
- expect(chart?.height).toBe('714px');
+ expect(
+ screen.getByText('No results were returned for this query'),
+ ).toBeVisible();
+ expect(
+ screen.getByText(
+ 'Make sure that the controls are configured properly and the datasource contains data for the selected time range',
+ ),
+ ).toBeVisible();
+ expect(screen.getByAltText('empty')).toBeVisible();
});
});