import { map } from 'lodash'; import React, { PureComponent } from 'react'; // Types import { CoreApp, SelectableValue } from '@grafana/data'; import { InlineFormLabel, LegacyForms, Select } from '@grafana/ui'; import { PromQuery } from '../types'; import { PromExemplarField } from './PromExemplarField'; import PromLink from './PromLink'; import PromQueryField from './PromQueryField'; import { PromQueryEditorProps } from './types'; const { Switch } = LegacyForms; export const FORMAT_OPTIONS: Array> = [ { label: 'Time series', value: 'time_series' }, { label: 'Table', value: 'table' }, { label: 'Heatmap', value: 'heatmap' }, ]; export const INTERVAL_FACTOR_OPTIONS: Array> = map([1, 2, 3, 4, 5, 10], (value: number) => ({ value, label: '1/' + value, })); interface State { legendFormat?: string; formatOption: SelectableValue; interval?: string; intervalFactorOption: SelectableValue; instant: boolean; exemplar: boolean; } export class PromQueryEditor extends PureComponent { // Query target to be modified and used for queries query: PromQuery; constructor(props: PromQueryEditorProps) { super(props); // Use default query to prevent undefined input values const defaultQuery: Partial = { expr: '', legendFormat: '', interval: '', // Set exemplar to false for alerting queries exemplar: props.app === CoreApp.UnifiedAlerting ? false : true, }; const query = Object.assign({}, defaultQuery, props.query); this.query = query; // Query target properties that are fully controlled inputs this.state = { // Fully controlled text inputs interval: query.interval, legendFormat: query.legendFormat, // Select options formatOption: FORMAT_OPTIONS.find((option) => option.value === query.format) || FORMAT_OPTIONS[0], intervalFactorOption: INTERVAL_FACTOR_OPTIONS.find((option) => option.value === query.intervalFactor) || INTERVAL_FACTOR_OPTIONS[0], // Switch options instant: Boolean(query.instant), exemplar: Boolean(query.exemplar), }; } onFieldChange = (query: PromQuery, override?: any) => { this.query.expr = query.expr; }; onFormatChange = (option: SelectableValue) => { this.query.format = option.value; this.setState({ formatOption: option }, this.onRunQuery); }; onInstantChange = (e: React.SyntheticEvent) => { const instant = (e.target as HTMLInputElement).checked; this.query.instant = instant; this.setState({ instant }, this.onRunQuery); }; onIntervalChange = (e: React.SyntheticEvent) => { const interval = e.currentTarget.value; this.query.interval = interval; this.setState({ interval }); }; onIntervalFactorChange = (option: SelectableValue) => { this.query.intervalFactor = option.value; this.setState({ intervalFactorOption: option }, this.onRunQuery); }; onLegendChange = (e: React.SyntheticEvent) => { const legendFormat = e.currentTarget.value; this.query.legendFormat = legendFormat; this.setState({ legendFormat }); }; onExemplarChange = (isEnabled: boolean) => { this.query.exemplar = isEnabled; this.setState({ exemplar: isEnabled }, this.onRunQuery); }; onRunQuery = () => { const { query } = this; // Change of query.hide happens outside of this component and is just passed as prop. We have to update it when running queries. const { hide } = this.props.query; this.props.onChange({ ...query, hide }); this.props.onRunQuery(); }; render() { const { datasource, query, range, data } = this.props; const { formatOption, instant, interval, intervalFactorOption, legendFormat } = this.state; //We want to hide exemplar field for unified alerting as exemplars in alerting don't make sense and are source of confusion const showExemplarField = this.props.app !== CoreApp.UnifiedAlerting; return (
Legend
An additional lower limit for the step parameter of the Prometheus query and for the{' '} $__interval and $__rate_interval variables. The limit is absolute and not modified by the "Resolution" setting. } > Min step
Resolution
{showExemplarField && ( )} } /> ); } } export const testIds = { editor: 'prom-editor', exemplar: 'exemplar-editor', };