Prometheus: fix labels infinite loading state in aggregations (#103005)

* fix labels in aggregation

* use timerange from props

* fix tests and lint

* fix lint
This commit is contained in:
Gareth Dawson
2025-04-07 18:40:48 +02:00
committed by GitHub
parent 369dc28ca2
commit a494c5dd3d
6 changed files with 15 additions and 7 deletions
@@ -1,7 +1,7 @@
// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx // Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx
import { useState } from 'react'; import { useState } from 'react';
import { DataSourceApi, SelectableValue, toOption } from '@grafana/data'; import { DataSourceApi, SelectableValue, TimeRange, toOption } from '@grafana/data';
import { Select } from '@grafana/ui'; import { Select } from '@grafana/ui';
import { promQueryModeller } from '../PromQueryModeller'; import { promQueryModeller } from '../PromQueryModeller';
@@ -16,6 +16,7 @@ export function LabelParamEditor({
value, value,
query, query,
datasource, datasource,
timeRange,
}: QueryBuilderOperationParamEditorProps) { }: QueryBuilderOperationParamEditorProps) {
const [state, setState] = useState<{ const [state, setState] = useState<{
options?: SelectableValue[]; options?: SelectableValue[];
@@ -29,7 +30,7 @@ export function LabelParamEditor({
openMenuOnFocus openMenuOnFocus
onOpenMenu={async () => { onOpenMenu={async () => {
setState({ isLoading: true }); setState({ isLoading: true });
const options = await loadGroupByLabels(query, datasource); const options = await loadGroupByLabels(timeRange, query, datasource);
setState({ options, isLoading: undefined }); setState({ options, isLoading: undefined });
}} }}
isLoading={state.isLoading} isLoading={state.isLoading}
@@ -43,7 +44,11 @@ export function LabelParamEditor({
); );
} }
async function loadGroupByLabels(query: PromVisualQuery, datasource: DataSourceApi): Promise<SelectableValue[]> { async function loadGroupByLabels(
timeRange: TimeRange,
query: PromVisualQuery,
datasource: DataSourceApi
): Promise<SelectableValue[]> {
let labels: QueryBuilderLabelFilter[] = query.labels; let labels: QueryBuilderLabelFilter[] = query.labels;
// This function is used by both Prometheus and Loki and this the only difference. // This function is used by both Prometheus and Loki and this the only difference.
@@ -52,7 +57,7 @@ async function loadGroupByLabels(query: PromVisualQuery, datasource: DataSourceA
} }
const expr = promQueryModeller.renderLabels(labels); const expr = promQueryModeller.renderLabels(labels);
const result = await datasource.languageProvider.fetchLabelsWithMatch(expr); const result = await datasource.languageProvider.fetchLabelsWithMatch(timeRange, expr);
return Object.keys(result).map((x) => ({ return Object.keys(result).map((x) => ({
label: x, label: x,
@@ -84,6 +84,7 @@ export const PromQueryBuilder = memo<PromQueryBuilderProps>((props) => {
onChange={onChange} onChange={onChange}
onRunQuery={onRunQuery} onRunQuery={onRunQuery}
highlightedOp={highlightedOp} highlightedOp={highlightedOp}
timeRange={data?.timeRange ?? getDefaultTimeRange()}
/> />
<div data-testid={selectors.components.DataSource.Prometheus.queryEditor.builder.hints}> <div data-testid={selectors.components.DataSource.Prometheus.queryEditor.builder.hints}>
<QueryBuilderHints<PromVisualQuery> <QueryBuilderHints<PromVisualQuery>
@@ -30,7 +30,7 @@ export interface Props {
onRunQuery: () => void; onRunQuery: () => void;
flash?: boolean; flash?: boolean;
highlight?: boolean; highlight?: boolean;
timeRange?: TimeRange; timeRange: TimeRange;
} }
export function OperationEditor({ export function OperationEditor({
@@ -7,6 +7,7 @@ import { DataSourceApi, DataSourceInstanceSettings } from '@grafana/data';
import { PrometheusDatasource } from '../../datasource'; import { PrometheusDatasource } from '../../datasource';
import PromQlLanguageProvider from '../../language_provider'; import PromQlLanguageProvider from '../../language_provider';
import { EmptyLanguageProviderMock } from '../../language_provider.mock'; import { EmptyLanguageProviderMock } from '../../language_provider.mock';
import { getMockTimeRange } from '../../test/__mocks__/datasource';
import { PromOptions } from '../../types'; import { PromOptions } from '../../types';
import { promQueryModeller } from '../PromQueryModeller'; import { promQueryModeller } from '../PromQueryModeller';
import { addOperationInQueryBuilder } from '../testUtils'; import { addOperationInQueryBuilder } from '../testUtils';
@@ -78,6 +79,7 @@ function setup(query: PromVisualQuery = defaultQuery) {
onRunQuery: () => {}, onRunQuery: () => {},
onChange: jest.fn(), onChange: jest.fn(),
queryModeller: promQueryModeller, queryModeller: promQueryModeller,
timeRange: getMockTimeRange(),
}; };
render(<OperationList {...props} query={query} />); render(<OperationList {...props} query={query} />);
@@ -18,7 +18,7 @@ export interface Props<T extends QueryWithOperations> {
queryModeller: VisualQueryModeller; queryModeller: VisualQueryModeller;
explainMode?: boolean; explainMode?: boolean;
highlightedOp?: QueryBuilderOperation; highlightedOp?: QueryBuilderOperation;
timeRange?: TimeRange; timeRange: TimeRange;
} }
export function OperationList<T extends QueryWithOperations>({ export function OperationList<T extends QueryWithOperations>({
@@ -92,7 +92,7 @@ export interface QueryBuilderOperationParamEditorProps {
operationId: string; operationId: string;
query: any; query: any;
datasource: DataSourceApi; datasource: DataSourceApi;
timeRange?: TimeRange; timeRange: TimeRange;
onChange: (index: number, value: QueryBuilderOperationParamValue) => void; onChange: (index: number, value: QueryBuilderOperationParamValue) => void;
onRunQuery: () => void; onRunQuery: () => void;
} }