From 10eb8aeeee1ab14b6ca3c3ff1a553bc6663dfba7 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Wed, 16 Apr 2025 08:36:23 +0200 Subject: [PATCH] Prometheus: Remove /series endpoint usage from Metrics Browser (#101705) * convert it to functional component * useReducer * usePromQueryFieldEffects * clean up the code * remove localStorage provider * introduce usePromQueryFieldEffects.test.ts * simpler state management * remove mocks * linting + betterer * Split PrometheusMetricsBrowser into small functional components * remove /series endpoint usages for Metrics Browser * add time ranges * remove unused file * fix unit test * use limit * re-fetch labels when a label value is selected * reset the label keys when selector is empty * select multiple labelValue * fix unit tests * add comments * don't show unpresented labelKeys * don't clear out selected label keys that are in local storage * show values properly * fix clearing * don't discard already selected label values when a new label value selected * remove unnecessary unit test * clear all selections * if metrics list is empty remove all label keys too * re-populate values when all label selections are removed * safety * more comments * updating the whole fetching mechanism * buildSafeSelector * loadSelectedLabelsFromStorage * fetchMetrics * fetchLabelKeys * fetchLabelValues * more unit test and comment * timeRange changes will trigger re-fetch * some more comments * fix the unit test * lint * fix unit tests * fix timerange causing problem * remove fethcing message * proper initialization * fix value fetching during metric selection * fix value fetching * fix unit tests * fix a bug * comments * some precaution * fix the test * fetch metrics when metric selection is changed * trigger initialize when seriesLimit is change * Revert "trigger initialize when seriesLimit is change" This reverts commit c6cbbc138634c722ee1adbb9c8dabb3fa8819e52. * remove redundant comments --- .../src/components/PromQueryField.tsx | 11 +- .../metrics-browser/LabelSelector.tsx | 54 +- .../metrics-browser/MetricSelector.tsx | 63 +- .../metrics-browser/MetricsBrowser.tsx | 27 + .../MetricsBrowserContext.test.tsx | 507 ++++++++++ .../metrics-browser/MetricsBrowserContext.tsx | 155 +++ .../PrometheusMetricsBrowser.test.tsx | 232 ----- .../PrometheusMetricsBrowser.tsx | 373 -------- .../metrics-browser/SelectorActions.tsx | 55 +- .../metrics-browser/ValueSelector.tsx | 113 +-- .../metrics-browser/selectorBuilder.test.ts | 479 ++-------- .../metrics-browser/selectorBuilder.ts | 95 +- .../src/components/metrics-browser/styles.ts | 84 +- .../src/components/metrics-browser/types.ts | 36 +- .../useMetricsLabelsValues.test.ts | 904 ++++++++++++++++++ .../metrics-browser/useMetricsLabelsValues.ts | 384 ++++++++ packages/grafana-prometheus/src/index.ts | 2 +- .../src/language_provider.ts | 36 +- 18 files changed, 2299 insertions(+), 1311 deletions(-) create mode 100644 packages/grafana-prometheus/src/components/metrics-browser/MetricsBrowser.tsx create mode 100644 packages/grafana-prometheus/src/components/metrics-browser/MetricsBrowserContext.test.tsx create mode 100644 packages/grafana-prometheus/src/components/metrics-browser/MetricsBrowserContext.tsx delete mode 100644 packages/grafana-prometheus/src/components/metrics-browser/PrometheusMetricsBrowser.test.tsx delete mode 100644 packages/grafana-prometheus/src/components/metrics-browser/PrometheusMetricsBrowser.tsx create mode 100644 packages/grafana-prometheus/src/components/metrics-browser/useMetricsLabelsValues.test.ts create mode 100644 packages/grafana-prometheus/src/components/metrics-browser/useMetricsLabelsValues.ts diff --git a/packages/grafana-prometheus/src/components/PromQueryField.tsx b/packages/grafana-prometheus/src/components/PromQueryField.tsx index b92a3c77a98..1e13895b50b 100644 --- a/packages/grafana-prometheus/src/components/PromQueryField.tsx +++ b/packages/grafana-prometheus/src/components/PromQueryField.tsx @@ -12,7 +12,8 @@ import { getInitHints } from '../query_hints'; import { PromOptions, PromQuery } from '../types'; import { CancelablePromise, isCancelablePromiseRejection, makePromiseCancelable } from './cancelable-promise'; -import { PrometheusMetricsBrowser } from './metrics-browser/PrometheusMetricsBrowser'; +import { MetricsBrowser } from './metrics-browser/MetricsBrowser'; +import { MetricsBrowserProvider } from './metrics-browser/MetricsBrowserContext'; import { MonacoQueryFieldWrapper } from './monaco-query-field/MonacoQueryFieldWrapper'; import { useMetricsState } from './useMetricsState'; import { usePromQueryFieldEffects } from './usePromQueryFieldEffects'; @@ -172,11 +173,13 @@ export const PromQueryField = (props: PromQueryFieldProps) => { {labelBrowserVisible && (
- + > + +
)} {ExtraFieldElement} diff --git a/packages/grafana-prometheus/src/components/metrics-browser/LabelSelector.tsx b/packages/grafana-prometheus/src/components/metrics-browser/LabelSelector.tsx index 780150b7cfa..06c511f5f5e 100644 --- a/packages/grafana-prometheus/src/components/metrics-browser/LabelSelector.tsx +++ b/packages/grafana-prometheus/src/components/metrics-browser/LabelSelector.tsx @@ -1,25 +1,23 @@ -import { ChangeEvent, MouseEvent } from 'react'; +import { useMemo, useState } from 'react'; import { selectors } from '@grafana/e2e-selectors'; -import { Input, Label, BrowserLabel as PromLabel } from '@grafana/ui'; +import { BrowserLabel as PromLabel, Input, Label, useStyles2 } from '@grafana/ui'; -import { SelectableLabel } from './types'; +import { useMetricsBrowser } from './MetricsBrowserContext'; +import { getStylesLabelSelector } from './styles'; +import { METRIC_LABEL } from './types'; -interface LabelSelectorProps { - nonMetricLabels: SelectableLabel[]; - labelSearchTerm: string; - onChangeLabelSearch: (event: ChangeEvent) => void; - onClickLabel: (name: string, value: string | undefined, event: MouseEvent) => void; - styles: Record; -} +export function LabelSelector() { + const styles = useStyles2(getStylesLabelSelector); + const [labelSearchTerm, setLabelSearchTerm] = useState(''); + const { labelKeys, selectedLabelKeys, onLabelKeyClick } = useMetricsBrowser(); + + const filteredLabelKeys = useMemo(() => { + return labelKeys.filter( + (lk) => lk !== METRIC_LABEL && (selectedLabelKeys.includes(lk) || lk.includes(labelSearchTerm)) + ); + }, [labelKeys, labelSearchTerm, selectedLabelKeys]); -export function LabelSelector({ - nonMetricLabels, - labelSearchTerm, - onChangeLabelSearch, - onClickLabel, - styles, -}: LabelSelectorProps) { return (
setLabelSearchTerm(e.currentTarget.value)} aria-label="Filter expression for label" value={labelSearchTerm} data-testid={selectors.components.DataSource.Prometheus.queryEditor.code.metricsBrowser.labelNamesFilter} @@ -35,15 +33,19 @@ export function LabelSelector({
{/* Using fixed height here to prevent jumpy layout */}
- {nonMetricLabels.map((label) => ( + {filteredLabelKeys.map((label) => (