TemplateQueryComponent.tsx 5.6 KB

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