Files
grafana/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditorAutocompleteInfo.tsx
T
Nick Richmond 559fab9dc6 Prometheus: Fuzzy search for metric names in Code Mode (#85396)
* perf: limit metric names in Code Mode suggestions

* feat: configurable metric names limit

* feat: code mode autocomplete info/disclaimer

* chore: put new functionality behind new feature toggle

* refactor: avoid type assertions

* refactor: avoid explicit `any`

refactor: type guards

* refactor: type guards

* chore: add testdata results

* fix: add missing feature toggle guard

* perf: prefer array access to `Array.prototype.at`

* test: add missing config override

* test: refactor for brevity & clarity

* perf: avoid unnecessary mapping

* chore: undo testdata changes

* fix: use correct limit; perf optimizations

* refactor: avoid unnecessary `async`s

* types: simplify

* test: add missing tests

* fix: avoid hardcoding

* test: update mock path

* docs: fix typo

style: remove formatting artifact

style: remove formatting artifact

style: remove formatting artifact

* fix: event scope regression

* style: refactor for clarity

* refactor: prefer `useCallback` to in-effect handler

* refactor: simplify & broaden `filter`

* refactor: rename file to keep with conventions

* chore: mirror Prometheus package changes in app

* refactor: prefer no `@ts-ignore`

* chore: update betterer results

* docs: use type in TSDoc `@link` without `@ts-ignore`

* test: add missing provider

* test: fix jest mock path

* fix: display disclaimer in empty input case
2024-04-04 23:38:23 +03:00

70 lines
2.3 KiB
TypeScript

import React, { useState, useEffect, useCallback } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { config } from '@grafana/runtime';
import { IconButton, Text, Stack } from '@grafana/ui';
import {
CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT,
isSuggestionsIncompleteEvent,
} from '../../components/monaco-query-field/monaco-completion-provider/data_provider';
import { PromQueryEditorProps } from '../../components/types';
import { QueryEditorMode } from '../shared/types';
interface Props {
datasourceUid: PromQueryEditorProps['datasource']['uid'];
editorMode: QueryEditorMode;
}
export function PromQueryCodeEditorAutocompleteInfo(props: Readonly<Props>) {
const [autocompleteLimit, setAutocompleteLimit] = useState('n');
const [autocompleteLimitExceeded, setAutocompleteLimitExceeded] = useState(false);
const handleSuggestionsIncompleteEvent = useCallback(
(e: Event) => {
if (!isSuggestionsIncompleteEvent(e)) {
return;
}
if (e.detail.datasourceUid === props.datasourceUid) {
setAutocompleteLimitExceeded(true);
setAutocompleteLimit(e.detail.limit.toString());
}
},
[props.datasourceUid]
);
useEffect(() => {
addEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent);
return () => {
removeEventListener(CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT, handleSuggestionsIncompleteEvent);
};
}, [handleSuggestionsIncompleteEvent]);
const showCodeModeAutocompleteDisclaimer = (): boolean => {
return (
Boolean(config.featureToggles.prometheusCodeModeMetricNamesSearch) &&
props.editorMode === QueryEditorMode.Code &&
autocompleteLimitExceeded
);
};
if (!showCodeModeAutocompleteDisclaimer()) {
return null;
}
return (
<div data-testid={selectors.components.DataSource.Prometheus.queryEditor.code.metricsCountInfo}>
<Stack direction="row" gap={1}>
<Text color="secondary" element="p" italic={true}>
Autocomplete suggestions limited
</Text>
<IconButton
name="info-circle"
tooltip={`The number of metric names exceeds the autocomplete limit. Only the ${autocompleteLimit}-most relevant metrics are displayed. You can adjust the threshold in the data source settings.`}
/>
</Stack>
</div>
);
}