diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx index d3f728e9269..0f0cb89a91b 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx @@ -99,6 +99,25 @@ describe('LokiQueryBuilderOptions', () => { expect(screen.getByText('Type: Range')).toBeInTheDocument(); expect(screen.getByText('Step: 1m')).toBeInTheDocument(); }); + + it('shows correct options for metric query with invalid step', async () => { + setup({ expr: 'rate({foo="bar"}[5m]', step: 'abc' }); + expect(screen.queryByText('Line limit: 20')).not.toBeInTheDocument(); + expect(screen.getByText('Type: Range')).toBeInTheDocument(); + expect(screen.getByText('Step: Invalid value')).toBeInTheDocument(); + }); + + it('shows error when invalid value in step', async () => { + setup({ expr: 'rate({foo="bar"}[5m]', step: 'a' }); + await userEvent.click(screen.getByTitle('Click to edit options')); + expect(screen.getByText(/Invalid step/)).toBeInTheDocument(); + }); + + it('does not shows error when valid value in step', async () => { + setup({ expr: 'rate({foo="bar"}[5m]', step: '1m' }); + await userEvent.click(screen.getByTitle('Click to edit options')); + expect(screen.queryByText(/Invalid step/)).not.toBeInTheDocument(); + }); }); function setup(queryOverrides: Partial = {}) { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx index 47835e0d71b..3f05e160bea 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx @@ -1,5 +1,5 @@ import { trim } from 'lodash'; -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { CoreApp, isValidDuration, SelectableValue } from '@grafana/data'; import { EditorField, EditorRow } from '@grafana/experimental'; @@ -70,11 +70,18 @@ export const LokiQueryBuilderOptions = React.memo( const queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range); const isLogQuery = isLogsQuery(query.expr); + const isValidStep = useMemo(() => { + if (!query.step || isValidDuration(query.step) || !isNaN(Number(query.step))) { + return true; + } + return false; + }, [query.step]); + return ( ( ( } ); -function getCollapsedInfo(query: LokiQuery, queryType: LokiQueryType, maxLines: number, isLogQuery: boolean): string[] { +function getCollapsedInfo( + query: LokiQuery, + queryType: LokiQueryType, + maxLines: number, + isLogQuery: boolean, + isValidStep: boolean +): string[] { const queryTypeLabel = queryTypeOptions.find((x) => x.value === queryType); const resolutionLabel = RESOLUTION_OPTIONS.find((x) => x.value === (query.resolution ?? 1)); @@ -175,7 +190,7 @@ function getCollapsedInfo(query: LokiQuery, queryType: LokiQueryType, maxLines: if (!isLogQuery) { if (query.step) { - items.push(`Step: ${query.step}`); + items.push(`Step: ${isValidStep ? query.step : 'Invalid value'}`); } if (query.resolution) {