TemplateQueryComponent.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. 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. isLabelQuery(queryType) {
  50. return ['metricLabels', 'resourceLabels'].indexOf(queryType) !== -1;
  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. renderSwitch(queryType) {
  78. switch (queryType) {
  79. case 'metricTypes':
  80. return (
  81. <ServiceSelector metricDescriptors={this.state.metricDescriptors} onServiceChange={this.onServiceChange} />
  82. );
  83. case 'metricLabels':
  84. case 'resourceLabels':
  85. const dropdown =
  86. queryType === 'resourceLabels' ? (
  87. <SimpleDropdown
  88. value={this.state.resourceLabelKey}
  89. options={this.state.resourceLabels}
  90. onValueChange={this.onResourceLabelKeyChange}
  91. label="Resource Labels"
  92. />
  93. ) : (
  94. <SimpleDropdown
  95. value={this.state.metricLabelKey}
  96. options={this.state.metricLabels}
  97. onValueChange={this.onMetricLabelKeyChange}
  98. label="Metric Labels"
  99. />
  100. );
  101. return (
  102. <React.Fragment>
  103. <ServiceSelector metricDescriptors={this.state.metricDescriptors} onServiceChange={this.onServiceChange} />
  104. <MetricTypeSelector
  105. selectedService={this.state.service}
  106. metricDescriptors={this.state.metricDescriptors}
  107. onMetricTypeChange={this.onMetricTypeChange}
  108. />
  109. {dropdown}
  110. </React.Fragment>
  111. );
  112. default:
  113. return '';
  114. }
  115. }
  116. render() {
  117. return (
  118. <React.Fragment>
  119. <div className="gf-form max-width-21">
  120. <span className="gf-form-label width-7">Query Type</span>
  121. <div className="gf-form-select-wrapper max-width-14">
  122. <select className="gf-form-input" required onChange={this.handleQueryTypeChange}>
  123. {this.queryTypes.map((qt, i) => (
  124. <option key={i} value={qt.value} ng-if="false">
  125. {qt.name}
  126. </option>
  127. ))}
  128. </select>
  129. </div>
  130. </div>
  131. {this.renderSwitch(this.state.type)}
  132. </React.Fragment>
  133. );
  134. }
  135. }