mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: app specific query editors for Loki and Prometheus (#34365)
* Adding simplified version of query editor based on app flag. * cleaned up the absolute time range. * changing placeholder text. * updated snapshot. * added some tests. * adding loki query editor tests. * updating snapshots.
This commit is contained in:
@@ -17,12 +17,6 @@ interface Props {
|
||||
export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEditor(props: Props) {
|
||||
const { expr, maxLines, instant, datasource, onChange } = props;
|
||||
|
||||
// Timerange to get existing labels from. Hard coding like this seems to be good enough right now.
|
||||
const absoluteRange = {
|
||||
from: Date.now() - 10000,
|
||||
to: Date.now(),
|
||||
};
|
||||
|
||||
const queryWithRefId: LokiQuery = {
|
||||
refId: '',
|
||||
expr,
|
||||
@@ -38,7 +32,6 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
||||
onRunQuery={() => {}}
|
||||
onBlur={() => {}}
|
||||
history={[]}
|
||||
absoluteRange={absoluteRange}
|
||||
ExtraFieldElement={
|
||||
<LokiOptionFields
|
||||
queryType={queryWithRefId.instant ? 'instant' : 'range'}
|
||||
|
||||
@@ -11,8 +11,7 @@ import { LokiOptionFields } from './LokiOptionFields';
|
||||
type Props = ExploreQueryFieldProps<LokiDatasource, LokiQuery, LokiOptions>;
|
||||
|
||||
export function LokiExploreQueryEditor(props: Props) {
|
||||
const { range, query, data, datasource, history, onChange, onRunQuery } = props;
|
||||
const absoluteTimeRange = { from: range!.from!.valueOf(), to: range!.to!.valueOf() }; // Range here is never optional
|
||||
const { query, data, datasource, history, onChange, onRunQuery } = props;
|
||||
|
||||
return (
|
||||
<LokiQueryField
|
||||
@@ -23,7 +22,6 @@ export function LokiExploreQueryEditor(props: Props) {
|
||||
onRunQuery={onRunQuery}
|
||||
history={history}
|
||||
data={data}
|
||||
absoluteRange={absoluteTimeRange}
|
||||
ExtraFieldElement={
|
||||
<LokiOptionFields
|
||||
queryType={query.instant ? 'instant' : 'range'}
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
// Libraries
|
||||
import React, { memo } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
// Types
|
||||
import { QueryEditorProps } from '@grafana/data';
|
||||
import { InlineFormLabel } from '@grafana/ui';
|
||||
import { LokiDatasource } from '../datasource';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
import { LokiOptionFields } from './LokiOptionFields';
|
||||
import { LokiQueryEditorProps } from './types';
|
||||
|
||||
type Props = QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions>;
|
||||
|
||||
export function LokiQueryEditor(props: Props) {
|
||||
const { range, query, data, datasource, onChange, onRunQuery } = props;
|
||||
const absoluteTimeRange = { from: range!.from!.valueOf(), to: range!.to!.valueOf() }; // Range here is never optional
|
||||
export function LokiQueryEditor(props: LokiQueryEditorProps) {
|
||||
const { query, data, datasource, onChange, onRunQuery } = props;
|
||||
|
||||
const onLegendChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const nextQuery = { ...query, legendFormat: e.currentTarget.value };
|
||||
@@ -51,7 +46,7 @@ export function LokiQueryEditor(props: Props) {
|
||||
onBlur={onRunQuery}
|
||||
history={[]}
|
||||
data={data}
|
||||
absoluteRange={absoluteTimeRange}
|
||||
data-testid={testIds.editor}
|
||||
ExtraFieldElement={
|
||||
<>
|
||||
<LokiOptionFields
|
||||
@@ -69,4 +64,6 @@ export function LokiQueryEditor(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(LokiQueryEditor);
|
||||
export const testIds = {
|
||||
editor: 'loki-editor',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { render, RenderResult } from '@testing-library/react';
|
||||
import { CoreApp } from '@grafana/data';
|
||||
import { noop } from 'lodash';
|
||||
import { LokiDatasource } from '../datasource';
|
||||
import { testIds as alertingTestIds } from './LokiQueryEditorForAlerting';
|
||||
import { testIds as regularTestIds } from './LokiQueryEditor';
|
||||
import LokiQueryEditorByApp from './LokiQueryEditorByApp';
|
||||
|
||||
function setup(app: CoreApp): RenderResult {
|
||||
const dataSource = ({
|
||||
languageProvider: {
|
||||
start: () => Promise.resolve([]),
|
||||
getSyntax: () => {},
|
||||
getLabelKeys: () => [],
|
||||
metrics: [],
|
||||
},
|
||||
} as unknown) as LokiDatasource;
|
||||
|
||||
return render(
|
||||
<LokiQueryEditorByApp
|
||||
app={app}
|
||||
onChange={noop}
|
||||
onRunQuery={noop}
|
||||
datasource={dataSource}
|
||||
query={{ refId: 'A', expr: '' }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
describe('LokiQueryEditorByApp', () => {
|
||||
it('should render simplified query editor for cloud alerting', () => {
|
||||
const { getByTestId, queryByTestId } = setup(CoreApp.CloudAlerting);
|
||||
|
||||
expect(getByTestId(alertingTestIds.editor)).toBeInTheDocument();
|
||||
expect(queryByTestId(regularTestIds.editor)).toBeNull();
|
||||
});
|
||||
|
||||
it('should render regular query editor for unkown apps', () => {
|
||||
const { getByTestId, queryByTestId } = setup(CoreApp.Unknown);
|
||||
|
||||
expect(getByTestId(regularTestIds.editor)).toBeInTheDocument();
|
||||
expect(queryByTestId(alertingTestIds.editor)).toBeNull();
|
||||
});
|
||||
|
||||
it('should render regular query editor for explore', () => {
|
||||
const { getByTestId, queryByTestId } = setup(CoreApp.Explore);
|
||||
|
||||
expect(getByTestId(regularTestIds.editor)).toBeInTheDocument();
|
||||
expect(queryByTestId(alertingTestIds.editor)).toBeNull();
|
||||
});
|
||||
|
||||
it('should render regular query editor for dashboard', () => {
|
||||
const { getByTestId, queryByTestId } = setup(CoreApp.Dashboard);
|
||||
|
||||
expect(getByTestId(regularTestIds.editor)).toBeInTheDocument();
|
||||
expect(queryByTestId(alertingTestIds.editor)).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import React, { memo } from 'react';
|
||||
import { CoreApp } from '@grafana/data';
|
||||
import { LokiQueryEditorProps } from './types';
|
||||
import { LokiQueryEditor } from './LokiQueryEditor';
|
||||
import { LokiQueryEditorForAlerting } from './LokiQueryEditorForAlerting';
|
||||
|
||||
export function LokiQueryEditorByApp(props: LokiQueryEditorProps) {
|
||||
const { app } = props;
|
||||
|
||||
switch (app) {
|
||||
case CoreApp.CloudAlerting:
|
||||
return <LokiQueryEditorForAlerting {...props} />;
|
||||
default:
|
||||
return <LokiQueryEditor {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default memo(LokiQueryEditorByApp);
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
import { LokiQueryEditorProps } from './types';
|
||||
|
||||
export function LokiQueryEditorForAlerting(props: LokiQueryEditorProps) {
|
||||
const { query, data, datasource, onChange, onRunQuery } = props;
|
||||
|
||||
return (
|
||||
<LokiQueryField
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
onBlur={onRunQuery}
|
||||
history={[]}
|
||||
data={data}
|
||||
placeholder="Enter a Loki query"
|
||||
data-testid={testIds.editor}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const testIds = {
|
||||
editor: 'loki-editor-cloud-alerting',
|
||||
};
|
||||
@@ -18,7 +18,7 @@ import { Plugin, Node } from 'slate';
|
||||
import { LokiLabelBrowser } from './LokiLabelBrowser';
|
||||
|
||||
// Types
|
||||
import { ExploreQueryFieldProps, AbsoluteTimeRange } from '@grafana/data';
|
||||
import { ExploreQueryFieldProps } from '@grafana/data';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider';
|
||||
@@ -63,8 +63,9 @@ function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadTe
|
||||
|
||||
export interface LokiQueryFieldProps extends ExploreQueryFieldProps<LokiDatasource, LokiQuery, LokiOptions> {
|
||||
history: LokiHistoryItem[];
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
ExtraFieldElement?: ReactNode;
|
||||
placeholder?: string;
|
||||
'data-testid'?: string;
|
||||
}
|
||||
|
||||
interface LokiQueryFieldState {
|
||||
@@ -138,7 +139,13 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
|
||||
};
|
||||
|
||||
render() {
|
||||
const { ExtraFieldElement, query, datasource } = this.props;
|
||||
const {
|
||||
ExtraFieldElement,
|
||||
query,
|
||||
datasource,
|
||||
placeholder = 'Enter a Loki query (run with Shift+Enter)',
|
||||
} = this.props;
|
||||
|
||||
const { labelsLoaded, labelBrowserVisible } = this.state;
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const cleanText = datasource.languageProvider ? lokiLanguageProvider.cleanText : undefined;
|
||||
@@ -148,7 +155,10 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline gf-form-inline--xs-view-flex-column flex-grow-1">
|
||||
<div
|
||||
className="gf-form-inline gf-form-inline--xs-view-flex-column flex-grow-1"
|
||||
data-testid={this.props['data-testid']}
|
||||
>
|
||||
<button
|
||||
className="gf-form-label query-keyword pointer"
|
||||
onClick={this.onClickChooserButton}
|
||||
@@ -167,7 +177,7 @@ export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, Lok
|
||||
onChange={this.onChangeQuery}
|
||||
onBlur={this.props.onBlur}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a Loki query (run with Shift+Enter)"
|
||||
placeholder={placeholder}
|
||||
portalOrigin="loki"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -17,12 +17,6 @@ exports[`LokiExploreQueryEditor should render component 1`] = `
|
||||
queryType="range"
|
||||
/>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1577836800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
data={
|
||||
Object {
|
||||
"request": Object {
|
||||
|
||||
@@ -43,12 +43,7 @@ exports[`Render LokiQueryEditor with legend should render 1`] = `
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1577836800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
data-testid="loki-editor"
|
||||
datasource={Object {}}
|
||||
history={Array []}
|
||||
onBlur={[MockFunction]}
|
||||
@@ -107,12 +102,7 @@ exports[`Render LokiQueryEditor with legend should update timerange 1`] = `
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1546300800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
data-testid="loki-editor"
|
||||
datasource={Object {}}
|
||||
history={Array []}
|
||||
onBlur={[MockFunction]}
|
||||
|
||||
5
public/app/plugins/datasource/loki/components/types.ts
Normal file
5
public/app/plugins/datasource/loki/components/types.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { QueryEditorProps } from '@grafana/data';
|
||||
import LokiDatasource from '../datasource';
|
||||
import { LokiOptions, LokiQuery } from '../types';
|
||||
|
||||
export type LokiQueryEditorProps = QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions>;
|
||||
@@ -3,12 +3,12 @@ import Datasource from './datasource';
|
||||
|
||||
import LokiCheatSheet from './components/LokiCheatSheet';
|
||||
import LokiExploreQueryEditor from './components/LokiExploreQueryEditor';
|
||||
import LokiQueryEditor from './components/LokiQueryEditor';
|
||||
import LokiQueryEditorByApp from './components/LokiQueryEditorByApp';
|
||||
import { LokiAnnotationsQueryCtrl } from './LokiAnnotationsQueryCtrl';
|
||||
import { ConfigEditor } from './configuration/ConfigEditor';
|
||||
|
||||
export const plugin = new DataSourcePlugin(Datasource)
|
||||
.setQueryEditor(LokiQueryEditor)
|
||||
.setQueryEditor(LokiQueryEditorByApp)
|
||||
.setConfigEditor(ConfigEditor)
|
||||
.setExploreQueryField(LokiExploreQueryEditor)
|
||||
.setQueryEditorHelp(LokiCheatSheet)
|
||||
|
||||
Reference in New Issue
Block a user