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. isFirstLoad: false,
  87. });
  88. } catch (err) {
  89. console.log('Loading error', err);
  90. this.setState({ loading: LoadingState.Error, isFirstLoad: false });
  91. }
  92. };
  93. render() {
  94. const { response, loading, isFirstLoad } = this.state;
  95. console.log('data panel render');
  96. const timeSeries = response.data;
  97. if (isFirstLoad && (loading === LoadingState.Loading || loading === LoadingState.NotStarted)) {
  98. return (
  99. <div className="loading">
  100. <p>Loading</p>
  101. </div>
  102. );
  103. }
  104. return (
  105. <>
  106. {this.loadingSpinner}
  107. {this.props.children({
  108. timeSeries,
  109. loading,
  110. })}
  111. </>
  112. );
  113. }
  114. private get loadingSpinner(): JSX.Element {
  115. const { loading } = this.state;
  116. if (loading === LoadingState.Loading) {
  117. return (
  118. <div className="panel__loading">
  119. <i className="fa fa-spinner fa-spin" />
  120. </div>
  121. );
  122. }
  123. return null;
  124. }
  125. }