Commit 08925ffa by Torkel Ödegaard

Basic loading state for slow dashboards

parent bbc5dff7
...@@ -45,7 +45,6 @@ export class CustomScrollbar extends PureComponent<Props> { ...@@ -45,7 +45,6 @@ export class CustomScrollbar extends PureComponent<Props> {
if (this.props.scrollTop > 10000) { if (this.props.scrollTop > 10000) {
ref.scrollToBottom(); ref.scrollToBottom();
} else { } else {
console.log('scrollbar set scrollTop');
ref.scrollTop(this.props.scrollTop); ref.scrollTop(this.props.scrollTop);
} }
} }
......
import { actionCreatorFactory } from './actionCreatorFactory'; export { actionCreatorFactory, noPayloadActionCreatorFactory, ActionOf } from './actionCreatorFactory';
import { reducerFactory } from './reducerFactory'; export { reducerFactory } from './reducerFactory';
export { actionCreatorFactory, reducerFactory };
...@@ -38,6 +38,7 @@ interface Props { ...@@ -38,6 +38,7 @@ interface Props {
urlEdit: boolean; urlEdit: boolean;
urlFullscreen: boolean; urlFullscreen: boolean;
loadingState: DashboardLoadingState; loadingState: DashboardLoadingState;
isLoadingSlow: boolean;
dashboard: DashboardModel; dashboard: DashboardModel;
initDashboard: typeof initDashboard; initDashboard: typeof initDashboard;
setDashboardModel: typeof setDashboardModel; setDashboardModel: typeof setDashboardModel;
...@@ -52,6 +53,7 @@ interface State { ...@@ -52,6 +53,7 @@ interface State {
fullscreenPanel: PanelModel | null; fullscreenPanel: PanelModel | null;
scrollTop: number; scrollTop: number;
rememberScrollTop: number; rememberScrollTop: number;
showLoadingState: boolean;
} }
export class DashboardPage extends PureComponent<Props, State> { export class DashboardPage extends PureComponent<Props, State> {
...@@ -59,6 +61,7 @@ export class DashboardPage extends PureComponent<Props, State> { ...@@ -59,6 +61,7 @@ export class DashboardPage extends PureComponent<Props, State> {
isSettingsOpening: false, isSettingsOpening: false,
isEditing: false, isEditing: false,
isFullscreen: false, isFullscreen: false,
showLoadingState: false,
fullscreenPanel: null, fullscreenPanel: null,
scrollTop: 0, scrollTop: 0,
rememberScrollTop: 0, rememberScrollTop: 0,
...@@ -196,11 +199,24 @@ export class DashboardPage extends PureComponent<Props, State> { ...@@ -196,11 +199,24 @@ export class DashboardPage extends PureComponent<Props, State> {
this.setState({ scrollTop: 0 }); this.setState({ scrollTop: 0 });
}; };
renderLoadingState() {
return (
<div className="dashboard-loading">
<div className="dashboard-loading__text">
<i className="fa fa-spinner fa-spin" /> Dashboard {this.props.loadingState}
</div>
</div>
);
}
render() { render() {
const { dashboard, editview, $injector } = this.props; const { dashboard, editview, $injector, isLoadingSlow } = this.props;
const { isSettingsOpening, isEditing, isFullscreen, scrollTop } = this.state; const { isSettingsOpening, isEditing, isFullscreen, scrollTop } = this.state;
if (!dashboard) { if (!dashboard) {
if (isLoadingSlow) {
return this.renderLoadingState();
}
return null; return null;
} }
...@@ -249,6 +265,7 @@ const mapStateToProps = (state: StoreState) => ({ ...@@ -249,6 +265,7 @@ const mapStateToProps = (state: StoreState) => ({
urlFullscreen: state.location.query.fullscreen === true, urlFullscreen: state.location.query.fullscreen === true,
urlEdit: state.location.query.edit === true, urlEdit: state.location.query.edit === true,
loadingState: state.dashboard.loadingState, loadingState: state.dashboard.loadingState,
isLoadingSlow: state.dashboard.isLoadingSlow,
dashboard: state.dashboard.model as DashboardModel, dashboard: state.dashboard.model as DashboardModel,
}); });
......
...@@ -3,8 +3,7 @@ import { ThunkAction } from 'redux-thunk'; ...@@ -3,8 +3,7 @@ import { ThunkAction } from 'redux-thunk';
// Services & Utils // Services & Utils
import { getBackendSrv } from 'app/core/services/backend_srv'; import { getBackendSrv } from 'app/core/services/backend_srv';
import { actionCreatorFactory } from 'app/core/redux'; import { actionCreatorFactory, noPayloadActionCreatorFactory, ActionOf } from 'app/core/redux';
import { ActionOf } from 'app/core/redux/actionCreatorFactory';
import { createSuccessNotification } from 'app/core/copy/appNotification'; import { createSuccessNotification } from 'app/core/copy/appNotification';
// Actions // Actions
...@@ -25,6 +24,7 @@ import { DashboardLoadingState, MutableDashboard } from 'app/types/dashboard'; ...@@ -25,6 +24,7 @@ import { DashboardLoadingState, MutableDashboard } from 'app/types/dashboard';
export const loadDashboardPermissions = actionCreatorFactory<DashboardAclDTO[]>('LOAD_DASHBOARD_PERMISSIONS').create(); export const loadDashboardPermissions = actionCreatorFactory<DashboardAclDTO[]>('LOAD_DASHBOARD_PERMISSIONS').create();
export const setDashboardLoadingState = actionCreatorFactory<DashboardLoadingState>('SET_DASHBOARD_LOADING_STATE').create(); export const setDashboardLoadingState = actionCreatorFactory<DashboardLoadingState>('SET_DASHBOARD_LOADING_STATE').create();
export const setDashboardModel = actionCreatorFactory<MutableDashboard>('SET_DASHBOARD_MODEL').create(); export const setDashboardModel = actionCreatorFactory<MutableDashboard>('SET_DASHBOARD_MODEL').create();
export const setDashboardLoadingSlow = noPayloadActionCreatorFactory('SET_DASHBOARD_LOADING_SLOW').create();
export type Action = ActionOf<DashboardAclDTO[]>; export type Action = ActionOf<DashboardAclDTO[]>;
export type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>; export type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>;
......
...@@ -12,7 +12,7 @@ import { config } from 'app/core/config'; ...@@ -12,7 +12,7 @@ import { config } from 'app/core/config';
import { updateLocation } from 'app/core/actions'; import { updateLocation } from 'app/core/actions';
import { notifyApp } from 'app/core/actions'; import { notifyApp } from 'app/core/actions';
import locationUtil from 'app/core/utils/location_util'; import locationUtil from 'app/core/utils/location_util';
import { setDashboardLoadingState, ThunkResult, setDashboardModel } from './actions'; import { setDashboardLoadingState, ThunkResult, setDashboardModel, setDashboardLoadingSlow } from './actions';
import { removePanel } from '../utils/panel'; import { removePanel } from '../utils/panel';
// Types // Types
...@@ -71,6 +71,14 @@ export function initDashboard({ ...@@ -71,6 +71,14 @@ export function initDashboard({
// set fetching state // set fetching state
dispatch(setDashboardLoadingState(DashboardLoadingState.Fetching)); dispatch(setDashboardLoadingState(DashboardLoadingState.Fetching));
// Detect slow loading / initializing and set state flag
// This is in order to not show loading indication for fast loading dashboards as it creates blinking/flashing
setTimeout(() => {
if (getState().dashboard.model === null) {
dispatch(setDashboardLoadingSlow());
}
}, 500);
try { try {
switch (routeInfo) { switch (routeInfo) {
// handle old urls with no uid // handle old urls with no uid
......
import { DashboardState, DashboardLoadingState } from 'app/types/dashboard'; import { DashboardState, DashboardLoadingState } from 'app/types/dashboard';
import { loadDashboardPermissions, setDashboardLoadingState, setDashboardModel } from './actions'; import { loadDashboardPermissions, setDashboardLoadingState, setDashboardModel, setDashboardLoadingSlow } from './actions';
import { reducerFactory } from 'app/core/redux'; import { reducerFactory } from 'app/core/redux';
import { processAclItems } from 'app/core/utils/acl'; import { processAclItems } from 'app/core/utils/acl';
export const initialState: DashboardState = { export const initialState: DashboardState = {
loadingState: DashboardLoadingState.NotStarted, loadingState: DashboardLoadingState.NotStarted,
isLoadingSlow: false,
model: null, model: null,
permissions: [], permissions: [],
}; };
...@@ -28,7 +29,15 @@ export const dashboardReducer = reducerFactory(initialState) ...@@ -28,7 +29,15 @@ export const dashboardReducer = reducerFactory(initialState)
filter: setDashboardModel, filter: setDashboardModel,
mapper: (state, action) => ({ mapper: (state, action) => ({
...state, ...state,
model: action.payload model: action.payload,
isLoadingSlow: false,
}),
})
.addMapper({
filter: setDashboardLoadingSlow,
mapper: (state, action) => ({
...state,
isLoadingSlow: true,
}), }),
}) })
.create(); .create();
......
...@@ -25,5 +25,6 @@ export enum DashboardLoadingState { ...@@ -25,5 +25,6 @@ export enum DashboardLoadingState {
export interface DashboardState { export interface DashboardState {
model: MutableDashboard | null; model: MutableDashboard | null;
loadingState: DashboardLoadingState; loadingState: DashboardLoadingState;
isLoadingSlow: boolean;
permissions: DashboardAcl[] | null; permissions: DashboardAcl[] | null;
} }
...@@ -276,3 +276,14 @@ div.flot-text { ...@@ -276,3 +276,14 @@ div.flot-text {
.panel-full-edit { .panel-full-edit {
padding-top: $dashboard-padding; padding-top: $dashboard-padding;
} }
.dashboard-loading {
height: 60vh;
display: flex;
align-items: center;
justify-content: center;
}
.dashboard-loading__text {
font-size: $font-size-lg;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment