OpenTSDB: Allow metric autocomplete to use suggest api on every input (#62045)

* allow metric autocomplete by suggest api

* debounce sugggest metrics

* debounce sugggest metrics with debounce-promise

* commit for tests
This commit is contained in:
Brendan O'Handley
2023-02-02 17:46:22 -05:00
committed by GitHub
parent 1694a35e0c
commit 70c1850888
2 changed files with 11 additions and 32 deletions

View File

@@ -1,7 +1,8 @@
import React, { useCallback, useState } from 'react';
import debounce from 'debounce-promise';
import React from 'react';
import { SelectableValue, toOption } from '@grafana/data';
import { Select, Input, InlineFormLabel } from '@grafana/ui';
import { Select, Input, InlineFormLabel, AsyncSelect } from '@grafana/ui';
import { OpenTsdbQuery } from '../types';
@@ -9,26 +10,13 @@ export interface MetricSectionProps {
query: OpenTsdbQuery;
onChange: (query: OpenTsdbQuery) => void;
onRunQuery: () => void;
suggestMetrics: () => Promise<SelectableValue[]>;
suggestMetrics: (value: string) => Promise<SelectableValue[]>;
aggregators: string[];
}
export function MetricSection({ query, onChange, onRunQuery, suggestMetrics, aggregators }: MetricSectionProps) {
const [state, setState] = useState<{
metrics?: Array<SelectableValue<string>>;
isLoading?: boolean;
}>({});
// We are matching words split with space
const splitSeparator = ' ';
const customFilterOption = useCallback((option: SelectableValue<string>, searchQuery: string) => {
const label = option.value ?? '';
const searchWords = searchQuery.split(splitSeparator);
return searchWords.reduce((acc, cur) => acc && label.toLowerCase().includes(cur.toLowerCase()), true);
}, []);
const aggregatorOptions = aggregators.map((value: string) => toOption(value));
const metricSearch = debounce((query: string) => suggestMetrics(query), 350);
return (
<div className="gf-form-inline" data-testid={testIds.section}>
@@ -36,23 +24,16 @@ export function MetricSection({ query, onChange, onRunQuery, suggestMetrics, agg
<InlineFormLabel width={8} className="query-keyword">
Metric
</InlineFormLabel>
<Select
{/* metric async select: autocomplete calls opentsdb suggest API */}
<AsyncSelect
width={25}
inputId="opentsdb-metric-select"
className="gf-form-input"
value={query.metric ? toOption(query.metric) : undefined}
placeholder="Metric name"
allowCustomValue
filterOption={customFilterOption}
onOpenMenu={async () => {
if (!state.metrics) {
setState({ isLoading: true });
const metrics = await suggestMetrics();
setState({ metrics, isLoading: undefined });
}
}}
isLoading={state.isLoading}
options={state.metrics}
loadOptions={metricSearch}
defaultOptions={[]}
onChange={({ value }) => {
if (value) {
onChange({ ...query, metric: value });

View File

@@ -74,10 +74,8 @@ export function OpenTsdbQueryEditor({
}
});
// previously called as an autocomplete on every input,
// in this we call it once on init and filter in the MetricSection component
async function suggestMetrics(): Promise<Array<{ value: string; description: string }>> {
return datasource.metricFindQuery('metrics()').then(getTextValues);
async function suggestMetrics(value: string): Promise<Array<{ value: string; description: string }>> {
return datasource.metricFindQuery(`metrics(${value})`).then(getTextValues);
}
// previously called as an autocomplete on every input,