1import { css } from '@emotion/css';
2import { GrafanaTheme2 } from '@grafana/data';
3import { config, getGrafanaLiveSrv } from '@grafana/runtime';
4import { Alert, stylesFactory } from '@grafana/ui';
5import React, { PureComponent } from 'react';
6import { Unsubscribable } from 'rxjs';
7import { contextSrv } from 'app/core/services/context_srv';
8
9export interface Props {}
10
11export interface State {
12  show?: boolean;
13}
14
15export class LiveConnectionWarning extends PureComponent<Props, State> {
16  subscription?: Unsubscribable;
17  styles = getStyle(config.theme2);
18  state: State = {};
19
20  componentDidMount() {
21    // Only show the error in development mode
22    if (process.env.NODE_ENV === 'development') {
23      // Wait a second to listen for server errors
24      setTimeout(this.initListener, 1500);
25    }
26  }
27
28  initListener = () => {
29    const live = getGrafanaLiveSrv();
30    if (live) {
31      this.subscription = live.getConnectionState().subscribe({
32        next: (v) => {
33          this.setState({ show: !v });
34        },
35      });
36    }
37  };
38
39  componentWillUnmount() {
40    if (this.subscription) {
41      this.subscription.unsubscribe();
42    }
43  }
44
45  render() {
46    const { show } = this.state;
47    if (show) {
48      if (!contextSrv.isSignedIn || !config.liveEnabled || contextSrv.user.orgRole === '') {
49        return null; // do not show the warning for anonymous users or ones with no org (and /login page etc)
50      }
51
52      return (
53        <div className={this.styles.foot}>
54          <Alert severity={'warning'} className={this.styles.warn} title="connection to server is lost..." />
55        </div>
56      );
57    }
58    return null;
59  }
60}
61
62const getStyle = stylesFactory((theme: GrafanaTheme2) => {
63  return {
64    foot: css`
65      position: absolute;
66      bottom: 0px;
67      left: 0px;
68      right: 0px;
69      z-index: 10000;
70      cursor: wait;
71      margin: 16px;
72    `,
73    warn: css`
74      border: 2px solid ${theme.colors.warning.main};
75      max-width: 400px;
76      margin: auto;
77      height: 3em;
78    `,
79  };
80});
81