QueryEditor.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import React from 'react';
  2. import _ from 'lodash';
  3. import { TemplateSrv } from 'app/features/templating/template_srv';
  4. import { Metrics } from './Metrics';
  5. import { Filter } from './Filter';
  6. import { Aggregations } from './Aggregations';
  7. import { Alignments } from './Alignments';
  8. import { AlignmentPeriods } from './AlignmentPeriods';
  9. import { AliasBy } from './AliasBy';
  10. import { Help } from './Help';
  11. import { StackdriverQuery, MetricDescriptor } from '../types';
  12. import { getAlignmentPickerData } from '../functions';
  13. import StackdriverDatasource from '../datasource';
  14. import { SelectOptionItem } from '@grafana/ui';
  15. export interface Props {
  16. onQueryChange: (target: StackdriverQuery) => void;
  17. onExecuteQuery: () => void;
  18. target: StackdriverQuery;
  19. events: any;
  20. datasource: StackdriverDatasource;
  21. templateSrv: TemplateSrv;
  22. }
  23. interface State extends StackdriverQuery {
  24. alignOptions: Array<SelectOptionItem<string>>;
  25. lastQuery: string;
  26. lastQueryError: string;
  27. [key: string]: any;
  28. }
  29. export const DefaultTarget: State = {
  30. defaultProject: 'loading project...',
  31. metricType: '',
  32. metricKind: '',
  33. valueType: '',
  34. refId: '',
  35. service: '',
  36. unit: '',
  37. crossSeriesReducer: 'REDUCE_MEAN',
  38. alignmentPeriod: 'stackdriver-auto',
  39. perSeriesAligner: 'ALIGN_MEAN',
  40. groupBys: [],
  41. filters: [],
  42. aliasBy: '',
  43. alignOptions: [],
  44. lastQuery: '',
  45. lastQueryError: '',
  46. usedAlignmentPeriod: '',
  47. };
  48. export class QueryEditor extends React.Component<Props, State> {
  49. state: State = DefaultTarget;
  50. componentDidMount() {
  51. const { events, target, templateSrv } = this.props;
  52. events.on('data-received', this.onDataReceived.bind(this));
  53. events.on('data-error', this.onDataError.bind(this));
  54. const { perSeriesAligner, alignOptions } = getAlignmentPickerData(target, templateSrv);
  55. this.setState({
  56. ...this.props.target,
  57. alignOptions,
  58. perSeriesAligner,
  59. });
  60. }
  61. componentWillUnmount() {
  62. this.props.events.off('data-received', this.onDataReceived);
  63. this.props.events.off('data-error', this.onDataError);
  64. }
  65. onDataReceived(dataList) {
  66. const series = dataList.find(item => item.refId === this.props.target.refId);
  67. if (series) {
  68. this.setState({
  69. lastQuery: decodeURIComponent(series.meta.rawQuery),
  70. lastQueryError: '',
  71. usedAlignmentPeriod: series.meta.alignmentPeriod,
  72. });
  73. }
  74. }
  75. onDataError(err) {
  76. let lastQuery;
  77. let lastQueryError;
  78. if (err.data && err.data.error) {
  79. lastQueryError = this.props.datasource.formatStackdriverError(err);
  80. } else if (err.data && err.data.results) {
  81. const queryRes = err.data.results[this.props.target.refId];
  82. lastQuery = decodeURIComponent(queryRes.meta.rawQuery);
  83. if (queryRes && queryRes.error) {
  84. try {
  85. lastQueryError = JSON.parse(queryRes.error).error.message;
  86. } catch {
  87. lastQueryError = queryRes.error;
  88. }
  89. }
  90. }
  91. this.setState({ lastQuery, lastQueryError });
  92. }
  93. onMetricTypeChange = ({ valueType, metricKind, type, unit }: MetricDescriptor) => {
  94. const { templateSrv, onQueryChange, onExecuteQuery } = this.props;
  95. const { perSeriesAligner, alignOptions } = getAlignmentPickerData(
  96. { valueType, metricKind, perSeriesAligner: this.state.perSeriesAligner },
  97. templateSrv
  98. );
  99. this.setState(
  100. {
  101. alignOptions,
  102. perSeriesAligner,
  103. metricType: type,
  104. unit,
  105. valueType,
  106. metricKind,
  107. },
  108. () => {
  109. onQueryChange(this.state);
  110. onExecuteQuery();
  111. }
  112. );
  113. };
  114. onPropertyChange(prop, value) {
  115. this.setState({ [prop]: value }, () => {
  116. this.props.onQueryChange(this.state);
  117. this.props.onExecuteQuery();
  118. });
  119. }
  120. render() {
  121. const {
  122. usedAlignmentPeriod,
  123. defaultProject,
  124. metricType,
  125. crossSeriesReducer,
  126. groupBys,
  127. filters,
  128. perSeriesAligner,
  129. alignOptions,
  130. alignmentPeriod,
  131. aliasBy,
  132. lastQuery,
  133. lastQueryError,
  134. refId,
  135. } = this.state;
  136. const { datasource, templateSrv } = this.props;
  137. return (
  138. <>
  139. <Metrics
  140. defaultProject={defaultProject}
  141. metricType={metricType}
  142. templateSrv={templateSrv}
  143. datasource={datasource}
  144. onChange={this.onMetricTypeChange}
  145. >
  146. {metric => (
  147. <>
  148. <Filter
  149. filtersChanged={value => this.onPropertyChange('filters', value)}
  150. groupBysChanged={value => this.onPropertyChange('groupBys', value)}
  151. filters={filters}
  152. groupBys={groupBys}
  153. refId={refId}
  154. hideGroupBys={false}
  155. templateSrv={templateSrv}
  156. datasource={datasource}
  157. metricType={metric ? metric.type : ''}
  158. />
  159. <Aggregations
  160. metricDescriptor={metric}
  161. templateSrv={templateSrv}
  162. crossSeriesReducer={crossSeriesReducer}
  163. groupBys={groupBys}
  164. onChange={value => this.onPropertyChange('crossSeriesReducer', value)}
  165. >
  166. {displayAdvancedOptions =>
  167. displayAdvancedOptions && (
  168. <Alignments
  169. alignOptions={alignOptions}
  170. templateSrv={templateSrv}
  171. perSeriesAligner={perSeriesAligner}
  172. onChange={value => this.onPropertyChange('perSeriesAligner', value)}
  173. />
  174. )
  175. }
  176. </Aggregations>
  177. <AlignmentPeriods
  178. templateSrv={templateSrv}
  179. alignmentPeriod={alignmentPeriod}
  180. perSeriesAligner={perSeriesAligner}
  181. usedAlignmentPeriod={usedAlignmentPeriod}
  182. onChange={value => this.onPropertyChange('alignmentPeriod', value)}
  183. />
  184. <AliasBy value={aliasBy} onChange={value => this.onPropertyChange('aliasBy', value)} />
  185. <Help datasource={datasource} rawQuery={lastQuery} lastQueryError={lastQueryError} />
  186. </>
  187. )}
  188. </Metrics>
  189. </>
  190. );
  191. }
  192. }