Metrics.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import React from 'react';
  2. import _ from 'lodash';
  3. import { StackdriverPicker } from './StackdriverPicker';
  4. export interface Props {
  5. onChange: (metricDescriptor) => void;
  6. templateSrv: any;
  7. datasource: any;
  8. defaultProject: string;
  9. metricType: string;
  10. }
  11. interface State {
  12. metricDescriptors: any[];
  13. metrics: any[];
  14. services: any[];
  15. service: string;
  16. metric: string;
  17. }
  18. export class Metrics extends React.Component<Props, State> {
  19. state: State = {
  20. metricDescriptors: [],
  21. metrics: [],
  22. services: [],
  23. service: '',
  24. metric: '',
  25. };
  26. constructor(props) {
  27. super(props);
  28. }
  29. componentDidMount() {
  30. this.getCurrentProject()
  31. .then(this.loadMetricDescriptors.bind(this))
  32. .then(this.initializeServiceAndMetrics.bind(this));
  33. }
  34. async getCurrentProject() {
  35. return new Promise(async (resolve, reject) => {
  36. try {
  37. if (!this.props.defaultProject || this.props.defaultProject === 'loading project...') {
  38. // this.props.defaultProject = await this.props.datasource.getDefaultProject();
  39. await this.props.datasource.getDefaultProject();
  40. }
  41. resolve(this.props.defaultProject);
  42. } catch (error) {
  43. // appEvents.emit('ds-request-error', error);
  44. reject();
  45. }
  46. });
  47. }
  48. async loadMetricDescriptors() {
  49. if (this.props.defaultProject !== 'loading project...') {
  50. const metricDescriptors = await this.props.datasource.getMetricTypes(this.props.defaultProject);
  51. this.setState({ metricDescriptors });
  52. return metricDescriptors;
  53. } else {
  54. return [];
  55. }
  56. }
  57. async initializeServiceAndMetrics() {
  58. const { metricDescriptors } = this.state;
  59. const services = this.getServicesList(metricDescriptors);
  60. const metrics = this.getMetricsList(metricDescriptors);
  61. const service = metrics.length > 0 ? metrics[0].service : '';
  62. this.setState({ metricDescriptors, services, metrics, service: service });
  63. }
  64. getMetricsList(metricDescriptors) {
  65. const selectedMetricDescriptor = metricDescriptors.find(
  66. md => md.type === this.props.templateSrv.replace(this.props.metricType)
  67. );
  68. const metricsByService = metricDescriptors.filter(m => m.service === selectedMetricDescriptor.service).map(m => ({
  69. service: m.service,
  70. value: m.type,
  71. label: m.displayName,
  72. description: m.description,
  73. }));
  74. return metricsByService;
  75. }
  76. handleServiceChange(service) {
  77. const { metricDescriptors } = this.state;
  78. const { templateSrv, metricType } = this.props;
  79. const metrics = metricDescriptors.filter(m => m.service === templateSrv.replace(service)).map(m => ({
  80. service: m.service,
  81. value: m.type,
  82. label: m.displayName,
  83. description: m.description,
  84. }));
  85. this.setState({ service, metrics });
  86. if (metrics.length > 0 && !metrics.some(m => m.value === templateSrv.replace(metricType))) {
  87. this.handleMetricTypeChange(metrics[0].value);
  88. }
  89. }
  90. handleMetricTypeChange(value) {
  91. const selectedMetricDescriptor = this.state.metricDescriptors.find(md => md.type === value);
  92. this.props.onChange(selectedMetricDescriptor);
  93. }
  94. getServicesList(metricDescriptors) {
  95. const services = metricDescriptors.map(m => ({
  96. value: m.service,
  97. label: _.startCase(m.serviceShortName),
  98. }));
  99. return services.length > 0 ? _.uniqBy(services, s => s.value) : [];
  100. }
  101. getTemplateVariablesGroup() {
  102. return {
  103. label: 'Template Variables',
  104. options: this.props.templateSrv.variables.map(v => ({
  105. label: `$${v.name}`,
  106. value: `$${v.name}`,
  107. })),
  108. };
  109. }
  110. render() {
  111. const { services, service, metrics } = this.state;
  112. const { metricType, templateSrv } = this.props;
  113. return (
  114. <React.Fragment>
  115. <div className="gf-form-inline">
  116. <div className="gf-form">
  117. <span className="gf-form-label width-9 query-keyword">Service</span>
  118. <StackdriverPicker
  119. onChange={value => this.handleServiceChange(value)}
  120. selected={service}
  121. options={services}
  122. searchable={false}
  123. placeholder="Select Services"
  124. className="width-15"
  125. />
  126. </div>
  127. <div className="gf-form gf-form--grow">
  128. <div className="gf-form-label gf-form-label--grow" />
  129. </div>
  130. </div>
  131. <div className="gf-form-inline">
  132. <div className="gf-form">
  133. <span className="gf-form-label width-9 query-keyword">Metric</span>
  134. <StackdriverPicker
  135. onChange={value => this.handleMetricTypeChange(value)}
  136. selected={metricType}
  137. templateVariables={templateSrv.variables}
  138. options={metrics}
  139. searchable={true}
  140. placeholder="Select Metric"
  141. className="width-15"
  142. groupName="Metric Types"
  143. />
  144. </div>
  145. <div className="gf-form gf-form--grow">
  146. <div className="gf-form-label gf-form-label--grow" />
  147. </div>
  148. </div>
  149. </React.Fragment>
  150. );
  151. }
  152. }