perf(native-filters): Load native filters after charts (#14443)

* fix:fix get permission function

* refactor: filter default value

* refactor: update default value loading

* refactor: apply defaultValues

* lint: fix lint

* lint: fix lint

* test: fix test

* refactor: use extraFormData for reload charts

* feat: load native filters after after charts

* feat: load filters after charts

* fix: revert changes

* test: fix timers

* test: fix tests
This commit is contained in:
simcha90 2021-05-04 16:07:40 +03:00 committed by GitHub
parent 9a22fb00d9
commit 582900c170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 12 deletions

View File

@ -29,6 +29,16 @@ describe('getFormDataWithExtraFilters', () => {
const filterId = 'native-filter-1';
const mockChart = {
id: chartId,
chartAlert: null,
chartStatus: null,
chartUpdateEndTime: null,
chartUpdateStartTime: 1,
lastRendered: 1,
latestQueryFormData: {},
sliceFormData: null,
queryController: null,
queriesResponse: null,
triggerQuery: false,
formData: {
viz_type: 'filter_select',
filters: [
@ -43,7 +53,7 @@ describe('getFormDataWithExtraFilters', () => {
const mockArgs: GetFormDataWithExtraFiltersArguments = {
chartConfiguration: {},
charts: {
[chartId]: mockChart,
[chartId as number]: mockChart,
},
chart: mockChart,
filters: {

View File

@ -214,6 +214,7 @@ class Chart extends React.PureComponent {
showMessage={false}
>
<Styles
data-ui-anchor="chart"
className="chart-container"
data-test="chart-container"
height={height}

View File

@ -22,7 +22,6 @@ import React, { FC, SyntheticEvent, useEffect, useState } from 'react';
import { Sticky, StickyContainer } from 'react-sticky';
import { TabContainer } from 'react-bootstrap';
import { JsonObject, styled } from '@superset-ui/core';
import ErrorBoundary from 'src/components/ErrorBoundary';
import BuilderComponentPane from 'src/dashboard/components/BuilderComponentPane';
import DashboardHeader from 'src/dashboard/containers/DashboardHeader';
@ -31,7 +30,6 @@ import DragDroppable from 'src/dashboard/components/dnd/DragDroppable';
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
import ToastPresenter from 'src/messageToasts/containers/ToastPresenter';
import WithPopoverMenu from 'src/dashboard/components/menu/WithPopoverMenu';
import getDirectPathToTabIndex from 'src/dashboard/util/getDirectPathToTabIndex';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import { URL_PARAMS } from 'src/constants';

View File

@ -41,6 +41,7 @@ import mockDatasource, {
import FilterBar, { FILTER_BAR_TEST_ID } from '.';
import { FILTERS_CONFIG_MODAL_TEST_ID } from '../FiltersConfigModal/FiltersConfigModal';
jest.useFakeTimers();
// @ts-ignore
mockCore.makeApi = jest.fn();
@ -244,9 +245,11 @@ describe('FilterBar', () => {
expect(screen.getByRole('img', { name: 'filter' })).toBeInTheDocument();
});
it('should render the filter control name', () => {
it('should render the filter control name', async () => {
renderWrapper();
expect(screen.getByText('test')).toBeInTheDocument();
expect(
await screen.findByText('test', {}, { timeout: 2000 }),
).toBeInTheDocument();
});
it('should toggle', () => {

View File

@ -35,6 +35,8 @@ import { useImmer } from 'use-immer';
import { areObjectsEqual } from 'src/reduxUtils';
import { testWithId } from 'src/utils/testUtils';
import { Filter } from 'src/dashboard/components/nativeFilters/types';
import Loading from 'src/components/Loading';
import { getInitialDataMask } from 'src/dataMask/reducer';
import {
getOnlyExtraFormData,
mapParentFiltersToChildren,
@ -46,11 +48,11 @@ import {
useFilters,
useFilterSets,
useFilterUpdates,
useInitialization,
} from './state';
import EditSection from './FilterSets/EditSection';
import Header from './Header';
import FilterControls from './FilterControls/FilterControls';
import { getInitialDataMask } from '../../../../dataMask/reducer';
const BAR_WIDTH = `250px`;
@ -216,6 +218,9 @@ const FilterBar: React.FC<FiltersBarProps> = ({
getOnlyExtraFormData(dataMaskApplied),
{ ignoreUndefined: true },
) || dataSelectedValues.length !== dataAppliedValues.length;
const isInitialized = useInitialization();
return (
<BarWrapper {...getFilterBarTestId()} className={cx({ open: filtersOpen })}>
<CollapsedBar
@ -238,7 +243,9 @@ const FilterBar: React.FC<FiltersBarProps> = ({
dataMaskSelected={dataMaskSelected}
dataMaskApplied={dataMaskApplied}
/>
{isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS_SET) ? (
{!isInitialized ? (
<Loading />
) : isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS_SET) ? (
<StyledTabs
centered
onChange={setTab as HandlerFunction}

View File

@ -27,8 +27,8 @@ import {
DataMaskStateWithId,
DataMaskWithId,
} from 'src/dataMask/types';
import { useEffect } from 'react';
import { RootState } from 'src/dashboard/types';
import { useEffect, useState } from 'react';
import { ChartsState, RootState } from 'src/dashboard/types';
import { NATIVE_FILTER_PREFIX } from '../FiltersConfigModal/utils';
export const useFilterSets = () =>
@ -72,3 +72,48 @@ export const useFilterUpdates = (
});
}, [dataMaskApplied, dataMaskSelected, filters, setDataMaskSelected]);
};
// Load filters after charts loaded
export const useInitialization = () => {
const [isInitialized, setIsInitialized] = useState<boolean>(false);
const charts = useSelector<RootState, ChartsState>(state => state.charts);
// We need to know how much charts now shown on dashboard to know how many of all charts should be loaded
let numberOfLoadingCharts = 0;
if (!isInitialized) {
numberOfLoadingCharts = document.querySelectorAll(
'[data-ui-anchor="chart"]',
).length;
}
useEffect(() => {
if (isInitialized) {
return;
}
// For some dashboards may be there are no charts on first page,
// so we check up to 1 sec if there is at least on chart to load
let filterTimeout: NodeJS.Timeout;
if (numberOfLoadingCharts === 0) {
filterTimeout = setTimeout(() => {
setIsInitialized(true);
}, 1000);
}
// @ts-ignore
if (numberOfLoadingCharts > 0 && filterTimeout !== undefined) {
clearTimeout(filterTimeout);
}
const numberOfLoadedCharts = Object.values(charts).filter(
({ chartStatus }) => chartStatus !== 'loading',
).length;
if (
numberOfLoadingCharts > 0 &&
numberOfLoadedCharts >= numberOfLoadingCharts
) {
setIsInitialized(true);
}
}, [charts, isInitialized, numberOfLoadingCharts]);
return isInitialized;
};

View File

@ -21,6 +21,7 @@ import { chart } from 'src/chart/chartReducer';
import componentTypes from 'src/dashboard/util/componentTypes';
import { DataMaskStateWithId } from '../dataMask/types';
import { NativeFiltersState } from './reducers/types';
import { ChartState } from '../explore/types';
export type ChartReducerInitialState = typeof chart;
@ -34,8 +35,7 @@ export interface ChartQueryPayload extends Partial<ChartReducerInitialState> {
}
/** Chart state of redux */
export type Chart = {
id: number;
export type Chart = ChartState & {
formData: {
viz_type: string;
};
@ -54,11 +54,13 @@ export type DashboardInfo = {
metadata: { show_native_filters: boolean; chart_configuration: JsonObject };
};
export type ChartsState = { [key: string]: Chart };
/** Root state of redux */
export type RootState = {
datasources: JsonObject;
sliceEntities: JsonObject;
charts: { [key: string]: Chart };
charts: ChartsState;
dashboardLayout: DashboardLayoutState;
dashboardFilters: {};
dashboardState: DashboardState;