From 1cda7c5977b309aba2d7c245d8b47e75f35e508b Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 29 Apr 2021 11:57:51 -0700 Subject: [PATCH] Live: show disconnection error banner when in dev mode (#33394) --- public/app/AppWrapper.tsx | 2 + .../features/live/LiveConnectionCorner.tsx | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 public/app/features/live/LiveConnectionCorner.tsx diff --git a/public/app/AppWrapper.tsx b/public/app/AppWrapper.tsx index 9ff34d1656d..9079e9af0c9 100644 --- a/public/app/AppWrapper.tsx +++ b/public/app/AppWrapper.tsx @@ -13,6 +13,7 @@ import { SideMenu } from './core/components/sidemenu/SideMenu'; import { GrafanaRoute } from './core/navigation/GrafanaRoute'; import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; import { SearchWrapper } from 'app/features/search'; +import { LiveConnectionCorner } from './features/live/LiveConnectionCorner'; interface AppWrapperProps { app: GrafanaApp; @@ -112,6 +113,7 @@ export class AppWrapper extends React.Component + diff --git a/public/app/features/live/LiveConnectionCorner.tsx b/public/app/features/live/LiveConnectionCorner.tsx new file mode 100644 index 00000000000..0dc76c2179e --- /dev/null +++ b/public/app/features/live/LiveConnectionCorner.tsx @@ -0,0 +1,67 @@ +import { css } from '@emotion/css'; +import { GrafanaTheme } from '@grafana/data'; +import { config, getGrafanaLiveSrv } from '@grafana/runtime'; +import { stylesFactory } from '@grafana/ui'; +import React, { PureComponent } from 'react'; +import { Unsubscribable } from 'rxjs'; + +export interface Props {} + +export interface State { + show?: boolean; +} + +export class LiveConnectionCorner extends PureComponent { + subscription?: Unsubscribable; + styles = getStyle(config.theme); + state: State = {}; + + componentDidMount() { + // Only show the error in development mode + if (process.env.NODE_ENV === 'development') { + // Wait a second to listen for server errors + setTimeout(this.initListener, 1500); + } + } + + initListener = () => { + const live = getGrafanaLiveSrv(); + if (live) { + this.subscription = live.getConnectionState().subscribe({ + next: (v) => { + this.setState({ show: !v }); + }, + }); + } + }; + + componentWillUnmount() { + if (this.subscription) { + this.subscription.unsubscribe(); + } + } + + render() { + const { show } = this.state; + if (show) { + return
; + } + return null; + } +} + +const getStyle = stylesFactory((theme: GrafanaTheme) => { + return { + corner: css` + position: fixed; + top: 0px !important; + left: 0px !important; + width: 0; + height: 0; + border-top: 60px solid ${theme.palette.brandWarning}; + border-right: 60px solid transparent; + z-index: 10000; + cursor: wait; + `, + }; +});