Loki: Add functionality to revert to initial query in log context (#68484)

* Loki: Add functionality to revert to initial query

* Add tests and fix button in button

* Use usereven instead of fireEvent

* Shortern onClick

* Add feature tracking

* Use testid instead of title

* Always show revert button

* Remove unused imports
This commit is contained in:
Ivana Huckova 2023-05-16 18:58:25 +02:00 committed by GitHub
parent 14fb4ff779
commit 1462ae91da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 16 deletions

View File

@ -206,4 +206,33 @@ describe('LokiContextUi', () => {
expect(screen.queryByText('Refine the search')).not.toBeInTheDocument();
});
});
it('should revert to original query when revert button clicked', async () => {
const props = setupProps();
const newProps = {
...props,
origQuery: {
expr: '{label1="value1"} | logfmt',
refId: 'A',
},
};
render(<LokiContextUi {...newProps} />);
// In initial query, label3 is not selected
await waitFor(() => {
expect(screen.queryByText('label3="value3"')).not.toBeInTheDocument();
});
// We select parsed label and label3="value3" should appear
const parsedLabelsInput = screen.getAllByRole('combobox')[1];
await userEvent.click(parsedLabelsInput);
await userEvent.type(parsedLabelsInput, '{enter}');
expect(screen.getByText('label3="value3"')).toBeInTheDocument();
// We click on revert button and label3="value3" should disappear
const revertButton = screen.getByTestId('revert-button');
await userEvent.click(revertButton);
await waitFor(() => {
expect(screen.queryByText('label3="value3"')).not.toBeInTheDocument();
});
});
});

View File

@ -1,10 +1,10 @@
import { css } from '@emotion/css';
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useAsync } from 'react-use';
import { GrafanaTheme2, LogRowModel, SelectableValue } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Collapse, Icon, Label, MultiSelect, Tooltip, useStyles2 } from '@grafana/ui';
import { Button, Collapse, Icon, Label, MultiSelect, Spinner, Tooltip, useStyles2 } from '@grafana/ui';
import store from 'app/core/store';
import { RawQuery } from '../../prometheus/querybuilder/shared/RawQuery';
@ -33,6 +33,7 @@ function getStyles(theme: GrafanaTheme2) {
flex-direction: column;
flex: 1;
gap: ${theme.spacing(0.5)};
position: relative;
`,
textWrapper: css`
display: flex;
@ -50,10 +51,11 @@ function getStyles(theme: GrafanaTheme2) {
margin: ${theme.spacing(2)} 0;
}
`,
query: css`
rawQueryContainer: css`
text-align: start;
line-break: anywhere;
margin-top: -${theme.spacing(0.25)};
width: calc(100% - 20px);
`,
ui: css`
background-color: ${theme.colors.background.secondary};
@ -65,6 +67,12 @@ function getStyles(theme: GrafanaTheme2) {
queryDescription: css`
margin-left: ${theme.spacing(0.5)};
`,
iconButton: css`
position: absolute;
top: ${theme.spacing(1)};
right: ${theme.spacing(1)};
z-index: ${theme.zIndex.navbarFixed};
`,
};
}
@ -83,6 +91,16 @@ export function LokiContextUi(props: LokiContextUiProps) {
const timerHandle = React.useRef<number>();
const previousInitialized = React.useRef<boolean>(false);
const previousContextFilters = React.useRef<ContextFilter[]>([]);
const isInitialQuery = useMemo(() => {
// Initial query has all regular labels enabled and all parsed labels disabled
if (initialized && contextFilters.some((filter) => filter.fromParser === filter.enabled)) {
return false;
}
return true;
}, [contextFilters, initialized]);
useEffect(() => {
if (!initialized) {
return;
@ -163,6 +181,29 @@ export function LokiContextUi(props: LokiContextUiProps) {
return (
<div className={styles.wrapper}>
<Tooltip content={'Revert to initial log context query.'}>
<div className={styles.iconButton}>
<Button
data-testid="revert-button"
icon="history-alt"
variant="secondary"
disabled={isInitialQuery}
onClick={(e) => {
reportInteraction('grafana_explore_logs_loki_log_context_reverted', {
logRowUid: row.uid,
});
setContextFilters((contextFilters) => {
return contextFilters.map((contextFilter) => ({
...contextFilter,
// For revert to initial query we need to enable all labels and disable all parsed labels
enabled: !contextFilter.fromParser,
}));
});
}}
/>
</div>
</Tooltip>
<Collapse
collapsible={true}
isOpen={isOpen}
@ -175,7 +216,9 @@ export function LokiContextUi(props: LokiContextUiProps) {
});
}}
label={
<div className={styles.query}>
<div className={styles.rawQueryContainer}>
{initialized ? (
<>
<RawQuery
lang={{ grammar: lokiGrammar, name: 'loki' }}
query={logContextProvider.processContextFiltersToExpr(
@ -188,6 +231,10 @@ export function LokiContextUi(props: LokiContextUiProps) {
<Tooltip content="The initial log context query is created from all labels defining the stream for the selected log line. Use the editor below to customize the log context query.">
<Icon name="info-circle" size="sm" className={styles.queryDescription} />
</Tooltip>
</>
) : (
<Spinner />
)}
</div>
}
>