From 750630626ed526512b2718ed092c644cc58d2202 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:24:01 +0200 Subject: [PATCH] Loki: Add step input field validation (#70319) * Loki: Add step inpout field validation * Show invalid step in Options * Update public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx Co-authored-by: Matias Chomicki * Update test --------- Co-authored-by: Matias Chomicki --- .../LokiQueryBuilderOptions.test.tsx | 19 +++++++++++++++ .../components/LokiQueryBuilderOptions.tsx | 23 +++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) 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) {