From eb781dd46d2c6ed99b0efc722ddb53ee322957e4 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Fri, 1 Nov 2024 15:32:17 +0000 Subject: [PATCH] Prometheus: Add Metrics Explorer button next to MetricCombobox (#95647) --- .../components/MetricCombobox.test.tsx | 28 ++++++++ .../components/MetricCombobox.tsx | 66 +++++++++++++++---- .../components/metrics-modal/MetricsModal.tsx | 8 ++- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.test.tsx b/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.test.tsx index 46a1396aaa3..4397d4104de 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.test.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.test.tsx @@ -2,7 +2,9 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; + import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { PrometheusDatasource } from '../../datasource'; import { PromOptions } from '../../types'; @@ -124,4 +126,30 @@ describe('MetricCombobox', () => { expect(mockOnChange).toHaveBeenCalledWith({ metric: 'random_metric', labels: [], operations: [] }); }); + + it("doesn't show the metrics explorer button by default", () => { + render(); + expect(screen.queryByRole('button', { name: /open metrics explorer/i })).not.toBeInTheDocument(); + }); + + describe('when metrics explorer toggle is enabled', () => { + beforeAll(() => { + jest.replaceProperty(config, 'featureToggles', { + prometheusMetricEncyclopedia: true, + }); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + + it('opens the metrics explorer when the button is clicked', async () => { + render( Promise.resolve([])} />); + + const button = screen.getByRole('button', { name: /open metrics explorer/i }); + await userEvent.click(button); + + expect(screen.getByText('Metrics explorer')).toBeInTheDocument(); + }); + }); }); diff --git a/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.tsx b/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.tsx index 796b794b6c3..26b55f30087 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/MetricCombobox.tsx @@ -1,14 +1,18 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { SelectableValue } from '@grafana/data'; -import { EditorField, EditorFieldGroup } from '@grafana/experimental'; -import { InlineField, InlineFieldRow, Combobox, ComboboxOption } from '@grafana/ui'; +import { EditorField, EditorFieldGroup, InputGroup } from '@grafana/experimental'; +import { config } from '@grafana/runtime'; +import { Button, InlineField, InlineFieldRow } from '@grafana/ui'; +import { Combobox, ComboboxOption } from '@grafana/ui/src/components/Combobox/Combobox'; import { PrometheusDatasource } from '../../datasource'; import { regexifyLabelValuesQueryString } from '../parsingUtils'; import { QueryBuilderLabelFilter } from '../shared/types'; import { PromVisualQuery } from '../types'; +import { MetricsModal } from './metrics-modal'; + export interface MetricComboboxProps { metricLookupDisabled: boolean; query: PromVisualQuery; @@ -28,6 +32,8 @@ export function MetricCombobox({ labelsFilters, variableEditor, }: Readonly) { + const [metricsModalOpen, setMetricsModalOpen] = useState(false); + /** * Gets label_values response from prometheus API for current autocomplete query string and any existing labels filters */ @@ -65,21 +71,59 @@ export function MetricCombobox({ [getMetricLabels, onGetMetrics] ); + const loadMetricsExplorerMetrics = useCallback(async () => { + const allMetrics = await onGetMetrics(); + const metrics: string[] = []; + for (const metric of allMetrics) { + if (metric.value) { + metrics.push(metric.value); + } + } + + return metrics; + }, [onGetMetrics]); + + const metricsExplorerEnabled = config.featureToggles.prometheusMetricEncyclopedia; + const asyncSelect = () => { return ( - + + + + {metricsExplorerEnabled ? ( +