PromQueryEditor.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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?: any) => {
  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. <PromQueryField
  84. datasource={datasource}
  85. query={query}
  86. onRunQuery={this.onRunQuery}
  87. onChange={this.onFieldChange}
  88. history={[]}
  89. panelData={panelData}
  90. queryResponse={queryResponse}
  91. datasourceStatus={DataSourceStatus.Connected} // TODO: replace with real DataSourceStatus
  92. />
  93. <div className="gf-form-inline">
  94. <div className="gf-form">
  95. <FormLabel
  96. width={7}
  97. tooltip="Controls the name of the time series, using name or pattern. For example
  98. {{hostname}} will be replaced with label value for the label hostname."
  99. >
  100. Legend
  101. </FormLabel>
  102. <input
  103. type="text"
  104. className="gf-form-input"
  105. placeholder="legend format"
  106. value={legendFormat}
  107. onChange={this.onLegendChange}
  108. />
  109. </div>
  110. <div className="gf-form">
  111. <FormLabel
  112. width={7}
  113. tooltip="Leave blank for auto handling based on time range and panel width.
  114. Note that the actual dates used in the query will be adjusted
  115. to a multiple of the interval step."
  116. >
  117. Min step
  118. </FormLabel>
  119. <input
  120. type="text"
  121. className="gf-form-input width-8"
  122. placeholder={interval}
  123. onChange={this.onIntervalChange}
  124. value={interval}
  125. />
  126. </div>
  127. <div className="gf-form">
  128. <div className="gf-form-label">Resolution</div>
  129. <Select
  130. isSearchable={false}
  131. options={INTERVAL_FACTOR_OPTIONS}
  132. onChange={this.onIntervalFactorChange}
  133. value={intervalFactorOption}
  134. />
  135. </div>
  136. <div className="gf-form">
  137. <div className="gf-form-label">Format</div>
  138. <Select isSearchable={false} options={FORMAT_OPTIONS} onChange={this.onFormatChange} value={formatOption} />
  139. <Switch label="Instant" checked={instant} onChange={this.onInstantChange} />
  140. <FormLabel width={10} tooltip="Link to Graph in Prometheus">
  141. <PromLink
  142. datasource={datasource}
  143. query={this.query} // Use modified query
  144. panelData={panelData}
  145. />
  146. </FormLabel>
  147. </div>
  148. </div>
  149. </div>
  150. );
  151. }
  152. }