diff --git a/.betterer.results b/.betterer.results
index 567cc847348..b1d89314506 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -7562,10 +7562,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
- "public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx:5381": [
- [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
- [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
- ],
"public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx
index 2079db28001..08cfd3bd16d 100644
--- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx
+++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx
@@ -2,10 +2,13 @@ import { render, screen, getAllByRole, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
+import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data';
+
import { LokiDatasource } from '../../datasource';
import { LokiOperationId, LokiVisualQuery } from '../types';
import { LokiQueryBuilder } from './LokiQueryBuilder';
+import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained';
const defaultQuery: LokiVisualQuery = {
labels: [{ op: '=', label: 'baz', value: 'bar' }],
@@ -17,8 +20,8 @@ const createDefaultProps = () => {
{
url: '',
jsonData: {},
- meta: {} as any,
- } as any,
+ meta: {} as DataSourcePluginMeta,
+ } as DataSourceInstanceSettings,
undefined,
undefined
);
@@ -66,4 +69,30 @@ describe('LokiQueryBuilder', () => {
).not.toBeInTheDocument();
});
});
+ it('shows explain section when showExplain is true', async () => {
+ const query = {
+ labels: [{ label: 'foo', op: '=', value: 'bar' }],
+ operations: [{ id: LokiOperationId.LineContains, params: ['error'] }],
+ };
+ const props = createDefaultProps();
+ props.showExplain = true;
+ props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
+
+ render();
+ expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument();
+ });
+
+ it('does not shows explain section when showExplain is false', async () => {
+ const query = {
+ labels: [{ label: 'foo', op: '=', value: 'bar' }],
+ operations: [{ id: LokiOperationId.LineContains, params: ['error'] }],
+ };
+ const props = createDefaultProps();
+ props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
+
+ render();
+ await waitFor(() => {
+ expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument();
+ });
+ });
});
diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx
index 634cd538c6e..5b04f7476e7 100644
--- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx
+++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx
@@ -21,6 +21,7 @@ import { lokiQueryModeller } from '../LokiQueryModeller';
import { buildVisualQueryFromString } from '../parsing';
import { LokiOperationId, LokiVisualQuery } from '../types';
+import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained';
import { NestedQueryList } from './NestedQueryList';
export interface Props {
@@ -119,7 +120,7 @@ export const LokiQueryBuilder = React.memo(({ datasource, query, onChange
stepNumber={1}
title={}
>
- Fetch all log lines matching label filters.
+ {EXPLAIN_LABEL_FILTER_CONTENT}
)}
diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx
index d78caf86006..ab5ee6552be 100644
--- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx
+++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx
@@ -10,6 +10,8 @@ import { lokiQueryModeller } from '../LokiQueryModeller';
import { buildVisualQueryFromString } from '../parsing';
import { LokiVisualQuery } from '../types';
+export const EXPLAIN_LABEL_FILTER_CONTENT = 'Fetch all log lines matching label filters.';
+
export interface Props {
query: string;
}
@@ -24,7 +26,7 @@ export const LokiQueryBuilderExplained = React.memo(({ query }) => {
stepNumber={1}
title={}
>
- Fetch all log lines matching label filters.
+ {EXPLAIN_LABEL_FILTER_CONTENT}
stepNumber={2}
diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx
new file mode 100644
index 00000000000..1df52e41bf4
--- /dev/null
+++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.test.tsx
@@ -0,0 +1,53 @@
+import { render, screen } from '@testing-library/react';
+import React from 'react';
+
+import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data';
+
+import { LokiDatasource } from '../../datasource';
+import { LokiQuery } from '../../types';
+
+import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained';
+import { LokiQueryCodeEditor } from './LokiQueryCodeEditor';
+
+const defaultQuery: LokiQuery = {
+ expr: '{job="bar}',
+ refId: 'A',
+};
+
+const createDefaultProps = () => {
+ const datasource = new LokiDatasource(
+ {
+ url: '',
+ jsonData: {},
+ meta: {} as DataSourcePluginMeta,
+ } as DataSourceInstanceSettings,
+ undefined,
+ undefined
+ );
+
+ const props = {
+ datasource,
+ onRunQuery: () => {},
+ onChange: () => {},
+ showExplain: false,
+ };
+
+ return props;
+};
+
+describe('LokiQueryCodeEditor', () => {
+ it('shows explain section when showExplain is true', () => {
+ const props = createDefaultProps();
+ props.showExplain = true;
+ props.datasource.metadataRequest = jest.fn().mockResolvedValue([]);
+ render();
+ expect(screen.getByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument();
+ });
+
+ it('does not shows explain section when showExplain is true', () => {
+ const props = createDefaultProps();
+ props.datasource.metadataRequest = jest.fn().mockResolvedValue([]);
+ render();
+ expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument();
+ });
+});
diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx
index 21d28feaad7..b449576353d 100644
--- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx
+++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx
@@ -8,6 +8,7 @@ import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/
import { LokiDatasource } from '../../datasource';
import { LokiQuery, LokiQueryType } from '../../types';
+import { EXPLAIN_LABEL_FILTER_CONTENT } from './LokiQueryBuilderExplained';
import { LokiQueryEditorSelector } from './LokiQueryEditorSelector';
jest.mock('@grafana/runtime', () => {
@@ -117,6 +118,13 @@ describe('LokiQueryEditorSelector', () => {
expect(selector.textContent).toBe('{job="grafana"}');
});
+ it('Can enable explain', async () => {
+ renderWithMode(QueryEditorMode.Builder);
+ expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument();
+ screen.getByLabelText('Explain').click();
+ expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument();
+ });
+
it('changes to code mode', async () => {
const { onChange } = renderWithMode(QueryEditorMode.Builder);
await switchToMode(QueryEditorMode.Code);