PromQueryEditor.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import _ from 'lodash';
  2. import React, { PureComponent } from 'react';
  3. // Types
  4. import { FormLabel, Select, SelectOptionItem, Switch } from '@grafana/ui';
  5. import { QueryEditorProps, DataSourceStatus } from '@grafana/ui/src/types';
  6. import { PrometheusDatasource } from '../datasource';
  7. import { PromQuery, PromOptions } from '../types';
  8. import PromQueryField from './PromQueryField';
  9. import PromLink from './PromLink';
  10. export type Props = QueryEditorProps<PrometheusDatasource, PromQuery, PromOptions>;
  11. const FORMAT_OPTIONS: Array<SelectOptionItem<string>> = [
  12. { label: 'Time series', value: 'time_series' },
  13. { label: 'Table', value: 'table' },
  14. { label: 'Heatmap', value: 'heatmap' },
  15. ];
  16. const INTERVAL_FACTOR_OPTIONS: Array<SelectOptionItem<number>> = _.map([1, 2, 3, 4, 5, 10], (value: number) => ({
  17. value,
  18. label: '1/' + value,
  19. }));
  20. interface State {
  21. legendFormat: string;
  22. formatOption: SelectOptionItem<string>;
  23. interval: string;
  24. intervalFactorOption: SelectOptionItem<number>;
  25. instant: boolean;
  26. }
  27. export class PromQueryEditor extends PureComponent<Props, State> {
  28. // Query target to be modified and used for queries
  29. query: PromQuery;
  30. constructor(props: Props) {
  31. super(props);
  32. const { query } = props;
  33. this.query = query;
  34. // Query target properties that are fullu controlled inputs
  35. this.state = {
  36. // Fully controlled text inputs
  37. interval: query.interval,
  38. legendFormat: query.legendFormat,
  39. // Select options
  40. formatOption: FORMAT_OPTIONS.find(option => option.value === query.format) || FORMAT_OPTIONS[0],
  41. intervalFactorOption:
  42. INTERVAL_FACTOR_OPTIONS.find(option => option.value === query.intervalFactor) || INTERVAL_FACTOR_OPTIONS[0],
  43. // Switch options
  44. instant: Boolean(query.instant),
  45. };
  46. }
  47. onFieldChange = (query: PromQuery, override?) => {
  48. this.query.expr = query.expr;
  49. };
  50. onFormatChange = (option: SelectOptionItem<string>) => {
  51. this.query.format = option.value;
  52. this.setState({ formatOption: option }, this.onRunQuery);
  53. };
  54. onInstantChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  55. const instant = e.target.checked;
  56. this.query.instant = instant;
  57. this.setState({ instant }, this.onRunQuery);
  58. };
  59. onIntervalChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
  60. const interval = e.currentTarget.value;
  61. this.query.interval = interval;
  62. this.setState({ interval });
  63. };
  64. onIntervalFactorChange = (option: SelectOptionItem<number>) => {
  65. this.query.intervalFactor = option.value;
  66. this.setState({ intervalFactorOption: option }, this.onRunQuery);
  67. };
  68. onLegendChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
  69. const legendFormat = e.currentTarget.value;
  70. this.query.legendFormat = legendFormat;
  71. this.setState({ legendFormat });
  72. };
  73. onRunQuery = () => {
  74. const { query } = this;
  75. this.props.onChange(query);
  76. this.props.onRunQuery();
  77. };
  78. render() {
  79. const { datasource, query, panelData, queryResponse } = this.props;
  80. const { formatOption, instant, interval, intervalFactorOption, legendFormat } = this.state;
  81. return (
  82. <div>
  83. <div className="gf-form-input" style={{ height: 'initial' }}>
  84. <PromQueryField
  85. datasource={datasource}
  86. query={query}
  87. onRunQuery={this.onRunQuery}
  88. onChange={this.onFieldChange}
  89. history={[]}
  90. panelData={panelData}
  91. queryResponse={queryResponse}
  92. datasourceStatus={DataSourceStatus.Connected} // TODO: replace with real DataSourceStatus
  93. />
  94. </div>
  95. <div className="gf-form-inline">
  96. <div className="gf-form">
  97. <FormLabel
  98. width={7}
  99. tooltip="Controls the name of the time series, using name or pattern. For example
  100. {{hostname}} will be replaced with label value for the label hostname."
  101. >
  102. Legend
  103. </FormLabel>
  104. <input
  105. type="text"
  106. className="gf-form-input"
  107. placeholder="legend format"
  108. value={legendFormat}
  109. onChange={this.onLegendChange}
  110. />
  111. </div>
  112. <div className="gf-form">
  113. <FormLabel
  114. width={7}
  115. tooltip="Leave blank for auto handling based on time range and panel width.
  116. Note that the actual dates used in the query will be adjusted
  117. to a multiple of the interval step."
  118. >
  119. Min step
  120. </FormLabel>
  121. <input
  122. type="text"
  123. className="gf-form-input width-8"
  124. placeholder={interval}
  125. onChange={this.onIntervalChange}
  126. value={interval}
  127. />
  128. </div>
  129. <div className="gf-form">
  130. <div className="gf-form-label">Resolution</div>
  131. <Select
  132. isSearchable={false}
  133. options={INTERVAL_FACTOR_OPTIONS}
  134. onChange={this.onIntervalFactorChange}
  135. value={intervalFactorOption}
  136. />
  137. </div>
  138. <div className="gf-form">
  139. <div className="gf-form-label">Format</div>
  140. <Select isSearchable={false} options={FORMAT_OPTIONS} onChange={this.onFormatChange} value={formatOption} />
  141. <Switch label="Instant" checked={instant} onChange={this.onInstantChange} />
  142. <FormLabel width={10} tooltip="Link to Graph in Prometheus">
  143. <PromLink
  144. datasource={datasource}
  145. query={this.query} // Use modified query
  146. panelData={panelData}
  147. />
  148. </FormLabel>
  149. </div>
  150. </div>
  151. </div>
  152. );
  153. }
  154. }