TemplateQueryComponent.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import React, { PureComponent } from 'react';
  2. import SimpleDropdown from './SimpleDropdown';
  3. import { TemplateQueryProps } from 'app/types/plugins';
  4. import { getMetricTypesByService, extractServicesFromMetricDescriptors } from '../functions';
  5. import defaultsDeep from 'lodash/defaultsDeep';
  6. import { MetricFindQueryTypes } from '../types';
  7. export class StackdriverTemplateQueryComponent extends PureComponent<TemplateQueryProps, any> {
  8. queryTypes: Array<{ value: string; name: string }> = [
  9. { value: MetricFindQueryTypes.Services, name: 'Services' },
  10. { value: MetricFindQueryTypes.MetricTypes, name: 'Metric Types' },
  11. { value: MetricFindQueryTypes.MetricLabels, name: 'Metric Labels' },
  12. { value: MetricFindQueryTypes.ResourceLabels, name: 'Resource Labels' },
  13. { value: MetricFindQueryTypes.ResourceTypes, name: 'Resource Types' },
  14. { value: MetricFindQueryTypes.Aggregations, name: 'Aggregations' },
  15. { value: MetricFindQueryTypes.Alignerns, name: 'Aligners' },
  16. { value: MetricFindQueryTypes.AlignmentPeriods, name: 'Alignment Periods' },
  17. ];
  18. defaults = {
  19. type: '',
  20. metricDescriptors: [],
  21. service: '',
  22. metricType: '',
  23. labels: [],
  24. labelKey: '',
  25. metricTypes: [],
  26. services: [],
  27. };
  28. constructor(props: TemplateQueryProps) {
  29. super(props);
  30. this.handleQueryTypeChange = this.handleQueryTypeChange.bind(this);
  31. this.onServiceChange = this.onServiceChange.bind(this);
  32. this.onMetricTypeChange = this.onMetricTypeChange.bind(this);
  33. this.onLabelKeyChange = this.onLabelKeyChange.bind(this);
  34. this.state = defaultsDeep(this.props.query, this.defaults);
  35. }
  36. async componentDidMount() {
  37. const metricDescriptors = await this.props.datasource.getMetricTypes(this.props.datasource.projectName);
  38. const services = extractServicesFromMetricDescriptors(metricDescriptors).map(m => ({
  39. value: m.service,
  40. name: m.serviceShortName,
  41. }));
  42. const service = this.state.service || services[0].value;
  43. const metricTypes = getMetricTypesByService(metricDescriptors, service).map(m => ({
  44. value: m.type,
  45. name: m.displayName,
  46. }));
  47. const metricType = this.state.metricType || metricTypes[0].value;
  48. const state: any = {
  49. services,
  50. service,
  51. metricTypes,
  52. metricType,
  53. metricDescriptors,
  54. ...await this.getLabels(this.state.metricType),
  55. };
  56. this.setState(state);
  57. }
  58. async handleQueryTypeChange(event) {
  59. const state: any = { type: event.target.value, ...await this.getLabels(this.state.metricType, event.target.value) };
  60. this.setState(state);
  61. }
  62. async onServiceChange(event) {
  63. const metricTypes = getMetricTypesByService(this.state.metricDescriptors, event.target.value).map(m => ({
  64. value: m.type,
  65. name: m.displayName,
  66. }));
  67. const metricTypeExistInArray = metricTypes.find(m => m.value === this.state.metricType);
  68. const metricType = metricTypeExistInArray ? metricTypeExistInArray.value : metricTypes[0].value;
  69. const state: any = { service: event.target.value, metricTypes, metricType, ...await this.getLabels(metricType) };
  70. this.setState(state);
  71. }
  72. async onMetricTypeChange(event) {
  73. const state: any = { metricType: event.target.value, ...await this.getLabels(event.target.value) };
  74. this.setState(state);
  75. }
  76. async getLabelKeys(metricType, type = this.state.type) {
  77. const refId = 'StackdriverTemplateQueryComponent';
  78. const response = await this.props.datasource.getLabels(metricType, refId);
  79. return Object.keys(response.meta[type]);
  80. }
  81. async getLabels(metricType, type = this.state.type) {
  82. let result = { labels: this.state.labels, labelKey: this.state.labelKey };
  83. if (this.isLabelQuery(type)) {
  84. const refId = 'StackdriverTemplateQueryComponent';
  85. const response = await this.props.datasource.getLabels(metricType, refId);
  86. const labels = Object.keys(response.meta[type]);
  87. const labelKey = labels.indexOf(this.state.labelKey) !== -1 ? this.state.labelKey : labels[0];
  88. result = { labels, labelKey };
  89. }
  90. return result;
  91. }
  92. onLabelKeyChange(event) {
  93. this.setState({ labelKey: event.target.value });
  94. }
  95. componentDidUpdate() {
  96. const { metricDescriptors, metricLabels, resourceLabels, ...queryModel } = this.state;
  97. this.props.onChange(queryModel);
  98. }
  99. isLabelQuery(queryType) {
  100. return [MetricFindQueryTypes.MetricLabels, MetricFindQueryTypes.ResourceLabels].indexOf(queryType) !== -1;
  101. }
  102. renderQueryTypeSwitch(queryType) {
  103. switch (queryType) {
  104. case MetricFindQueryTypes.MetricTypes:
  105. return (
  106. <SimpleDropdown
  107. value={this.state.service}
  108. options={this.state.services}
  109. onValueChange={this.onServiceChange}
  110. label="Services"
  111. />
  112. );
  113. case MetricFindQueryTypes.MetricLabels:
  114. case MetricFindQueryTypes.ResourceLabels:
  115. case MetricFindQueryTypes.ResourceTypes:
  116. return (
  117. <React.Fragment>
  118. <SimpleDropdown
  119. value={this.state.service}
  120. options={this.state.services}
  121. onValueChange={this.onServiceChange}
  122. label="Services"
  123. />
  124. <SimpleDropdown
  125. value={this.state.metricType}
  126. options={this.state.metricTypes}
  127. onValueChange={this.onMetricTypeChange}
  128. label="Metric Types"
  129. />
  130. <SimpleDropdown
  131. value={this.state.labelKey}
  132. options={this.state.labels.map(l => ({ value: l, name: l }))}
  133. onValueChange={this.onLabelKeyChange}
  134. label={
  135. this.state.type === MetricFindQueryTypes.ResourceLabels ? 'Resource Label Key' : 'Metric Label Key'
  136. }
  137. />
  138. </React.Fragment>
  139. );
  140. case MetricFindQueryTypes.Alignerns:
  141. case MetricFindQueryTypes.Aggregations:
  142. return (
  143. <React.Fragment>
  144. <SimpleDropdown
  145. value={this.state.service}
  146. options={this.state.services}
  147. onValueChange={this.onServiceChange}
  148. label="Services"
  149. />
  150. <SimpleDropdown
  151. value={this.state.metricType}
  152. options={this.state.metricTypes}
  153. onValueChange={this.onMetricTypeChange}
  154. label="Metric Types"
  155. />
  156. </React.Fragment>
  157. );
  158. default:
  159. return '';
  160. }
  161. }
  162. render() {
  163. return (
  164. <React.Fragment>
  165. <SimpleDropdown
  166. value={this.state.type}
  167. options={this.queryTypes}
  168. onValueChange={this.handleQueryTypeChange}
  169. label="Query Types"
  170. />
  171. {this.renderQueryTypeSwitch(this.state.type)}
  172. </React.Fragment>
  173. );
  174. }
  175. }