DataPanel.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. async componentDidUpdate(prevProps: Props) {
  43. if (!this.hasPropsChanged(prevProps)) {
  44. return;
  45. }
  46. this.issueQueries();
  47. }
  48. hasPropsChanged(prevProps: Props) {
  49. return this.props.refreshCounter !== prevProps.refreshCounter || this.props.isVisible !== prevProps.isVisible;
  50. }
  51. issueQueries = async () => {
  52. const { isVisible, queries, datasource, panelId, dashboardId, timeRange } = this.props;
  53. if (!isVisible) {
  54. return;
  55. }
  56. if (!queries.length) {
  57. this.setState({ loading: LoadingState.Done });
  58. return;
  59. }
  60. this.setState({ loading: LoadingState.Loading });
  61. try {
  62. const dataSourceSrv = getDatasourceSrv();
  63. const ds = await dataSourceSrv.get(datasource);
  64. const queryOptions: DataQueryOptions = {
  65. timezone: 'browser',
  66. panelId: panelId,
  67. dashboardId: dashboardId,
  68. range: timeRange,
  69. rangeRaw: timeRange.raw,
  70. interval: '1s',
  71. intervalMs: 60000,
  72. targets: queries,
  73. maxDataPoints: 500,
  74. scopedVars: {},
  75. cacheTimeout: null,
  76. };
  77. console.log('Issuing DataPanel query', queryOptions);
  78. const resp = await ds.query(queryOptions);
  79. console.log('Issuing DataPanel query Resp', resp);
  80. this.setState({
  81. loading: LoadingState.Done,
  82. response: resp,
  83. isFirstLoad: false,
  84. });
  85. } catch (err) {
  86. console.log('Loading error', err);
  87. this.setState({ loading: LoadingState.Error, isFirstLoad: false });
  88. }
  89. };
  90. render() {
  91. const { response, loading, isFirstLoad } = this.state;
  92. const timeSeries = response.data;
  93. if (isFirstLoad && (loading === LoadingState.Loading || loading === LoadingState.NotStarted)) {
  94. return (
  95. <div className="loading">
  96. <p>Loading</p>
  97. </div>
  98. );
  99. }
  100. return (
  101. <>
  102. {this.loadingSpinner}
  103. {this.props.children({
  104. timeSeries,
  105. loading,
  106. })}
  107. </>
  108. );
  109. }
  110. private get loadingSpinner(): JSX.Element {
  111. const { loading } = this.state;
  112. if (loading === LoadingState.Loading) {
  113. return (
  114. <div className="panel__loading">
  115. <i className="fa fa-spinner fa-spin" />
  116. </div>
  117. );
  118. }
  119. return null;
  120. }
  121. }