mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus/Loki: Show raw query by default in the builder(#50007)
This commit is contained in:
parent
ace5b2058d
commit
c63071f519
@ -30,6 +30,7 @@ describe('LokiQueryBuilderContainer', () => {
|
||||
),
|
||||
onChange: jest.fn(),
|
||||
onRunQuery: () => {},
|
||||
showRawQuery: true,
|
||||
};
|
||||
render(<LokiQueryBuilderContainer {...props} />);
|
||||
expect(screen.getByText('testjob')).toBeInTheDocument();
|
||||
|
@ -15,6 +15,7 @@ export interface Props {
|
||||
datasource: LokiDatasource;
|
||||
onChange: (update: LokiQuery) => void;
|
||||
onRunQuery: () => void;
|
||||
showRawQuery: boolean;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
@ -26,7 +27,7 @@ export interface State {
|
||||
* This component is here just to contain the translation logic between string query and the visual query builder model.
|
||||
*/
|
||||
export function LokiQueryBuilderContainer(props: Props) {
|
||||
const { query, onChange, onRunQuery, datasource } = props;
|
||||
const { query, onChange, onRunQuery, datasource, showRawQuery } = props;
|
||||
const [state, dispatch] = useReducer(stateSlice.reducer, {
|
||||
expr: query.expr,
|
||||
// Use initial visual query only if query.expr is empty string
|
||||
@ -62,7 +63,7 @@ export function LokiQueryBuilderContainer(props: Props) {
|
||||
onChange={onVisQueryChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
{query.rawQuery && <QueryPreview query={query.expr} />}
|
||||
{showRawQuery && <QueryPreview query={query.expr} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -10,6 +10,18 @@ import { LokiQuery, LokiQueryType } from '../../types';
|
||||
|
||||
import { LokiQueryEditorSelector } from './LokiQueryEditorSelector';
|
||||
|
||||
jest.mock('app/core/store', () => {
|
||||
return {
|
||||
get() {
|
||||
return undefined;
|
||||
},
|
||||
set() {},
|
||||
getObject(key: string, defaultValue: any) {
|
||||
return defaultValue;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const defaultQuery = {
|
||||
refId: 'A',
|
||||
expr: '{label1="foo", label2="bar"}',
|
||||
@ -86,23 +98,14 @@ describe('LokiQueryEditorSelector', () => {
|
||||
});
|
||||
|
||||
it('Can enable raw query', async () => {
|
||||
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
||||
expect(screen.queryByLabelText('selector')).not.toBeInTheDocument();
|
||||
|
||||
renderWithMode(QueryEditorMode.Builder);
|
||||
expect(screen.queryByLabelText('selector')).toBeInTheDocument();
|
||||
screen.getByLabelText('Raw query').click();
|
||||
|
||||
expect(onChange).toBeCalledWith({
|
||||
refId: 'A',
|
||||
expr: defaultQuery.expr,
|
||||
queryType: 'range',
|
||||
editorMode: QueryEditorMode.Builder,
|
||||
rawQuery: true,
|
||||
});
|
||||
expect(screen.queryByLabelText('selector')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should show raw query', async () => {
|
||||
it('Should show raw query by default', async () => {
|
||||
renderWithProps({
|
||||
rawQuery: true,
|
||||
editorMode: QueryEditorMode.Builder,
|
||||
expr: '{job="grafana"}',
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ import { LokiQueryEditorProps } from '../../components/types';
|
||||
import { LokiQuery } from '../../types';
|
||||
import { lokiQueryModeller } from '../LokiQueryModeller';
|
||||
import { buildVisualQueryFromString } from '../parsing';
|
||||
import { changeEditorMode, getQueryWithDefaults } from '../state';
|
||||
import { changeEditorMode, getQueryWithDefaults, useRawQuery } from '../state';
|
||||
|
||||
import { LokiQueryBuilderContainer } from './LokiQueryBuilderContainer';
|
||||
import { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained';
|
||||
@ -24,6 +24,7 @@ export const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props)
|
||||
const [dataIsStale, setDataIsStale] = useState(false);
|
||||
|
||||
const query = getQueryWithDefaults(props.query);
|
||||
const [rawQuery, setRawQuery] = useRawQuery();
|
||||
// This should be filled in from the defaults by now.
|
||||
const editorMode = query.editorMode!;
|
||||
|
||||
@ -53,7 +54,7 @@ export const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props)
|
||||
|
||||
const onQueryPreviewChange = (event: SyntheticEvent<HTMLInputElement>) => {
|
||||
const isEnabled = event.currentTarget.checked;
|
||||
onChange({ ...query, rawQuery: isEnabled });
|
||||
setRawQuery(isEnabled);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -86,7 +87,7 @@ export const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props)
|
||||
}}
|
||||
options={lokiQueryModeller.getQueryPatterns().map((x) => ({ label: x.name, value: x }))}
|
||||
/>
|
||||
<QueryHeaderSwitch label="Raw query" value={query.rawQuery} onChange={onQueryPreviewChange} />
|
||||
<QueryHeaderSwitch label="Raw query" value={rawQuery} onChange={onQueryPreviewChange} />
|
||||
</>
|
||||
)}
|
||||
<FlexItem grow={1} />
|
||||
@ -110,6 +111,7 @@ export const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props)
|
||||
query={query}
|
||||
onChange={onChangeInternal}
|
||||
onRunQuery={props.onRunQuery}
|
||||
showRawQuery={rawQuery}
|
||||
/>
|
||||
)}
|
||||
{editorMode === QueryEditorMode.Explain && <LokiQueryBuilderExplained query={query.expr} />}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import store from 'app/core/store';
|
||||
|
||||
import { QueryEditorMode } from '../../prometheus/querybuilder/shared/types';
|
||||
@ -53,3 +55,28 @@ export function getQueryWithDefaults(query: LokiQuery): LokiQuery {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const queryEditorRawQueryLocalStorageKey = 'LokiQueryEditorRawQueryDefault';
|
||||
|
||||
function getRawQueryVisibility(): boolean {
|
||||
const val = store.get(queryEditorRawQueryLocalStorageKey);
|
||||
return val === undefined ? true : Boolean(parseInt(val, 10));
|
||||
}
|
||||
|
||||
function setRawQueryVisibility(value: boolean) {
|
||||
store.set(queryEditorRawQueryLocalStorageKey, value ? '1' : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Use and store value of raw query switch in local storage.
|
||||
* Needs to be a hook with local state to trigger rerenders.
|
||||
*/
|
||||
export function useRawQuery(): [boolean, (val: boolean) => void] {
|
||||
const [rawQuery, setRawQuery] = useState(getRawQueryVisibility());
|
||||
const setter = useCallback((value: boolean) => {
|
||||
setRawQueryVisibility(value);
|
||||
setRawQuery(value);
|
||||
}, []);
|
||||
|
||||
return [rawQuery, setter];
|
||||
}
|
||||
|
@ -49,8 +49,6 @@ export interface LokiQuery extends DataQuery {
|
||||
/* @deprecated now use queryType */
|
||||
instant?: boolean;
|
||||
editorMode?: QueryEditorMode;
|
||||
/** Controls if the raw query text is shown */
|
||||
rawQuery?: boolean;
|
||||
}
|
||||
|
||||
export interface LokiOptions extends DataSourceJsonData {
|
||||
|
@ -18,6 +18,7 @@ export interface Props {
|
||||
onChange: (update: PromQuery) => void;
|
||||
onRunQuery: () => void;
|
||||
data?: PanelData;
|
||||
showRawQuery?: boolean;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
@ -29,7 +30,7 @@ export interface State {
|
||||
* This component is here just to contain the translation logic between string query and the visual query builder model.
|
||||
*/
|
||||
export function PromQueryBuilderContainer(props: Props) {
|
||||
const { query, onChange, onRunQuery, datasource, data } = props;
|
||||
const { query, onChange, onRunQuery, datasource, data, showRawQuery } = props;
|
||||
const [state, dispatch] = useReducer(stateSlice.reducer, { expr: query.expr });
|
||||
|
||||
// Only rebuild visual query if expr changes from outside
|
||||
@ -56,7 +57,7 @@ export function PromQueryBuilderContainer(props: Props) {
|
||||
onRunQuery={onRunQuery}
|
||||
data={data}
|
||||
/>
|
||||
{query.rawQuery && <QueryPreview query={query.expr} />}
|
||||
{showRawQuery && <QueryPreview query={query.expr} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -20,6 +20,18 @@ jest.mock('../../components/monaco-query-field/MonacoQueryFieldWrapper', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('app/core/store', () => {
|
||||
return {
|
||||
get() {
|
||||
return undefined;
|
||||
},
|
||||
set() {},
|
||||
getObject(key: string, defaultValue: any) {
|
||||
return defaultValue;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
return {
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
@ -87,23 +99,14 @@ describe('PromQueryEditorSelector', () => {
|
||||
});
|
||||
|
||||
it('Can enable raw query', async () => {
|
||||
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
||||
expect(screen.queryByLabelText('selector')).not.toBeInTheDocument();
|
||||
|
||||
renderWithMode(QueryEditorMode.Builder);
|
||||
expect(screen.queryByLabelText('selector')).toBeInTheDocument();
|
||||
screen.getByLabelText('Raw query').click();
|
||||
|
||||
expect(onChange).toBeCalledWith({
|
||||
refId: 'A',
|
||||
expr: defaultQuery.expr,
|
||||
range: true,
|
||||
editorMode: QueryEditorMode.Builder,
|
||||
rawQuery: true,
|
||||
});
|
||||
expect(screen.queryByLabelText('selector')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should show raw query', async () => {
|
||||
it('Should show raw query by default', async () => {
|
||||
renderWithProps({
|
||||
rawQuery: true,
|
||||
editorMode: QueryEditorMode.Builder,
|
||||
expr: 'my_metric',
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ import { FeedbackLink } from '../shared/FeedbackLink';
|
||||
import { QueryEditorModeToggle } from '../shared/QueryEditorModeToggle';
|
||||
import { QueryHeaderSwitch } from '../shared/QueryHeaderSwitch';
|
||||
import { QueryEditorMode } from '../shared/types';
|
||||
import { changeEditorMode, getQueryWithDefaults } from '../state';
|
||||
import { changeEditorMode, getQueryWithDefaults, useRawQuery } from '../state';
|
||||
|
||||
import { PromQueryBuilderContainer } from './PromQueryBuilderContainer';
|
||||
import { PromQueryBuilderExplained } from './PromQueryBuilderExplained';
|
||||
@ -28,6 +28,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
const [dataIsStale, setDataIsStale] = useState(false);
|
||||
|
||||
const query = getQueryWithDefaults(props.query, app);
|
||||
const [rawQuery, setRawQuery] = useRawQuery();
|
||||
// This should be filled in from the defaults by now.
|
||||
const editorMode = query.editorMode!;
|
||||
|
||||
@ -59,7 +60,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
|
||||
const onQueryPreviewChange = (event: SyntheticEvent<HTMLInputElement>) => {
|
||||
const isEnabled = event.currentTarget.checked;
|
||||
onChange({ ...query, rawQuery: isEnabled });
|
||||
setRawQuery(isEnabled);
|
||||
};
|
||||
|
||||
const onChangeInternal = (query: PromQuery) => {
|
||||
@ -99,7 +100,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
}}
|
||||
options={promQueryModeller.getQueryPatterns().map((x) => ({ label: x.name, value: x }))}
|
||||
/>
|
||||
<QueryHeaderSwitch label="Raw query" value={query.rawQuery} onChange={onQueryPreviewChange} />
|
||||
<QueryHeaderSwitch label="Raw query" value={rawQuery} onChange={onQueryPreviewChange} />
|
||||
</>
|
||||
)}
|
||||
{editorMode === QueryEditorMode.Builder && (
|
||||
@ -127,6 +128,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
onChange={onChangeInternal}
|
||||
onRunQuery={props.onRunQuery}
|
||||
data={data}
|
||||
showRawQuery={rawQuery}
|
||||
/>
|
||||
)}
|
||||
{editorMode === QueryEditorMode.Explain && <PromQueryBuilderExplained query={query.expr} />}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { CoreApp } from '@grafana/data';
|
||||
import store from 'app/core/store';
|
||||
|
||||
@ -59,3 +61,28 @@ export function getQueryWithDefaults(query: PromQuery, app: CoreApp | undefined)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const queryEditorRawQueryLocalStorageKey = 'PrometheusQueryEditorRawQueryDefault';
|
||||
|
||||
function getRawQueryVisibility(): boolean {
|
||||
const val = store.get(queryEditorRawQueryLocalStorageKey);
|
||||
return val === undefined ? true : Boolean(parseInt(val, 10));
|
||||
}
|
||||
|
||||
function setRawQueryVisibility(value: boolean) {
|
||||
store.set(queryEditorRawQueryLocalStorageKey, value ? '1' : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Use and store value of raw query switch in local storage.
|
||||
* Needs to be a hook with local state to trigger rerenders.
|
||||
*/
|
||||
export function useRawQuery(): [boolean, (val: boolean) => void] {
|
||||
const [rawQuery, setRawQuery] = useState(getRawQueryVisibility());
|
||||
const setter = useCallback((value: boolean) => {
|
||||
setRawQueryVisibility(value);
|
||||
setRawQuery(value);
|
||||
}, []);
|
||||
|
||||
return [rawQuery, setter];
|
||||
}
|
||||
|
@ -20,8 +20,6 @@ export interface PromQuery extends DataQuery {
|
||||
showingTable?: boolean;
|
||||
/** Code, Builder or Explain */
|
||||
editorMode?: QueryEditorMode;
|
||||
/** Controls if the raw query text is shown */
|
||||
rawQuery?: boolean;
|
||||
}
|
||||
|
||||
export interface PromOptions extends DataSourceJsonData {
|
||||
|
Loading…
Reference in New Issue
Block a user