From c96b704af3e61095b9580f0b502309738be5adb4 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:02:37 +0200 Subject: [PATCH] Loki: Update log context UI (#66848) * Loki: Update log context UI * Update copy --- .../loki/components/LokiContextUi.test.tsx | 64 +++++++++++++++++-- .../loki/components/LokiContextUi.tsx | 31 ++++++--- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/public/app/plugins/datasource/loki/components/LokiContextUi.test.tsx b/public/app/plugins/datasource/loki/components/LokiContextUi.test.tsx index 0dc2ae6495b..eabc5968e5e 100644 --- a/public/app/plugins/datasource/loki/components/LokiContextUi.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiContextUi.test.tsx @@ -37,6 +37,10 @@ const setupProps = (): LokiContextUiProps => { }, } as unknown as LogRowModel, onClose: jest.fn(), + origQuery: { + expr: '{label1="value1"} | logfmt', + refId: 'A', + }, }; return defaults; @@ -78,7 +82,14 @@ describe('LokiContextUi', () => { it('renders and shows executed query text', async () => { const props = setupProps(); render(); - expect(await screen.findByText(/Executed log context query:/)).toBeInTheDocument(); + await waitFor(() => { + // We should see the query text (it is split into multiple spans) + expect(screen.getByText('{')).toBeInTheDocument(); + expect(screen.getByText('label1')).toBeInTheDocument(); + expect(screen.getByText('=')).toBeInTheDocument(); + expect(screen.getByText('"value1"')).toBeInTheDocument(); + expect(screen.getByText('}')).toBeInTheDocument(); + }); }); it('initialize context filters', async () => { @@ -139,10 +150,8 @@ describe('LokiContextUi', () => { it('displays executed query even if context ui closed', async () => { const props = setupProps(); render(); - // We start with the context ui open - expect(await screen.findByText(/Executed log context query:/)).toBeInTheDocument(); - // We click on it to close - await userEvent.click(screen.getByText(/Executed log context query:/)); + // We start with the context ui open and click on it to close + await userEvent.click(screen.getAllByRole('button')[0]); await waitFor(() => { // We should see the query text (it is split into multiple spans) expect(screen.getByText('{')).toBeInTheDocument(); @@ -152,4 +161,49 @@ describe('LokiContextUi', () => { expect(screen.getByText('}')).toBeInTheDocument(); }); }); + + it('does not show parsed labels section if origQuery has 0 parsers', async () => { + const props = setupProps(); + const newProps = { + ...props, + origQuery: { + expr: '{label1="value1"}', + refId: 'A', + }, + }; + render(); + await waitFor(() => { + expect(screen.queryByText('Refine the search')).not.toBeInTheDocument(); + }); + }); + + it('shows parsed labels section if origQuery has 1 parser', async () => { + const props = setupProps(); + const newProps = { + ...props, + origQuery: { + expr: '{label1="value1"} | logfmt', + refId: 'A', + }, + }; + render(); + await waitFor(() => { + expect(screen.getByText('Refine the search')).toBeInTheDocument(); + }); + }); + + it('does not show parsed labels section if origQuery has 2 parsers', async () => { + const props = setupProps(); + const newProps = { + ...props, + origQuery: { + expr: '{label1="value1"} | logfmt | json', + refId: 'A', + }, + }; + render(); + await waitFor(() => { + expect(screen.queryByText('Refine the search')).not.toBeInTheDocument(); + }); + }); }); diff --git a/public/app/plugins/datasource/loki/components/LokiContextUi.tsx b/public/app/plugins/datasource/loki/components/LokiContextUi.tsx index ba82209170d..61a32acf93e 100644 --- a/public/app/plugins/datasource/loki/components/LokiContextUi.tsx +++ b/public/app/plugins/datasource/loki/components/LokiContextUi.tsx @@ -4,12 +4,13 @@ import { useAsync } from 'react-use'; import { GrafanaTheme2, LogRowModel, SelectableValue } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; -import { Collapse, Label, LoadingPlaceholder, MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui'; +import { Collapse, Icon, Label, LoadingPlaceholder, MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui'; import store from 'app/core/store'; import { RawQuery } from '../../prometheus/querybuilder/shared/RawQuery'; import { LogContextProvider } from '../LogContextProvider'; import { escapeLabelValueInSelector } from '../languageUtils'; +import { isQueryWithParser } from '../queryUtils'; import { lokiGrammar } from '../syntax'; import { ContextFilter, LokiQuery } from '../types'; @@ -56,12 +57,18 @@ function getStyles(theme: GrafanaTheme2) { query: css` text-align: start; line-break: anywhere; - margin-top: ${theme.spacing(0.5)}; + margin-top: -${theme.spacing(0.25)}; `, ui: css` background-color: ${theme.colors.background.secondary}; padding: ${theme.spacing(2)}; `, + rawQuery: css` + display: inline; + `, + queryDescription: css` + margin-left: ${theme.spacing(0.5)}; + `, }; } @@ -155,6 +162,9 @@ export function LokiContextUi(props: LokiContextUiProps) { }; }, []); + // Currently we support adding of parser and showing parsed labels only if there is 1 parser + const showParsedLabels = origQuery && isQueryWithParser(origQuery.expr).parserCount === 1 && parsedLabels.length > 0; + return (
@@ -167,7 +177,6 @@ export function LokiContextUi(props: LokiContextUiProps) { }} label={
- enabled), origQuery )} + className={styles.rawQuery} /> + + +
} >
@@ -190,9 +203,9 @@ export function LokiContextUi(props: LokiContextUiProps) { {' '} - {parsedLabels.length > 0 && ( + {showParsedLabels && ( <>