Glue: Hide run queries button in Correlations Page (#61039)

* Hide run queries button in Correlations Page when showing Loki and Prometheus editors

* Use more semantic selectors

Co-authored-by: Giordano Ricci <me@giordanoricci.com>

* Use more semantic selectors

Co-authored-by: Giordano Ricci <me@giordanoricci.com>

* Post-merge fix (remove duplicate)

Co-authored-by: Giordano Ricci <me@giordanoricci.com>
This commit is contained in:
Piotr Jamróz 2023-01-12 21:14:55 +01:00 committed by GitHub
parent 49ae1bbe63
commit e8ef0395b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 13 deletions

View File

@ -13,10 +13,10 @@ export enum CoreApp {
UnifiedAlerting = 'unified-alerting',
Dashboard = 'dashboard',
Explore = 'explore',
Correlations = 'correlations',
Unknown = 'unknown',
PanelEditor = 'panel-editor',
PanelViewer = 'panel-viewer',
Correlations = 'correlations',
}
export interface AppRootProps<T extends KeyValue = KeyValue> {

View File

@ -130,6 +130,7 @@ export const QueryEditorField = ({ dsUid, invalid, error, name }: Props) => {
return (
<>
<QueryEditor
app={CoreApp.Correlations}
onRunQuery={() => handleValidation(value)}
onChange={(value) => {
setIsValidQuery(undefined);

View File

@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
import { cloneDeep, defaultsDeep } from 'lodash';
import React from 'react';
import { CoreApp } from '@grafana/data';
import { config } from '@grafana/runtime';
import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types';
@ -11,6 +12,7 @@ import { EXPLAIN_LABEL_FILTER_CONTENT } from '../querybuilder/components/LokiQue
import { LokiQuery, LokiQueryType } from '../types';
import { LokiQueryEditor } from './LokiQueryEditor';
import { LokiQueryEditorProps } from './types';
jest.mock('@grafana/runtime', () => {
return {
@ -19,6 +21,15 @@ jest.mock('@grafana/runtime', () => {
};
});
// We need to mock this because it seems jest has problem importing monaco in tests
jest.mock('./monaco-query-field/MonacoQueryFieldWrapper', () => {
return {
MonacoQueryFieldWrapper: () => {
return 'MonacoQueryFieldWrapper';
},
};
});
jest.mock('app/core/store', () => {
return {
get() {
@ -82,6 +93,21 @@ describe('LokiQueryEditorSelector', () => {
await expectBuilder();
});
it('shows Run Queries button in Dashboards', () => {
renderWithProps({}, { app: CoreApp.Dashboard });
expectRunQueriesButton();
});
it('hides Run Queries button in Explore', async () => {
renderWithProps({}, { app: CoreApp.Explore });
expectNoRunQueriesButton();
});
it('hides Run Queries button in Correlations Page', async () => {
renderWithProps({}, { app: CoreApp.Correlations });
await expectNoRunQueriesButton();
});
it('changes to builder mode', async () => {
const { onChange } = renderWithMode(QueryEditorMode.Code);
await expectCodeEditor();
@ -160,23 +186,31 @@ function renderWithMode(mode: QueryEditorMode) {
return renderWithProps({ editorMode: mode });
}
function renderWithProps(overrides?: Partial<LokiQuery>) {
function renderWithProps(overrides?: Partial<LokiQuery>, componentProps: Partial<LokiQueryEditorProps> = {}) {
const query = defaultsDeep(overrides ?? {}, cloneDeep(defaultQuery));
const onChange = jest.fn();
const stuff = render(<LokiQueryEditor {...defaultProps} query={query} onChange={onChange} />);
const allProps = { ...defaultProps, ...componentProps };
const stuff = render(<LokiQueryEditor {...allProps} query={query} onChange={onChange} />);
return { onChange, ...stuff };
}
async function expectCodeEditor() {
// Label browser shows this until log labels are loaded.
expect(await screen.findByText('Loading...')).toBeInTheDocument();
expect(await screen.findByText('MonacoQueryFieldWrapper')).toBeInTheDocument();
}
async function expectBuilder() {
expect(await screen.findByText('Label filters')).toBeInTheDocument();
}
function expectRunQueriesButton() {
expect(screen.getByRole('button', { name: /run queries/i })).toBeInTheDocument();
}
function expectNoRunQueriesButton() {
expect(screen.queryByRole('button', { name: /run queries/i })).not.toBeInTheDocument();
}
async function switchToMode(mode: QueryEditorMode) {
const label = {
[QueryEditorMode.Code]: /Code/,

View File

@ -138,7 +138,7 @@ export const LokiQueryEditor = React.memo<LokiQueryEditorProps>((props) => {
</Stack>
<QueryHeaderSwitch label="Explain query" value={explain} onChange={onExplainChange} />
<FlexItem grow={1} />
{app !== CoreApp.Explore && (
{app !== CoreApp.Explore && app !== CoreApp.Correlations && (
<Button
variant={dataIsStale ? 'primary' : 'secondary'}
size="sm"

View File

@ -3,6 +3,9 @@ import userEvent from '@testing-library/user-event';
import { cloneDeep, defaultsDeep } from 'lodash';
import React from 'react';
import { CoreApp } from '@grafana/data';
import { PromQueryEditorProps } from '../../components/types';
import { PrometheusDatasource } from '../../datasource';
import PromQlLanguageProvider from '../../language_provider';
import { EmptyLanguageProviderMock } from '../../language_provider.mock';
@ -79,11 +82,26 @@ describe('PromQueryEditorSelector', () => {
expectCodeEditor();
});
it('shows builder when builder mode is set', async () => {
it('shows builder when builder mode is set', () => {
renderWithMode(QueryEditorMode.Builder);
expectBuilder();
});
it('shows Run Queries button in Dashboards', () => {
renderWithProps({}, { app: CoreApp.Dashboard });
expectRunQueriesButton();
});
it('hides Run Queries button in Explore', () => {
renderWithProps({}, { app: CoreApp.Explore });
expectNoRunQueriesButton();
});
it('hides Run Queries button in Correlations Page', () => {
renderWithProps({}, { app: CoreApp.Correlations });
expectNoRunQueriesButton();
});
it('changes to builder mode', async () => {
const { onChange } = renderWithMode(QueryEditorMode.Code);
await switchToMode(QueryEditorMode.Builder);
@ -150,23 +168,30 @@ function renderWithMode(mode: QueryEditorMode) {
return renderWithProps({ editorMode: mode } as any);
}
function renderWithProps(overrides?: Partial<PromQuery>) {
function renderWithProps(overrides?: Partial<PromQuery>, componentProps: Partial<PromQueryEditorProps> = {}) {
const query = defaultsDeep(overrides ?? {}, cloneDeep(defaultQuery));
const onChange = jest.fn();
const stuff = render(<PromQueryEditorSelector {...defaultProps} query={query} onChange={onChange} />);
const allProps = { ...defaultProps, ...componentProps };
const stuff = render(<PromQueryEditorSelector {...allProps} query={query} onChange={onChange} />);
return { onChange, ...stuff };
}
function expectCodeEditor() {
// Metric browser shows this until metrics are loaded.
expect(screen.getByText('Loading metrics...')).toBeInTheDocument();
expect(screen.getByText('MonacoQueryFieldWrapper')).toBeInTheDocument();
}
function expectBuilder() {
expect(screen.getByText('Metric')).toBeInTheDocument();
}
function expectRunQueriesButton() {
expect(screen.getByRole('button', { name: /run queries/i })).toBeInTheDocument();
}
function expectNoRunQueriesButton() {
expect(screen.queryByRole('button', { name: /run queries/i })).not.toBeInTheDocument();
}
async function switchToMode(mode: QueryEditorMode) {
const label = {
[QueryEditorMode.Code]: /Code/,

View File

@ -4,7 +4,7 @@ import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react';
import { CoreApp, LoadingState, SelectableValue } from '@grafana/data';
import { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental';
import { reportInteraction } from '@grafana/runtime';
import { ConfirmModal, Button } from '@grafana/ui';
import { Button, ConfirmModal } from '@grafana/ui';
import { PromQueryEditorProps } from '../../components/types';
import { PromQuery } from '../../types';
@ -110,7 +110,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
/>
<QueryHeaderSwitch label="Explain" value={explain} onChange={onShowExplainChange} />
<FlexItem grow={1} />
{app !== CoreApp.Explore && (
{app !== CoreApp.Explore && app !== CoreApp.Correlations && (
<Button
variant={dataIsStale ? 'primary' : 'secondary'}
size="sm"