fix(dashboard): Chart stuck in loading state when when datasets request and chart request fail (#19327)

This commit is contained in:
Kamil Gabryjelski 2022-03-23 15:43:32 +01:00 committed by GitHub
parent 468c5ca29a
commit a08f83bc60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 4 deletions

View File

@ -29,6 +29,7 @@ import ErrorBoundary from 'src/components/ErrorBoundary';
import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
import { URL_PARAMS } from 'src/constants';
import { getUrlParam } from 'src/utils/urlUtils';
import { ResourceStatus } from 'src/hooks/apiResources/apiResources';
import ChartRenderer from './ChartRenderer';
import { ChartErrorMessage } from './ChartErrorMessage';
@ -72,6 +73,7 @@ const propTypes = {
onFilterMenuClose: PropTypes.func,
ownState: PropTypes.object,
postTransformProps: PropTypes.func,
datasetsStatus: PropTypes.oneOf(['loading', 'error', 'complete']),
};
const BLANK = {};
@ -207,6 +209,7 @@ class Chart extends React.PureComponent {
datasource,
dashboardId,
height,
datasetsStatus,
} = this.props;
const error = queryResponse?.errors?.[0];
@ -216,7 +219,8 @@ class Chart extends React.PureComponent {
if (
chartAlert !== undefined &&
chartAlert !== NONEXISTENT_DATASET &&
datasource === PLACEHOLDER_DATASOURCE
datasource === PLACEHOLDER_DATASOURCE &&
datasetsStatus !== ResourceStatus.ERROR
) {
return (
<Styles

View File

@ -612,3 +612,11 @@ export function maxUndoHistoryToast() {
);
};
}
export const SET_DATASETS_STATUS = 'SET_DATASETS_STATUS';
export function setDatasetsStatus(status) {
return {
type: SET_DATASETS_STATUS,
status,
};
}

View File

@ -51,6 +51,7 @@ import { TIME_RANGE } from 'src/visualizations/FilterBox/FilterBox';
import { URL_PARAMS } from 'src/constants';
import { getUrlParam } from 'src/utils/urlUtils';
import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants';
import { ResourceStatus } from 'src/hooks/apiResources/apiResources';
import { FeatureFlag, isFeatureEnabled } from '../../featureFlags';
import extractUrlParams from '../util/extractUrlParams';
import getNativeFilterConfig from '../util/filterboxMigrationHelper';
@ -400,6 +401,7 @@ export const hydrateDashboard =
isFiltersRefreshing: false,
activeTabs: dashboardState?.activeTabs || [],
filterboxMigrationState,
datasetsStatus: ResourceStatus.LOADING,
},
dashboardLayout,
},

View File

@ -83,6 +83,7 @@ const propTypes = {
ownState: PropTypes.object,
filterState: PropTypes.object,
postTransformProps: PropTypes.func,
datasetsStatus: PropTypes.oneOf(['loading', 'error', 'complete']),
};
const defaultProps = {
@ -338,6 +339,7 @@ export default class Chart extends React.Component {
isFullSize,
filterboxMigrationState,
postTransformProps,
datasetsStatus,
} = this.props;
const { width } = this.state;
@ -463,6 +465,7 @@ export default class Chart extends React.Component {
isDeactivatedViz={isDeactivatedViz}
filterboxMigrationState={filterboxMigrationState}
postTransformProps={postTransformProps}
datasetsStatus={datasetsStatus}
/>
</div>
</div>

View File

@ -60,7 +60,7 @@ function mapStateToProps(
const datasource =
(chart && chart.form_data && datasources[chart.form_data.datasource]) ||
PLACEHOLDER_DATASOURCE;
const { colorScheme, colorNamespace } = dashboardState;
const { colorScheme, colorNamespace, datasetsStatus } = dashboardState;
const labelColors = dashboardInfo?.metadata?.label_colors || {};
const sharedLabelColors = dashboardInfo?.metadata?.shared_label_colors || {};
// note: this method caches filters if possible to prevent render cascades
@ -101,6 +101,7 @@ function mapStateToProps(
filterState: dataMask[id]?.filterState,
maxRows: common.conf.SQL_MAX_ROW,
filterboxMigrationState: dashboardState.filterboxMigrationState,
datasetsStatus,
};
}

View File

@ -56,6 +56,7 @@ import { URL_PARAMS } from 'src/constants';
import { getUrlParam } from 'src/utils/urlUtils';
import { canUserEditDashboard } from 'src/dashboard/util/findPermission';
import { getFilterSets } from '../actions/nativeFilters';
import { setDatasetsStatus } from '../actions/dashboardState';
import {
getFilterValue,
getPermalinkValue,
@ -90,8 +91,11 @@ const DashboardPage: FC = () => {
useDashboard(idOrSlug);
const { result: charts, error: chartsApiError } =
useDashboardCharts(idOrSlug);
const { result: datasets, error: datasetsApiError } =
useDashboardDatasets(idOrSlug);
const {
result: datasets,
error: datasetsApiError,
status,
} = useDashboardDatasets(idOrSlug);
const isDashboardHydrated = useRef(false);
const error = dashboardApiError || chartsApiError;
@ -107,6 +111,10 @@ const DashboardPage: FC = () => {
migrationStateParam || FILTER_BOX_MIGRATION_STATES.NOOP,
);
useEffect(() => {
dispatch(setDatasetsStatus(status));
}, [dispatch, status]);
useEffect(() => {
// should convert filter_box to filter component?
const hasFilterBox =

View File

@ -42,6 +42,7 @@ import {
RESET_SLICE,
ON_FILTERS_REFRESH,
ON_FILTERS_REFRESH_SUCCESS,
SET_DATASETS_STATUS,
} from '../actions/dashboardState';
import { HYDRATE_DASHBOARD } from '../actions/hydrate';
@ -212,6 +213,12 @@ export default function dashboardStateReducer(state = {}, action) {
fullSizeChartId: action.chartId,
};
},
[SET_DATASETS_STATUS]() {
return {
...state,
datasetsStatus: action.status,
};
},
};
if (action.type in actionHandlers) {