Commit 4f943687 by Johannes Schill

feat: Display error when plot fail to render

parent 0b89f816
...@@ -9,6 +9,7 @@ export interface PanelProps<T = any> { ...@@ -9,6 +9,7 @@ export interface PanelProps<T = any> {
renderCounter: number; renderCounter: number;
width: number; width: number;
height: number; height: number;
onRenderError: () => void;
} }
export interface PanelOptionsProps<T = any> { export interface PanelOptionsProps<T = any> {
......
...@@ -13,6 +13,7 @@ interface GraphProps { ...@@ -13,6 +13,7 @@ interface GraphProps {
showBars?: boolean; showBars?: boolean;
width: number; width: number;
height: number; height: number;
onRenderError: () => void;
} }
export class Graph extends PureComponent<GraphProps> { export class Graph extends PureComponent<GraphProps> {
...@@ -37,7 +38,7 @@ export class Graph extends PureComponent<GraphProps> { ...@@ -37,7 +38,7 @@ export class Graph extends PureComponent<GraphProps> {
return; return;
} }
const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props; const { width, timeSeries, timeRange, showLines, showBars, showPoints, onRenderError } = this.props;
if (!width) { if (!width) {
return; return;
...@@ -98,6 +99,7 @@ export class Graph extends PureComponent<GraphProps> { ...@@ -98,6 +99,7 @@ export class Graph extends PureComponent<GraphProps> {
$.plot(this.element, timeSeries, flotOptions); $.plot(this.element, timeSeries, flotOptions);
} catch (err) { } catch (err) {
console.log('Graph rendering error', err, flotOptions, timeSeries); console.log('Graph rendering error', err, flotOptions, timeSeries);
onRenderError();
} }
} }
......
...@@ -3,6 +3,11 @@ import Portal from 'app/core/components/Portal/Portal'; ...@@ -3,6 +3,11 @@ import Portal from 'app/core/components/Portal/Portal';
import { Manager, Popper as ReactPopper, Reference } from 'react-popper'; import { Manager, Popper as ReactPopper, Reference } from 'react-popper';
import Transition from 'react-transition-group/Transition'; import Transition from 'react-transition-group/Transition';
export enum Themes {
Default = 'popper__background--default',
Error = 'popper__background--error',
}
const defaultTransitionStyles = { const defaultTransitionStyles = {
transition: 'opacity 200ms linear', transition: 'opacity 200ms linear',
opacity: 0, opacity: 0,
...@@ -21,12 +26,7 @@ interface Props { ...@@ -21,12 +26,7 @@ interface Props {
placement?: any; placement?: any;
content: string | ((props: any) => JSX.Element); content: string | ((props: any) => JSX.Element);
refClassName?: string; refClassName?: string;
theme?: string; theme?: Themes;
}
export enum Themes {
Default = 'popper__background--default',
Error = 'popper__background--error',
} }
class Popper extends PureComponent<Props> { class Popper extends PureComponent<Props> {
......
import React from 'react'; import React from 'react';
import { Themes } from './Popper';
export interface UsingPopperProps { export interface UsingPopperProps {
showPopper: (prevState: object) => void; showPopper: (prevState: object) => void;
hidePopper: (prevState: object) => void; hidePopper: (prevState: object) => void;
...@@ -9,7 +9,7 @@ export interface UsingPopperProps { ...@@ -9,7 +9,7 @@ export interface UsingPopperProps {
content: string | ((props: any) => JSX.Element); content: string | ((props: any) => JSX.Element);
className?: string; className?: string;
refClassName?: string; refClassName?: string;
theme?: string; theme?: Themes;
} }
interface Props { interface Props {
...@@ -17,7 +17,7 @@ interface Props { ...@@ -17,7 +17,7 @@ interface Props {
className?: string; className?: string;
refClassName?: string; refClassName?: string;
content: string | ((props: any) => JSX.Element); content: string | ((props: any) => JSX.Element);
theme?: string; theme?: Themes;
} }
interface State { interface State {
......
...@@ -16,6 +16,7 @@ import { Themes } from 'app/core/components/Tooltip/Popper'; ...@@ -16,6 +16,7 @@ import { Themes } from 'app/core/components/Tooltip/Popper';
interface RenderProps { interface RenderProps {
loading: LoadingState; loading: LoadingState;
timeSeries: TimeSeries[]; timeSeries: TimeSeries[];
onRenderError: () => void;
} }
export interface Props { export interface Props {
...@@ -35,6 +36,7 @@ export interface Props { ...@@ -35,6 +36,7 @@ export interface Props {
export interface State { export interface State {
isFirstLoad: boolean; isFirstLoad: boolean;
loading: LoadingState; loading: LoadingState;
errorMessage: string;
response: DataQueryResponse; response: DataQueryResponse;
} }
...@@ -53,6 +55,7 @@ export class DataPanel extends Component<Props, State> { ...@@ -53,6 +55,7 @@ export class DataPanel extends Component<Props, State> {
this.state = { this.state = {
loading: LoadingState.NotStarted, loading: LoadingState.NotStarted,
errorMessage: '',
response: { response: {
data: [], data: [],
}, },
...@@ -92,7 +95,7 @@ export class DataPanel extends Component<Props, State> { ...@@ -92,7 +95,7 @@ export class DataPanel extends Component<Props, State> {
return; return;
} }
this.setState({ loading: LoadingState.Loading }); this.setState({ loading: LoadingState.Loading, errorMessage: '' });
try { try {
const ds = await this.dataSourceSrv.get(datasource); const ds = await this.dataSourceSrv.get(datasource);
...@@ -130,10 +133,24 @@ export class DataPanel extends Component<Props, State> { ...@@ -130,10 +133,24 @@ export class DataPanel extends Component<Props, State> {
}); });
} catch (err) { } catch (err) {
console.log('Loading error', 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() { render() {
const { queries } = this.props; const { queries } = this.props;
const { response, loading, isFirstLoad } = this.state; const { response, loading, isFirstLoad } = this.state;
...@@ -158,13 +175,14 @@ export class DataPanel extends Component<Props, State> { ...@@ -158,13 +175,14 @@ export class DataPanel extends Component<Props, State> {
{this.props.children({ {this.props.children({
timeSeries, timeSeries,
loading, loading,
onRenderError: this.onRenderError
})} })}
</> </>
); );
} }
private renderLoadingStates(): JSX.Element { private renderLoadingStates(): JSX.Element {
const { loading } = this.state; const { loading, errorMessage } = this.state;
if (loading === LoadingState.Loading) { if (loading === LoadingState.Loading) {
return ( return (
<div className="panel-loading"> <div className="panel-loading">
...@@ -174,7 +192,7 @@ export class DataPanel extends Component<Props, State> { ...@@ -174,7 +192,7 @@ export class DataPanel extends Component<Props, State> {
} else if (loading === LoadingState.Error) { } else if (loading === LoadingState.Error) {
return ( return (
<Tooltip <Tooltip
content="Request Error" content={errorMessage}
className="popper__manager--block" className="popper__manager--block"
refClassName={`panel-info-corner panel-info-corner--error`} refClassName={`panel-info-corner panel-info-corner--error`}
placement="bottom-start" placement="bottom-start"
......
...@@ -87,7 +87,6 @@ export class PanelChrome extends PureComponent<Props, State> { ...@@ -87,7 +87,6 @@ export class PanelChrome extends PureComponent<Props, State> {
const { datasource, targets, transparent } = panel; const { datasource, targets, transparent } = panel;
const PanelComponent = plugin.exports.Panel; const PanelComponent = plugin.exports.Panel;
const containerClassNames = `panel-container panel-container--absolute ${transparent ? 'panel-transparent' : ''}`; const containerClassNames = `panel-container panel-container--absolute ${transparent ? 'panel-transparent' : ''}`;
return ( return (
<AutoSizer> <AutoSizer>
{({ width, height }) => { {({ width, height }) => {
...@@ -115,7 +114,7 @@ export class PanelChrome extends PureComponent<Props, State> { ...@@ -115,7 +114,7 @@ export class PanelChrome extends PureComponent<Props, State> {
widthPixels={width} widthPixels={width}
refreshCounter={refreshCounter} refreshCounter={refreshCounter}
> >
{({ loading, timeSeries }) => { {({ loading, timeSeries, onRenderError }) => {
return ( return (
<div className="panel-content"> <div className="panel-content">
<PanelComponent <PanelComponent
...@@ -126,6 +125,7 @@ export class PanelChrome extends PureComponent<Props, State> { ...@@ -126,6 +125,7 @@ export class PanelChrome extends PureComponent<Props, State> {
width={width} width={width}
height={height - PANEL_HEADER_HEIGHT} height={height - PANEL_HEADER_HEIGHT}
renderCounter={renderCounter} renderCounter={renderCounter}
onRenderError={onRenderError}
/> />
</div> </div>
); );
......
// Libraries // Libraries
import _ from 'lodash'; import _ from 'lodash';
import React, { PureComponent } from 'react'; import React, { Component } from 'react';
import colors from 'app/core/utils/colors'; import colors from 'app/core/utils/colors';
// Components & Types // Components & Types
...@@ -9,13 +9,13 @@ import { Options } from './types'; ...@@ -9,13 +9,13 @@ import { Options } from './types';
interface Props extends PanelProps<Options> {} interface Props extends PanelProps<Options> {}
export class GraphPanel extends PureComponent<Props> { export class GraphPanel extends Component<Props> {
constructor(props) { constructor(props) {
super(props); super(props);
} }
render() { render() {
const { timeSeries, timeRange, width, height } = this.props; const { timeSeries, timeRange, width, height, onRenderError } = this.props;
const { showLines, showBars, showPoints } = this.props.options; const { showLines, showBars, showPoints } = this.props.options;
const vmSeries = processTimeSeries({ const vmSeries = processTimeSeries({
...@@ -33,6 +33,7 @@ export class GraphPanel extends PureComponent<Props> { ...@@ -33,6 +33,7 @@ export class GraphPanel extends PureComponent<Props> {
showBars={showBars} showBars={showBars}
width={width} width={width}
height={height} height={height}
onRenderError={onRenderError}
/> />
); );
} }
......
...@@ -233,7 +233,7 @@ div.flot-text { ...@@ -233,7 +233,7 @@ div.flot-text {
&--error { &--error {
display: block; display: block;
color: $text-color; color: $white;
@include panel-corner-color($popover-error-bg); @include panel-corner-color($popover-error-bg);
.fa:before { .fa:before {
content: '\f12a'; content: '\f12a';
......
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