DataPanel.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Library
  2. import React, { Component } from 'react';
  3. // Services
  4. import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
  5. // Types
  6. import { TimeRange, LoadingState, DataQueryOptions, DataQueryResponse, TimeSeries } from 'app/types';
  7. interface RenderProps {
  8. loading: LoadingState;
  9. timeSeries: TimeSeries[];
  10. }
  11. export interface Props {
  12. datasource: string | null;
  13. queries: any[];
  14. panelId?: number;
  15. dashboardId?: number;
  16. isVisible?: boolean;
  17. timeRange?: TimeRange;
  18. refreshCounter: number;
  19. children: (r: RenderProps) => JSX.Element;
  20. }
  21. export interface State {
  22. isFirstLoad: boolean;
  23. loading: LoadingState;
  24. response: DataQueryResponse;
  25. }
  26. export class DataPanel extends Component<Props, State> {
  27. static defaultProps = {
  28. isVisible: true,
  29. panelId: 1,
  30. dashboardId: 1,
  31. };
  32. constructor(props: Props) {
  33. super(props);
  34. this.state = {
  35. loading: LoadingState.NotStarted,
  36. response: {
  37. data: [],
  38. },
  39. isFirstLoad: true,
  40. };
  41. }
  42. componentDidMount() {
  43. console.log('DataPanel mount');
  44. }
  45. async componentDidUpdate(prevProps: Props) {
  46. if (!this.hasPropsChanged(prevProps)) {
  47. return;
  48. }
  49. this.issueQueries();
  50. }
  51. hasPropsChanged(prevProps: Props) {
  52. return this.props.refreshCounter !== prevProps.refreshCounter || this.props.isVisible !== prevProps.isVisible;
  53. }
  54. issueQueries = async () => {
  55. const { isVisible, queries, datasource, panelId, dashboardId, timeRange } = this.props;
  56. if (!isVisible) {
  57. return;
  58. }
  59. if (!queries.length) {
  60. this.setState({ loading: LoadingState.Done });
  61. return;
  62. }
  63. this.setState({ loading: LoadingState.Loading });
  64. try {
  65. const dataSourceSrv = getDatasourceSrv();
  66. const ds = await dataSourceSrv.get(datasource);
  67. const queryOptions: DataQueryOptions = {
  68. timezone: 'browser',
  69. panelId: panelId,
  70. dashboardId: dashboardId,
  71. range: timeRange,
  72. rangeRaw: timeRange.raw,
  73. interval: '1s',
  74. intervalMs: 60000,
  75. targets: queries,
  76. maxDataPoints: 500,
  77. scopedVars: {},
  78. cacheTimeout: null,
  79. };
  80. console.log('Issuing DataPanel query', queryOptions);
  81. const resp = await ds.query(queryOptions);
  82. console.log('Issuing DataPanel query Resp', resp);
  83. this.setState({
  84. loading: LoadingState.Done,
  85. response: resp,
  86. });
  87. } catch (err) {
  88. console.log('Loading error', err);
  89. this.setState({ loading: LoadingState.Error });
  90. }
  91. };
  92. render() {
  93. const { response, loading, isFirstLoad } = this.state;
  94. console.log('data panel render');
  95. const timeSeries = response.data;
  96. if (isFirstLoad && (loading === LoadingState.Loading || loading === LoadingState.NotStarted)) {
  97. return (
  98. <div className="loading">
  99. <p>Loading</p>
  100. </div>
  101. );
  102. }
  103. return (
  104. <>
  105. {this.loadingSpinner}
  106. {this.props.children({
  107. timeSeries,
  108. loading,
  109. })}
  110. </>
  111. );
  112. }
  113. private get loadingSpinner(): JSX.Element {
  114. const { loading } = this.state;
  115. if (loading === LoadingState.Loading) {
  116. return (
  117. <div className="panel__loading">
  118. <i className="fa fa-spinner fa-spin" />
  119. </div>
  120. );
  121. }
  122. return null;
  123. }
  124. }