import React, { FC, FormEvent, useEffect, useState } from 'react'; import { QueryEditorProps, SelectableValue } from '@grafana/data'; import { InlineField, InlineFieldRow, Input, Select, TextArea } from '@grafana/ui'; import { PrometheusDatasource } from '../datasource'; import { migrateVariableEditorBackToVariableSupport, migrateVariableQueryToEditor, } from '../migrations/variableMigration'; import { PromOptions, PromQuery, PromVariableQuery, PromVariableQueryType as QueryType } from '../types'; export const variableOptions = [ { label: 'Label names', value: QueryType.LabelNames }, { label: 'Label values', value: QueryType.LabelValues }, { label: 'Metrics', value: QueryType.MetricNames }, { label: 'Query result', value: QueryType.VarQueryResult }, { label: 'Series query', value: QueryType.SeriesQuery }, ]; export type Props = QueryEditorProps; const refId = 'PrometheusVariableQueryEditor-VariableQuery'; export const PromVariableQueryEditor: FC = ({ onChange, query, datasource }) => { // to select the query type, i.e. label_names, label_values, etc. const [qryType, setQryType] = useState(undefined); // list of variables for each function const [label, setLabel] = useState(''); // metric is used for both label_values() and metric() // label_values() metric requires a whole/complete metric // metric() is expected to be a part of a metric string const [metric, setMetric] = useState(''); // varQuery is a whole query, can include math/rates/etc const [varQuery, setVarQuery] = useState(''); // seriesQuery is only a whole const [seriesQuery, setSeriesQuery] = useState(''); // list of label names for label_values(), /api/v1/labels, contains the same results as label_names() function const [labelOptions, setLabelOptions] = useState>>([]); useEffect(() => { if (!query) { return; } // Changing from standard to custom variable editor changes the string attr from expr to query const variableQuery = query.query ? migrateVariableQueryToEditor(query.query) : query; setQryType(variableQuery.qryType); setLabel(variableQuery.label ?? ''); setMetric(variableQuery.metric ?? ''); setVarQuery(variableQuery.varQuery ?? ''); setSeriesQuery(variableQuery.seriesQuery ?? ''); // set the migrated label in the label options if (variableQuery.label) { setLabelOptions([{ label: variableQuery.label, value: variableQuery.label }]); } }, [query]); // set the label names options for the label values var query useEffect(() => { if (qryType !== QueryType.LabelValues) { return; } datasource.getLabelNames().then((labelNames: Array<{ text: string }>) => { setLabelOptions(labelNames.map(({ text }) => ({ label: text, value: text }))); }); }, [datasource, qryType]); const onChangeWithVariableString = (qryType: QueryType) => { const queryVar = { qryType: qryType, label, metric, varQuery, seriesQuery, refId: 'PrometheusVariableQueryEditor-VariableQuery', }; const queryString = migrateVariableEditorBackToVariableSupport(queryVar); onChange({ query: queryString, refId, }); }; const onQueryTypeChange = (newType: SelectableValue) => { setQryType(newType.value); if (newType.value === QueryType.LabelNames) { onChangeWithVariableString(newType.value); } }; const onLabelChange = (newLabel: SelectableValue) => { setLabel(newLabel.value ?? ''); }; const onMetricChange = (e: FormEvent) => { setMetric(e.currentTarget.value); }; const onVarQueryChange = (e: FormEvent) => { setVarQuery(e.currentTarget.value); }; const onSeriesQueryChange = (e: FormEvent) => { setSeriesQuery(e.currentTarget.value); }; const handleBlur = () => { if (qryType === QueryType.LabelNames) { onChangeWithVariableString(qryType); } else if (qryType === QueryType.LabelValues && label) { onChangeWithVariableString(qryType); } else if (qryType === QueryType.MetricNames && metric) { onChangeWithVariableString(qryType); } else if (qryType === QueryType.VarQueryResult && varQuery) { onChangeWithVariableString(qryType); } else if (qryType === QueryType.SeriesQuery && seriesQuery) { onChangeWithVariableString(qryType); } }; return ( The Prometheus data source plugin provides the following query types for template variables. } > Optional: returns a list of label values for the label name in the specified metric.} > )} {qryType === QueryType.MetricNames && ( <> Returns a list of metrics matching the specified metric regex.} > )} {qryType === QueryType.VarQueryResult && ( <> Returns a list of Prometheus query results for the query. This can include Prometheus functions, i.e. sum(go_goroutines). } >