fix: chart empty state & result panel when multiple queries are executed display incorrectly (#20816)

This commit is contained in:
Diego Medina 2022-07-22 03:58:42 -03:00 committed by GitHub
parent 34278c2d56
commit 279ab954b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 44 deletions

View File

@ -26,6 +26,7 @@ import { ParentSize } from '@vx/responsive';
import { createSelector } from 'reselect';
import { withTheme } from '@emotion/react';
import { parseLength, Dimension } from '../../dimension';
import getChartMetadataRegistry from '../registries/ChartMetadataRegistrySingleton';
import SuperChartCore, { Props as SuperChartCoreProps } from './SuperChartCore';
import DefaultFallbackComponent from './FallbackComponent';
import ChartProps, { ChartPropsConfig } from '../models/ChartProps';
@ -140,6 +141,9 @@ class SuperChart extends React.PureComponent<Props, {}> {
this.core = core;
};
private getQueryCount = () =>
getChartMetadataRegistry().get(this.props.chartType)?.queryObjectCount ?? 1;
renderChart(width: number, height: number) {
const {
id,
@ -174,9 +178,11 @@ class SuperChart extends React.PureComponent<Props, {}> {
const noResultQueries =
enableNoResults &&
(!queriesData ||
queriesData.every(
({ data }) => !data || (Array.isArray(data) && data.length === 0),
));
queriesData
.slice(0, this.getQueryCount())
.every(
({ data }) => !data || (Array.isArray(data) && data.length === 0),
));
if (noResultQueries) {
chart = noResults || (
<NoResultsComponent

View File

@ -48,6 +48,7 @@ export interface ChartMetadataConfig {
// label: ChartLabel.DEPRECATED which will display a "deprecated" label on the chart.
label?: ChartLabel | null;
labelExplanation?: string | null;
queryObjectCount?: number;
}
export default class ChartMetadata {
@ -87,6 +88,8 @@ export default class ChartMetadata {
labelExplanation?: string | null;
queryObjectCount: number;
constructor(config: ChartMetadataConfig) {
const {
name,
@ -106,6 +109,7 @@ export default class ChartMetadata {
deprecated = false,
label = null,
labelExplanation = null,
queryObjectCount = 1,
} = config;
this.name = name;
@ -134,6 +138,7 @@ export default class ChartMetadata {
this.deprecated = deprecated;
this.label = label;
this.labelExplanation = labelExplanation;
this.queryObjectCount = queryObjectCount;
}
canBeAnnotationType(type: string): boolean {

View File

@ -84,6 +84,7 @@ export default class EchartsTimeseriesChartPlugin extends ChartPlugin<
t('Time'),
t('Transformable'),
],
queryObjectCount: 2,
}),
// @ts-ignore
transformProps,

View File

@ -17,13 +17,17 @@
* under the License.
*/
import React, { useState, useEffect } from 'react';
import { ensureIsArray, styled, t } from '@superset-ui/core';
import {
ensureIsArray,
styled,
t,
getChartMetadataRegistry,
} from '@superset-ui/core';
import Loading from 'src/components/Loading';
import { EmptyStateMedium } from 'src/components/EmptyState';
import { getChartDataRequest } from 'src/components/Chart/chartAction';
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
import { ResultsPaneProps, QueryResultInterface } from '../types';
import { getQueryCount } from '../utils';
import { SingleQueryResultPane } from './SingleQueryResultPane';
import { TableControls } from './DataTableControls';
@ -43,12 +47,14 @@ export const useResultsPane = ({
isVisible,
dataSize = 50,
}: ResultsPaneProps): React.ReactElement[] => {
const metadata = getChartMetadataRegistry().get(
queryFormData?.viz_type || queryFormData?.vizType,
);
const [resultResp, setResultResp] = useState<QueryResultInterface[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [responseError, setResponseError] = useState<string>('');
const queryCount = getQueryCount(
queryFormData?.viz_type || queryFormData?.vizType,
);
const queryCount = metadata?.queryObjectCount ?? 1;
useEffect(() => {
// it's an invalid formData when gets a errorMessage
@ -122,15 +128,17 @@ export const useResultsPane = ({
);
}
return resultResp.map((result, idx) => (
<SingleQueryResultPane
data={result.data}
colnames={result.colnames}
coltypes={result.coltypes}
dataSize={dataSize}
datasourceId={queryFormData.datasource}
key={idx}
isVisible={isVisible}
/>
));
return resultResp
.slice(0, queryCount)
.map((result, idx) => (
<SingleQueryResultPane
data={result.data}
colnames={result.colnames}
coltypes={result.coltypes}
dataSize={dataSize}
datasourceId={queryFormData.datasource}
key={idx}
isVisible={isVisible}
/>
));
};

View File

@ -24,7 +24,7 @@ import {
waitForElementToBeRemoved,
} from 'spec/helpers/testing-library';
import { exploreActions } from 'src/explore/actions/exploreActions';
import { promiseTimeout } from '@superset-ui/core';
import { ChartMetadata, ChartPlugin, promiseTimeout } from '@superset-ui/core';
import { ResultsPaneOnDashboard } from '../components';
import { createResultsPaneOnDashboardProps } from './fixture';
@ -147,6 +147,19 @@ describe('ResultsPaneOnDashboard', () => {
});
test('multiple results pane', async () => {
const FakeChart = () => <span>test</span>;
const metadata = new ChartMetadata({
name: 'test-chart',
thumbnail: '',
queryObjectCount: 2,
});
const plugin = new ChartPlugin({
metadata,
Chart: FakeChart,
});
plugin.configure({ key: 'mixed_timeseries' }).register();
const props = createResultsPaneOnDashboardProps({
sliceId: 196,
vizType: 'mixed_timeseries',

View File

@ -1,24 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const queryObjectCount = {
mixed_timeseries: 2,
};
export const getQueryCount = (vizType: string): number =>
queryObjectCount?.[vizType] || 1;