diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts index 44336555a81..cf808f514de 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -9,6 +9,7 @@ export interface PanelProps { renderCounter: number; width: number; height: number; + onRenderError: () => void; } export interface PanelOptionsProps { diff --git a/packages/grafana-ui/src/visualizations/Graph/Graph.tsx b/packages/grafana-ui/src/visualizations/Graph/Graph.tsx index 51afb33802d..b3f2120639c 100644 --- a/packages/grafana-ui/src/visualizations/Graph/Graph.tsx +++ b/packages/grafana-ui/src/visualizations/Graph/Graph.tsx @@ -13,6 +13,7 @@ interface GraphProps { showBars?: boolean; width: number; height: number; + onRenderError: () => void; } export class Graph extends PureComponent { @@ -37,7 +38,7 @@ export class Graph extends PureComponent { return; } - const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props; + const { width, timeSeries, timeRange, showLines, showBars, showPoints, onRenderError } = this.props; if (!width) { return; @@ -98,6 +99,7 @@ export class Graph extends PureComponent { $.plot(this.element, timeSeries, flotOptions); } catch (err) { console.log('Graph rendering error', err, flotOptions, timeSeries); + onRenderError(); } } diff --git a/public/app/core/components/Tooltip/Popper.tsx b/public/app/core/components/Tooltip/Popper.tsx index d5ea1d93091..65ef510ba8f 100644 --- a/public/app/core/components/Tooltip/Popper.tsx +++ b/public/app/core/components/Tooltip/Popper.tsx @@ -3,6 +3,11 @@ import Portal from 'app/core/components/Portal/Portal'; import { Manager, Popper as ReactPopper, Reference } from 'react-popper'; import Transition from 'react-transition-group/Transition'; +export enum Themes { + Default = 'popper__background--default', + Error = 'popper__background--error', +} + const defaultTransitionStyles = { transition: 'opacity 200ms linear', opacity: 0, @@ -21,12 +26,7 @@ interface Props { placement?: any; content: string | ((props: any) => JSX.Element); refClassName?: string; - theme?: string; -} - -export enum Themes { - Default = 'popper__background--default', - Error = 'popper__background--error', + theme?: Themes; } class Popper extends PureComponent { diff --git a/public/app/core/components/Tooltip/withPopper.tsx b/public/app/core/components/Tooltip/withPopper.tsx index 7be12748247..3766b78f0f6 100644 --- a/public/app/core/components/Tooltip/withPopper.tsx +++ b/public/app/core/components/Tooltip/withPopper.tsx @@ -1,5 +1,5 @@ import React from 'react'; - +import { Themes } from './Popper'; export interface UsingPopperProps { showPopper: (prevState: object) => void; hidePopper: (prevState: object) => void; @@ -9,7 +9,7 @@ export interface UsingPopperProps { content: string | ((props: any) => JSX.Element); className?: string; refClassName?: string; - theme?: string; + theme?: Themes; } interface Props { @@ -17,7 +17,7 @@ interface Props { className?: string; refClassName?: string; content: string | ((props: any) => JSX.Element); - theme?: string; + theme?: Themes; } interface State { diff --git a/public/app/features/dashboard/dashgrid/DataPanel.tsx b/public/app/features/dashboard/dashgrid/DataPanel.tsx index d57b787bf57..4cd9460802a 100644 --- a/public/app/features/dashboard/dashgrid/DataPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DataPanel.tsx @@ -16,6 +16,7 @@ import { Themes } from 'app/core/components/Tooltip/Popper'; interface RenderProps { loading: LoadingState; timeSeries: TimeSeries[]; + onRenderError: () => void; } export interface Props { @@ -35,6 +36,7 @@ export interface Props { export interface State { isFirstLoad: boolean; loading: LoadingState; + errorMessage: string; response: DataQueryResponse; } @@ -53,6 +55,7 @@ export class DataPanel extends Component { this.state = { loading: LoadingState.NotStarted, + errorMessage: '', response: { data: [], }, @@ -92,7 +95,7 @@ export class DataPanel extends Component { return; } - this.setState({ loading: LoadingState.Loading }); + this.setState({ loading: LoadingState.Loading, errorMessage: '' }); try { const ds = await this.dataSourceSrv.get(datasource); @@ -130,10 +133,24 @@ export class DataPanel extends Component { }); } catch (err) { console.log('Loading error', err); - this.setState({ loading: LoadingState.Error, isFirstLoad: false }); + this.onError('Request Error'); } }; + onError = (errorMessage: string) => { + if (this.state.loading !== LoadingState.Error || this.state.errorMessage !== errorMessage) { + this.setState({ + loading: LoadingState.Error, + isFirstLoad: false, + errorMessage: errorMessage + }); + } + } + + onRenderError = () => { + this.onError('Error rendering panel'); + } + render() { const { queries } = this.props; const { response, loading, isFirstLoad } = this.state; @@ -158,13 +175,14 @@ export class DataPanel extends Component { {this.props.children({ timeSeries, loading, + onRenderError: this.onRenderError })} ); } private renderLoadingStates(): JSX.Element { - const { loading } = this.state; + const { loading, errorMessage } = this.state; if (loading === LoadingState.Loading) { return (
@@ -174,7 +192,7 @@ export class DataPanel extends Component { } else if (loading === LoadingState.Error) { return ( { const { datasource, targets, transparent } = panel; const PanelComponent = plugin.exports.Panel; const containerClassNames = `panel-container panel-container--absolute ${transparent ? 'panel-transparent' : ''}`; - return ( {({ width, height }) => { @@ -115,7 +114,7 @@ export class PanelChrome extends PureComponent { widthPixels={width} refreshCounter={refreshCounter} > - {({ loading, timeSeries }) => { + {({ loading, timeSeries, onRenderError }) => { return (
{ width={width} height={height - PANEL_HEADER_HEIGHT} renderCounter={renderCounter} + onRenderError={onRenderError} />
); diff --git a/public/app/plugins/panel/graph2/GraphPanel.tsx b/public/app/plugins/panel/graph2/GraphPanel.tsx index a08276e5179..1a23fba0c27 100644 --- a/public/app/plugins/panel/graph2/GraphPanel.tsx +++ b/public/app/plugins/panel/graph2/GraphPanel.tsx @@ -1,6 +1,6 @@ // Libraries import _ from 'lodash'; -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import colors from 'app/core/utils/colors'; // Components & Types @@ -9,13 +9,13 @@ import { Options } from './types'; interface Props extends PanelProps {} -export class GraphPanel extends PureComponent { +export class GraphPanel extends Component { constructor(props) { super(props); } render() { - const { timeSeries, timeRange, width, height } = this.props; + const { timeSeries, timeRange, width, height, onRenderError } = this.props; const { showLines, showBars, showPoints } = this.props.options; const vmSeries = processTimeSeries({ @@ -33,6 +33,7 @@ export class GraphPanel extends PureComponent { showBars={showBars} width={width} height={height} + onRenderError={onRenderError} /> ); } diff --git a/public/sass/pages/_dashboard.scss b/public/sass/pages/_dashboard.scss index 81698d396f8..a0ff9fd877c 100644 --- a/public/sass/pages/_dashboard.scss +++ b/public/sass/pages/_dashboard.scss @@ -233,7 +233,7 @@ div.flot-text { &--error { display: block; - color: $text-color; + color: $white; @include panel-corner-color($popover-error-bg); .fa:before { content: '\f12a';