TemplateQueryComponent.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import React, { PureComponent } from 'react';
  2. import ServiceSelector from './ServiceSelector';
  3. import MetricTypeSelector from './MetricTypeSelector';
  4. import SimpleDropdown from './SimpleDropdown';
  5. import { TemplateQueryProps } from 'app/types/plugins';
  6. import defaultsDeep from 'lodash/defaultsDeep';
  7. import has from 'lodash/has';
  8. import { MetricFindQueryTypes } from '../types';
  9. export class StackdriverTemplateQueryComponent extends PureComponent<TemplateQueryProps, any> {
  10. queryTypes: Array<{ value: string; name: string }> = [
  11. { value: MetricFindQueryTypes.Services, name: 'Services' },
  12. { value: MetricFindQueryTypes.MetricTypes, name: 'Metric Types' },
  13. { value: MetricFindQueryTypes.MetricLabels, name: 'Metric Labels' },
  14. { value: MetricFindQueryTypes.ResourceLabels, name: 'Resource Labels' },
  15. { value: MetricFindQueryTypes.ResourceTypes, name: 'Resource Types' },
  16. { value: MetricFindQueryTypes.Aggregations, name: 'Aggregations' },
  17. { value: MetricFindQueryTypes.Alignerns, name: 'Aligners' },
  18. { value: MetricFindQueryTypes.AlignmentPeriods, name: 'Alignment Periods' },
  19. ];
  20. defaults = {
  21. type: '',
  22. metricDescriptors: [],
  23. service: '',
  24. metricType: '',
  25. metricLabels: [],
  26. resourceLabels: [],
  27. metricLabelKey: '',
  28. resourceLabelKey: '',
  29. };
  30. constructor(props: TemplateQueryProps) {
  31. super(props);
  32. this.handleQueryTypeChange = this.handleQueryTypeChange.bind(this);
  33. this.onServiceChange = this.onServiceChange.bind(this);
  34. this.onMetricTypeChange = this.onMetricTypeChange.bind(this);
  35. this.onLabelKeyChange = this.onLabelKeyChange.bind(this);
  36. this.state = defaultsDeep(this.props.query, this.defaults);
  37. }
  38. async componentDidMount() {
  39. const metricDescriptors = await this.props.datasource.getMetricTypes(this.props.datasource.projectName);
  40. this.setState({ metricDescriptors });
  41. }
  42. async loadTimeSeriesData() {
  43. const refId = 'StackdriverTemplateQueryComponent';
  44. const response = await this.props.datasource.getLabels(this.state.metricType, refId);
  45. if (this.isLabelQuery(this.state.type) && has(response, `meta.${this.state.type}`)) {
  46. this.setState({ [this.state.type]: Object.keys(response.meta[this.state.type]) });
  47. }
  48. }
  49. handleQueryTypeChange(event) {
  50. this.setState({ type: event.target.value });
  51. if (this.isLabelQuery(event.target.value)) {
  52. this.loadTimeSeriesData();
  53. }
  54. }
  55. onServiceChange(event) {
  56. this.setState({ service: event.target.value });
  57. }
  58. onMetricTypeChange(event) {
  59. this.setState({ metricType: event.target.value });
  60. if (this.isLabelQuery(this.state.type)) {
  61. this.loadTimeSeriesData();
  62. }
  63. }
  64. onLabelKeyChange(event) {
  65. const key = this.state.type === MetricFindQueryTypes.MetricLabels ? 'metricLabelKey' : 'resourceLabelKey';
  66. this.setState({ [key]: event.target.value });
  67. }
  68. componentDidUpdate() {
  69. const { metricDescriptors, metricLabels, resourceLabels, ...queryModel } = this.state;
  70. this.props.onChange(queryModel);
  71. }
  72. isLabelQuery(queryType) {
  73. return [MetricFindQueryTypes.MetricLabels, MetricFindQueryTypes.ResourceLabels].indexOf(queryType) !== -1;
  74. }
  75. getDropdown(queryType) {
  76. switch (queryType) {
  77. case MetricFindQueryTypes.ResourceLabels:
  78. return (
  79. <SimpleDropdown
  80. value={this.state.resourceLabelKey}
  81. options={this.state.resourceLabels}
  82. onValueChange={this.onLabelKeyChange}
  83. label="Resource Labels"
  84. />
  85. );
  86. case MetricFindQueryTypes.MetricLabels:
  87. return (
  88. <SimpleDropdown
  89. value={this.state.metricLabelKey}
  90. options={this.state.metricLabels}
  91. onValueChange={this.onLabelKeyChange}
  92. label="Metric Labels"
  93. />
  94. );
  95. default:
  96. return '';
  97. }
  98. }
  99. renderQueryTypeSwitch(queryType) {
  100. switch (queryType) {
  101. case MetricFindQueryTypes.MetricTypes:
  102. return (
  103. <ServiceSelector metricDescriptors={this.state.metricDescriptors} onServiceChange={this.onServiceChange} />
  104. );
  105. case MetricFindQueryTypes.MetricLabels:
  106. case MetricFindQueryTypes.ResourceLabels:
  107. case MetricFindQueryTypes.ResourceTypes:
  108. const dropdown = this.getDropdown(queryType);
  109. return (
  110. <React.Fragment>
  111. <ServiceSelector metricDescriptors={this.state.metricDescriptors} onServiceChange={this.onServiceChange} />
  112. <MetricTypeSelector
  113. selectedService={this.state.service}
  114. metricDescriptors={this.state.metricDescriptors}
  115. onMetricTypeChange={this.onMetricTypeChange}
  116. />
  117. {dropdown}
  118. </React.Fragment>
  119. );
  120. case MetricFindQueryTypes.Alignerns:
  121. case MetricFindQueryTypes.Aggregations:
  122. return (
  123. <React.Fragment>
  124. <ServiceSelector metricDescriptors={this.state.metricDescriptors} onServiceChange={this.onServiceChange} />
  125. <MetricTypeSelector
  126. selectedService={this.state.service}
  127. metricDescriptors={this.state.metricDescriptors}
  128. onMetricTypeChange={this.onMetricTypeChange}
  129. />
  130. </React.Fragment>
  131. );
  132. default:
  133. return '';
  134. }
  135. }
  136. render() {
  137. return (
  138. <React.Fragment>
  139. <div className="gf-form max-width-21">
  140. <span className="gf-form-label width-7">Query Type</span>
  141. <div className="gf-form-select-wrapper max-width-14">
  142. <select className="gf-form-input" required onChange={this.handleQueryTypeChange}>
  143. {this.queryTypes.map((qt, i) => (
  144. <option key={i} value={qt.value} ng-if="false">
  145. {qt.name}
  146. </option>
  147. ))}
  148. </select>
  149. </div>
  150. </div>
  151. {this.renderQueryTypeSwitch(this.state.type)}
  152. </React.Fragment>
  153. );
  154. }
  155. }