TemplateQueryComponent.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import React, { PureComponent } from 'react';
  2. import ServicePicker from './ServicePicker';
  3. import MetricTypePicker from './MetricTypePicker';
  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. // metricLabelValue: '',
  30. // resourceLabelValue: '',
  31. };
  32. constructor(props: TemplateQueryProps) {
  33. super(props);
  34. this.handleQueryTypeChange = this.handleQueryTypeChange.bind(this);
  35. this.onServiceChange = this.onServiceChange.bind(this);
  36. this.onMetricTypeChange = this.onMetricTypeChange.bind(this);
  37. this.onLabelKeyChange = this.onLabelKeyChange.bind(this);
  38. this.state = defaultsDeep(this.props.query, this.defaults);
  39. }
  40. async componentDidMount() {
  41. const metricDescriptors = await this.props.datasource.getMetricTypes(this.props.datasource.projectName);
  42. this.setState({ metricDescriptors }, () => {
  43. if (this.state.metricType) {
  44. this.loadTimeSeriesData();
  45. }
  46. });
  47. }
  48. async loadTimeSeriesData() {
  49. console.log('loadTimeSeriesData', this.state.metricType);
  50. const refId = 'StackdriverTemplateQueryComponent';
  51. const response = await this.props.datasource.getLabels(this.state.metricType, refId);
  52. if (this.isLabelQuery(this.state.type) && has(response, `meta.${this.state.type}`)) {
  53. this.setState({ [this.state.type]: Object.keys(response.meta[this.state.type]) });
  54. }
  55. }
  56. handleQueryTypeChange(event) {
  57. this.setState({ type: event.target.value }, () => {
  58. if (this.isLabelQuery(event.target.value)) {
  59. this.loadTimeSeriesData();
  60. }
  61. });
  62. }
  63. onServiceChange(event) {
  64. this.setState({ service: event.target.value });
  65. }
  66. onMetricTypeChange(event) {
  67. this.setState({ metricType: event.target.value }, () => {
  68. if (this.isLabelQuery(this.state.type)) {
  69. this.loadTimeSeriesData();
  70. }
  71. });
  72. }
  73. onLabelKeyChange(event) {
  74. const key = this.state.type === MetricFindQueryTypes.MetricLabels ? 'metricLabelKey' : 'resourceLabelKey';
  75. this.setState({ [key]: event.target.value });
  76. }
  77. componentDidUpdate() {
  78. const { metricDescriptors, metricLabels, resourceLabels, ...queryModel } = this.state;
  79. this.props.onChange(queryModel);
  80. }
  81. isLabelQuery(queryType) {
  82. return [MetricFindQueryTypes.MetricLabels, MetricFindQueryTypes.ResourceLabels].indexOf(queryType) !== -1;
  83. }
  84. getDropdown(queryType) {
  85. switch (queryType) {
  86. case MetricFindQueryTypes.ResourceLabels:
  87. return (
  88. <SimpleDropdown
  89. value={this.state.resourceLabelKey}
  90. options={this.state.resourceLabels}
  91. onValueChange={this.onLabelKeyChange}
  92. label="Resource Labels"
  93. />
  94. );
  95. case MetricFindQueryTypes.MetricLabels:
  96. return (
  97. <SimpleDropdown
  98. value={this.state.metricLabelKey}
  99. options={this.state.metricLabels}
  100. onValueChange={this.onLabelKeyChange}
  101. label="Metric Labels"
  102. />
  103. );
  104. default:
  105. return '';
  106. }
  107. }
  108. renderQueryTypeSwitch(queryType) {
  109. switch (queryType) {
  110. case MetricFindQueryTypes.MetricTypes:
  111. return (
  112. <ServicePicker
  113. selectedService={this.state.service}
  114. metricDescriptors={this.state.metricDescriptors}
  115. onServiceChange={this.onServiceChange}
  116. />
  117. );
  118. case MetricFindQueryTypes.MetricLabels:
  119. case MetricFindQueryTypes.ResourceLabels:
  120. case MetricFindQueryTypes.ResourceTypes:
  121. const dropdown = this.getDropdown(queryType);
  122. return (
  123. <React.Fragment>
  124. {this.state.metricLabels.join(',')}
  125. <ServicePicker
  126. selectedService={this.state.service}
  127. metricDescriptors={this.state.metricDescriptors}
  128. onServiceChange={this.onServiceChange}
  129. />
  130. <MetricTypePicker
  131. selectedService={this.state.service}
  132. selectedMetricType={this.state.metricType}
  133. metricDescriptors={this.state.metricDescriptors}
  134. onMetricTypeChange={this.onMetricTypeChange}
  135. />
  136. {dropdown}
  137. </React.Fragment>
  138. );
  139. case MetricFindQueryTypes.Alignerns:
  140. case MetricFindQueryTypes.Aggregations:
  141. return (
  142. <React.Fragment>
  143. <ServicePicker
  144. selectedService={this.state.service}
  145. metricDescriptors={this.state.metricDescriptors}
  146. onServiceChange={this.onServiceChange}
  147. />
  148. <MetricTypePicker
  149. selectedMetricType={this.state.metricType}
  150. selectedService={this.state.service}
  151. metricDescriptors={this.state.metricDescriptors}
  152. onMetricTypeChange={this.onMetricTypeChange}
  153. />
  154. </React.Fragment>
  155. );
  156. default:
  157. return '';
  158. }
  159. }
  160. render() {
  161. return (
  162. <React.Fragment>
  163. <div className="gf-form max-width-21">
  164. <span className="gf-form-label width-7">Query Type</span>
  165. <div className="gf-form-select-wrapper max-width-14">
  166. <select
  167. className="gf-form-input"
  168. defaultValue={this.state.type}
  169. required
  170. onChange={this.handleQueryTypeChange}
  171. >
  172. {this.queryTypes.map((qt, i) => (
  173. <option key={i} value={qt.value} ng-if="false">
  174. {qt.name}
  175. </option>
  176. ))}
  177. </select>
  178. </div>
  179. </div>
  180. {this.renderQueryTypeSwitch(this.state.type)}
  181. </React.Fragment>
  182. );
  183. }
  184. }