mirror of https://github.com/apache/superset.git
perf(dashboard): Send chart requests before native filter requests (#19077)
This commit is contained in:
parent
c79ee56884
commit
b8091e33a9
|
@ -422,6 +422,16 @@ const refreshCharts = (chartList, force, interval, dashboardId, dispatch) =>
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ON_FILTERS_REFRESH = 'ON_FILTERS_REFRESH';
|
||||||
|
export function onFiltersRefresh() {
|
||||||
|
return { type: ON_FILTERS_REFRESH };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ON_FILTERS_REFRESH_SUCCESS = 'ON_FILTERS_REFRESH_SUCCESS';
|
||||||
|
export function onFiltersRefreshSuccess() {
|
||||||
|
return { type: ON_FILTERS_REFRESH_SUCCESS };
|
||||||
|
}
|
||||||
|
|
||||||
export const ON_REFRESH_SUCCESS = 'ON_REFRESH_SUCCESS';
|
export const ON_REFRESH_SUCCESS = 'ON_REFRESH_SUCCESS';
|
||||||
export function onRefreshSuccess() {
|
export function onRefreshSuccess() {
|
||||||
return { type: ON_REFRESH_SUCCESS };
|
return { type: ON_REFRESH_SUCCESS };
|
||||||
|
@ -436,8 +446,11 @@ export function onRefresh(
|
||||||
) {
|
) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch({ type: ON_REFRESH });
|
dispatch({ type: ON_REFRESH });
|
||||||
refreshCharts(chartList, force, interval, dashboardId, dispatch).then(() =>
|
refreshCharts(chartList, force, interval, dashboardId, dispatch).then(
|
||||||
dispatch({ type: ON_REFRESH_SUCCESS }),
|
() => {
|
||||||
|
dispatch(onRefreshSuccess());
|
||||||
|
dispatch(onFiltersRefresh());
|
||||||
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,7 @@ export const hydrateDashboard =
|
||||||
maxUndoHistoryExceeded: false,
|
maxUndoHistoryExceeded: false,
|
||||||
lastModifiedTime: dashboardData.changed_on,
|
lastModifiedTime: dashboardData.changed_on,
|
||||||
isRefreshing: false,
|
isRefreshing: false,
|
||||||
|
isFiltersRefreshing: false,
|
||||||
activeTabs: dashboardState?.activeTabs || [],
|
activeTabs: dashboardState?.activeTabs || [],
|
||||||
filterboxMigrationState,
|
filterboxMigrationState,
|
||||||
},
|
},
|
||||||
|
|
|
@ -43,6 +43,7 @@ import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||||
import { waitForAsyncData } from 'src/middleware/asyncEvent';
|
import { waitForAsyncData } from 'src/middleware/asyncEvent';
|
||||||
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
|
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||||
import { RootState } from 'src/dashboard/types';
|
import { RootState } from 'src/dashboard/types';
|
||||||
|
import { onFiltersRefreshSuccess } from 'src/dashboard/actions/dashboardState';
|
||||||
import { dispatchFocusAction } from './utils';
|
import { dispatchFocusAction } from './utils';
|
||||||
import { FilterProps } from './types';
|
import { FilterProps } from './types';
|
||||||
import { getFormData } from '../../utils';
|
import { getFormData } from '../../utils';
|
||||||
|
@ -62,6 +63,18 @@ const StyledDiv = styled.div`
|
||||||
const queriesDataPlaceholder = [{ data: [{}] }];
|
const queriesDataPlaceholder = [{ data: [{}] }];
|
||||||
const behaviors = [Behavior.NATIVE_FILTER];
|
const behaviors = [Behavior.NATIVE_FILTER];
|
||||||
|
|
||||||
|
const useShouldFilterRefresh = () => {
|
||||||
|
const isDashboardRefreshing = useSelector<RootState, boolean>(
|
||||||
|
state => state.dashboardState.isRefreshing,
|
||||||
|
);
|
||||||
|
const isFilterRefreshing = useSelector<RootState, boolean>(
|
||||||
|
state => state.dashboardState.isFiltersRefreshing,
|
||||||
|
);
|
||||||
|
|
||||||
|
// trigger filter requests only after charts requests were triggered
|
||||||
|
return !isDashboardRefreshing && isFilterRefreshing;
|
||||||
|
};
|
||||||
|
|
||||||
const FilterValue: React.FC<FilterProps> = ({
|
const FilterValue: React.FC<FilterProps> = ({
|
||||||
dataMaskSelected,
|
dataMaskSelected,
|
||||||
filter,
|
filter,
|
||||||
|
@ -75,9 +88,7 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
const { id, targets, filterType, adhoc_filters, time_range } = filter;
|
const { id, targets, filterType, adhoc_filters, time_range } = filter;
|
||||||
const metadata = getChartMetadataRegistry().get(filterType);
|
const metadata = getChartMetadataRegistry().get(filterType);
|
||||||
const dependencies = useFilterDependencies(id, dataMaskSelected);
|
const dependencies = useFilterDependencies(id, dataMaskSelected);
|
||||||
const isDashboardRefreshing = useSelector<RootState, boolean>(
|
const shouldRefresh = useShouldFilterRefresh();
|
||||||
state => state.dashboardState.isRefreshing,
|
|
||||||
);
|
|
||||||
const [state, setState] = useState<ChartDataResponseResult[]>([]);
|
const [state, setState] = useState<ChartDataResponseResult[]>([]);
|
||||||
const [error, setError] = useState<string>('');
|
const [error, setError] = useState<string>('');
|
||||||
const [formData, setFormData] = useState<Partial<QueryFormData>>({
|
const [formData, setFormData] = useState<Partial<QueryFormData>>({
|
||||||
|
@ -97,6 +108,14 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const handleFilterLoadFinish = useCallback(() => {
|
||||||
|
setIsRefreshing(false);
|
||||||
|
setIsLoading(false);
|
||||||
|
if (shouldRefresh) {
|
||||||
|
dispatch(onFiltersRefreshSuccess());
|
||||||
|
}
|
||||||
|
}, [dispatch, shouldRefresh]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!inViewFirstTime && inView) {
|
if (!inViewFirstTime && inView) {
|
||||||
setInViewFirstTime(true);
|
setInViewFirstTime(true);
|
||||||
|
@ -127,7 +146,7 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
!isRefreshing &&
|
!isRefreshing &&
|
||||||
(!isEqualWith(formData, newFormData, customizer) ||
|
(!isEqualWith(formData, newFormData, customizer) ||
|
||||||
!isEqual(ownState, filterOwnState) ||
|
!isEqual(ownState, filterOwnState) ||
|
||||||
isDashboardRefreshing)
|
shouldRefresh)
|
||||||
) {
|
) {
|
||||||
setFormData(newFormData);
|
setFormData(newFormData);
|
||||||
setOwnState(filterOwnState);
|
setOwnState(filterOwnState);
|
||||||
|
@ -147,22 +166,19 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
const result = 'result' in json ? json.result[0] : json;
|
const result = 'result' in json ? json.result[0] : json;
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setIsRefreshing(false);
|
|
||||||
setIsLoading(false);
|
|
||||||
setState([result]);
|
setState([result]);
|
||||||
|
handleFilterLoadFinish();
|
||||||
} else if (response.status === 202) {
|
} else if (response.status === 202) {
|
||||||
waitForAsyncData(result)
|
waitForAsyncData(result)
|
||||||
.then((asyncResult: ChartDataResponseResult[]) => {
|
.then((asyncResult: ChartDataResponseResult[]) => {
|
||||||
setIsRefreshing(false);
|
|
||||||
setIsLoading(false);
|
|
||||||
setState(asyncResult);
|
setState(asyncResult);
|
||||||
|
handleFilterLoadFinish();
|
||||||
})
|
})
|
||||||
.catch((error: ClientErrorObject) => {
|
.catch((error: ClientErrorObject) => {
|
||||||
setError(
|
setError(
|
||||||
error.message || error.error || t('Check configuration'),
|
error.message || error.error || t('Check configuration'),
|
||||||
);
|
);
|
||||||
setIsRefreshing(false);
|
handleFilterLoadFinish();
|
||||||
setIsLoading(false);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -172,14 +188,12 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
} else {
|
} else {
|
||||||
setState(json.result);
|
setState(json.result);
|
||||||
setError('');
|
setError('');
|
||||||
setIsRefreshing(false);
|
handleFilterLoadFinish();
|
||||||
setIsLoading(false);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error: Response) => {
|
.catch((error: Response) => {
|
||||||
setError(error.statusText);
|
setError(error.statusText);
|
||||||
setIsRefreshing(false);
|
handleFilterLoadFinish();
|
||||||
setIsLoading(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
@ -187,10 +201,11 @@ const FilterValue: React.FC<FilterProps> = ({
|
||||||
dependencies,
|
dependencies,
|
||||||
datasetId,
|
datasetId,
|
||||||
groupby,
|
groupby,
|
||||||
|
handleFilterLoadFinish,
|
||||||
JSON.stringify(filter),
|
JSON.stringify(filter),
|
||||||
hasDataSource,
|
hasDataSource,
|
||||||
isRefreshing,
|
isRefreshing,
|
||||||
isDashboardRefreshing,
|
shouldRefresh,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -39,6 +39,8 @@ import {
|
||||||
UNSET_FOCUSED_FILTER_FIELD,
|
UNSET_FOCUSED_FILTER_FIELD,
|
||||||
SET_ACTIVE_TABS,
|
SET_ACTIVE_TABS,
|
||||||
SET_FULL_SIZE_CHART_ID,
|
SET_FULL_SIZE_CHART_ID,
|
||||||
|
ON_FILTERS_REFRESH,
|
||||||
|
ON_FILTERS_REFRESH_SUCCESS,
|
||||||
} from '../actions/dashboardState';
|
} from '../actions/dashboardState';
|
||||||
import { HYDRATE_DASHBOARD } from '../actions/hydrate';
|
import { HYDRATE_DASHBOARD } from '../actions/hydrate';
|
||||||
|
|
||||||
|
@ -136,6 +138,18 @@ export default function dashboardStateReducer(state = {}, action) {
|
||||||
isRefreshing: true,
|
isRefreshing: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
[ON_FILTERS_REFRESH]() {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFiltersRefreshing: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[ON_FILTERS_REFRESH_SUCCESS]() {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isFiltersRefreshing: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
[ON_REFRESH_SUCCESS]() {
|
[ON_REFRESH_SUCCESS]() {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -63,6 +63,7 @@ export type DashboardState = {
|
||||||
activeTabs: ActiveTabs;
|
activeTabs: ActiveTabs;
|
||||||
fullSizeChartId: number | null;
|
fullSizeChartId: number | null;
|
||||||
isRefreshing: boolean;
|
isRefreshing: boolean;
|
||||||
|
isFiltersRefreshing: boolean;
|
||||||
hasUnsavedChanges: boolean;
|
hasUnsavedChanges: boolean;
|
||||||
};
|
};
|
||||||
export type DashboardInfo = {
|
export type DashboardInfo = {
|
||||||
|
|
Loading…
Reference in New Issue