mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: Refactor query editor so query field can be used independently (#33276)
* Refactor Loki so LokiQueryField can be used independently * Refactor PromQueryEditor
This commit is contained in:
parent
c809d63065
commit
c32c682f81
@ -1,9 +1,9 @@
|
||||
// Libraries
|
||||
import React, { memo } from 'react';
|
||||
|
||||
// Types
|
||||
import { LokiQuery } from '../types';
|
||||
import { LokiQueryFieldForm } from './LokiQueryFieldForm';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
import { LokiOptionFields } from './LokiOptionFields';
|
||||
import LokiDatasource from '../datasource';
|
||||
|
||||
interface Props {
|
||||
@ -18,7 +18,7 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
||||
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 absolute = {
|
||||
const absoluteRange = {
|
||||
from: Date.now() - 10000,
|
||||
to: Date.now(),
|
||||
};
|
||||
@ -31,13 +31,23 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
||||
};
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<LokiQueryFieldForm
|
||||
<LokiQueryField
|
||||
datasource={datasource}
|
||||
query={queryWithRefId}
|
||||
onChange={onChange}
|
||||
onRunQuery={() => {}}
|
||||
onBlur={() => {}}
|
||||
history={[]}
|
||||
absoluteRange={absolute}
|
||||
absoluteRange={absoluteRange}
|
||||
ExtraFieldElement={
|
||||
<LokiOptionFields
|
||||
queryType={queryWithRefId.instant ? 'instant' : 'range'}
|
||||
lineLimitValue={queryWithRefId?.maxLines?.toString() || ''}
|
||||
query={queryWithRefId}
|
||||
onRunQuery={() => {}}
|
||||
onChange={onChange}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -6,11 +6,13 @@ import { ExploreQueryFieldProps } from '@grafana/data';
|
||||
import { LokiDatasource } from '../datasource';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
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
|
||||
|
||||
return (
|
||||
<LokiQueryField
|
||||
@ -21,7 +23,16 @@ export function LokiExploreQueryEditor(props: Props) {
|
||||
onRunQuery={onRunQuery}
|
||||
history={history}
|
||||
data={data}
|
||||
range={range}
|
||||
absoluteRange={absoluteTimeRange}
|
||||
ExtraFieldElement={
|
||||
<LokiOptionFields
|
||||
queryType={query.instant ? 'instant' : 'range'}
|
||||
lineLimitValue={query?.maxLines?.toString() || ''}
|
||||
query={query}
|
||||
onRunQuery={onRunQuery}
|
||||
onChange={onChange}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ import { InlineFormLabel } from '@grafana/ui';
|
||||
import { LokiDatasource } from '../datasource';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
import { LokiOptionFields } from './LokiOptionFields';
|
||||
|
||||
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
|
||||
|
||||
const onLegendChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const nextQuery = { ...query, legendFormat: e.currentTarget.value };
|
||||
@ -49,9 +51,20 @@ export function LokiQueryEditor(props: Props) {
|
||||
onBlur={onRunQuery}
|
||||
history={[]}
|
||||
data={data}
|
||||
range={range}
|
||||
absoluteRange={absoluteTimeRange}
|
||||
ExtraFieldElement={
|
||||
<>
|
||||
<LokiOptionFields
|
||||
queryType={query.instant ? 'instant' : 'range'}
|
||||
lineLimitValue={query?.maxLines?.toString() || ''}
|
||||
query={query}
|
||||
onRunQuery={onRunQuery}
|
||||
onChange={onChange}
|
||||
runOnBlur={true}
|
||||
ExtraFieldElement={legendField}
|
||||
/>
|
||||
{legendField}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,16 +1,185 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { LokiQueryFieldForm, LokiQueryFieldFormProps } from './LokiQueryFieldForm';
|
||||
// Libraries
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
type LokiQueryFieldProps = Omit<
|
||||
LokiQueryFieldFormProps,
|
||||
'labelsLoaded' | 'onLoadOptions' | 'onLabelsRefresh' | 'absoluteRange'
|
||||
>;
|
||||
import {
|
||||
SlatePrism,
|
||||
TypeaheadOutput,
|
||||
SuggestionsState,
|
||||
QueryField,
|
||||
TypeaheadInput,
|
||||
BracesPlugin,
|
||||
DOMUtil,
|
||||
Icon,
|
||||
} from '@grafana/ui';
|
||||
|
||||
export const LokiQueryField: FunctionComponent<LokiQueryFieldProps> = (props) => {
|
||||
const { datasource, range, ...otherProps } = props;
|
||||
const absoluteTimeRange = { from: range!.from!.valueOf(), to: range!.to!.valueOf() }; // Range here is never optional
|
||||
// Utils & Services
|
||||
// dom also includes Element polyfills
|
||||
import { Plugin, Node } from 'slate';
|
||||
import { LokiLabelBrowser } from './LokiLabelBrowser';
|
||||
|
||||
return <LokiQueryFieldForm datasource={datasource} absoluteRange={absoluteTimeRange} {...otherProps} />;
|
||||
};
|
||||
// Types
|
||||
import { ExploreQueryFieldProps, AbsoluteTimeRange } from '@grafana/data';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider';
|
||||
import LokiDatasource from '../datasource';
|
||||
|
||||
export default LokiQueryField;
|
||||
function getChooserText(hasSyntax: boolean, hasLogLabels: boolean) {
|
||||
if (!hasSyntax) {
|
||||
return 'Loading labels...';
|
||||
}
|
||||
if (!hasLogLabels) {
|
||||
return '(No logs found)';
|
||||
}
|
||||
return 'Log browser';
|
||||
}
|
||||
|
||||
function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadText }: SuggestionsState): string {
|
||||
// Modify suggestion based on context
|
||||
switch (typeaheadContext) {
|
||||
case 'context-labels': {
|
||||
const nextChar = DOMUtil.getNextCharacter();
|
||||
if (!nextChar || nextChar === '}' || nextChar === ',') {
|
||||
suggestion += '=';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'context-label-values': {
|
||||
// Always add quotes and remove existing ones instead
|
||||
if (!typeaheadText.match(/^(!?=~?"|")/)) {
|
||||
suggestion = `"${suggestion}`;
|
||||
}
|
||||
if (DOMUtil.getNextCharacter() !== '"') {
|
||||
suggestion = `${suggestion}"`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
export interface LokiQueryFieldProps extends ExploreQueryFieldProps<LokiDatasource, LokiQuery, LokiOptions> {
|
||||
history: LokiHistoryItem[];
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
ExtraFieldElement?: ReactNode;
|
||||
}
|
||||
|
||||
interface LokiQueryFieldState {
|
||||
labelsLoaded: boolean;
|
||||
labelBrowserVisible: boolean;
|
||||
}
|
||||
|
||||
export class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryFieldState> {
|
||||
plugins: Plugin[];
|
||||
|
||||
constructor(props: LokiQueryFieldProps) {
|
||||
super(props);
|
||||
|
||||
this.state = { labelsLoaded: false, labelBrowserVisible: false };
|
||||
|
||||
this.plugins = [
|
||||
BracesPlugin(),
|
||||
SlatePrism(
|
||||
{
|
||||
onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block',
|
||||
getSyntax: (node: Node) => 'logql',
|
||||
},
|
||||
{ ...(prismLanguages as LanguageMap), logql: this.props.datasource.languageProvider.getSyntax() }
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
async componentDidUpdate() {
|
||||
await this.props.datasource.languageProvider.start();
|
||||
this.setState({ labelsLoaded: true });
|
||||
}
|
||||
|
||||
onChangeLogLabels = (selector: string) => {
|
||||
this.onChangeQuery(selector, true);
|
||||
this.setState({ labelBrowserVisible: false });
|
||||
};
|
||||
|
||||
onChangeQuery = (value: string, override?: boolean) => {
|
||||
// Send text change to parent
|
||||
const { query, onChange, onRunQuery } = this.props;
|
||||
if (onChange) {
|
||||
const nextQuery = { ...query, expr: value };
|
||||
onChange(nextQuery);
|
||||
|
||||
if (override && onRunQuery) {
|
||||
onRunQuery();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onClickChooserButton = () => {
|
||||
this.setState((state) => ({ labelBrowserVisible: !state.labelBrowserVisible }));
|
||||
};
|
||||
|
||||
onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {
|
||||
const { datasource } = this.props;
|
||||
|
||||
if (!datasource.languageProvider) {
|
||||
return { suggestions: [] };
|
||||
}
|
||||
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const { history } = this.props;
|
||||
const { prefix, text, value, wrapperClasses, labelKey } = typeahead;
|
||||
|
||||
const result = await lokiLanguageProvider.provideCompletionItems(
|
||||
{ text, value, prefix, wrapperClasses, labelKey },
|
||||
{ history }
|
||||
);
|
||||
return result;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { ExtraFieldElement, query, datasource } = this.props;
|
||||
const { labelsLoaded, labelBrowserVisible } = this.state;
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const cleanText = datasource.languageProvider ? lokiLanguageProvider.cleanText : undefined;
|
||||
const hasLogLabels = lokiLanguageProvider.getLabelKeys().length > 0;
|
||||
const chooserText = getChooserText(labelsLoaded, hasLogLabels);
|
||||
const buttonDisabled = !(labelsLoaded && hasLogLabels);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline gf-form-inline--xs-view-flex-column flex-grow-1">
|
||||
<button
|
||||
className="gf-form-label query-keyword pointer"
|
||||
onClick={this.onClickChooserButton}
|
||||
disabled={buttonDisabled}
|
||||
>
|
||||
{chooserText}
|
||||
<Icon name={labelBrowserVisible ? 'angle-down' : 'angle-right'} />
|
||||
</button>
|
||||
<div className="gf-form gf-form--grow flex-shrink-1 min-width-15">
|
||||
<QueryField
|
||||
additionalPlugins={this.plugins}
|
||||
cleanText={cleanText}
|
||||
query={query.expr}
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onChange={this.onChangeQuery}
|
||||
onBlur={this.props.onBlur}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a Loki query (run with Shift+Enter)"
|
||||
portalOrigin="loki"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{labelBrowserVisible && (
|
||||
<div className="gf-form">
|
||||
<LokiLabelBrowser languageProvider={lokiLanguageProvider} onChange={this.onChangeLogLabels} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ExtraFieldElement}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,194 +0,0 @@
|
||||
// Libraries
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
import {
|
||||
SlatePrism,
|
||||
TypeaheadOutput,
|
||||
SuggestionsState,
|
||||
QueryField,
|
||||
TypeaheadInput,
|
||||
BracesPlugin,
|
||||
DOMUtil,
|
||||
Icon,
|
||||
} from '@grafana/ui';
|
||||
|
||||
// Utils & Services
|
||||
// dom also includes Element polyfills
|
||||
import { Plugin, Node } from 'slate';
|
||||
import { LokiLabelBrowser } from './LokiLabelBrowser';
|
||||
|
||||
// Types
|
||||
import { ExploreQueryFieldProps, AbsoluteTimeRange } from '@grafana/data';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider';
|
||||
import LokiDatasource from '../datasource';
|
||||
import LokiOptionFields from './LokiOptionFields';
|
||||
|
||||
function getChooserText(hasSyntax: boolean, hasLogLabels: boolean) {
|
||||
if (!hasSyntax) {
|
||||
return 'Loading labels...';
|
||||
}
|
||||
if (!hasLogLabels) {
|
||||
return '(No logs found)';
|
||||
}
|
||||
return 'Log browser';
|
||||
}
|
||||
|
||||
function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadText }: SuggestionsState): string {
|
||||
// Modify suggestion based on context
|
||||
switch (typeaheadContext) {
|
||||
case 'context-labels': {
|
||||
const nextChar = DOMUtil.getNextCharacter();
|
||||
if (!nextChar || nextChar === '}' || nextChar === ',') {
|
||||
suggestion += '=';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'context-label-values': {
|
||||
// Always add quotes and remove existing ones instead
|
||||
if (!typeaheadText.match(/^(!?=~?"|")/)) {
|
||||
suggestion = `"${suggestion}`;
|
||||
}
|
||||
if (DOMUtil.getNextCharacter() !== '"') {
|
||||
suggestion = `${suggestion}"`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
export interface LokiQueryFieldFormProps extends ExploreQueryFieldProps<LokiDatasource, LokiQuery, LokiOptions> {
|
||||
history: LokiHistoryItem[];
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
ExtraFieldElement?: ReactNode;
|
||||
runOnBlur?: boolean;
|
||||
}
|
||||
|
||||
interface LokiQueryFieldFormState {
|
||||
labelsLoaded: boolean;
|
||||
labelBrowserVisible: boolean;
|
||||
}
|
||||
|
||||
export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormProps, LokiQueryFieldFormState> {
|
||||
plugins: Plugin[];
|
||||
|
||||
constructor(props: LokiQueryFieldFormProps) {
|
||||
super(props);
|
||||
|
||||
this.state = { labelsLoaded: false, labelBrowserVisible: false };
|
||||
|
||||
this.plugins = [
|
||||
BracesPlugin(),
|
||||
SlatePrism(
|
||||
{
|
||||
onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block',
|
||||
getSyntax: (node: Node) => 'logql',
|
||||
},
|
||||
{ ...(prismLanguages as LanguageMap), logql: this.props.datasource.languageProvider.getSyntax() }
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
async componentDidUpdate() {
|
||||
await this.props.datasource.languageProvider.start();
|
||||
this.setState({ labelsLoaded: true });
|
||||
}
|
||||
|
||||
onChangeLogLabels = (selector: string) => {
|
||||
this.onChangeQuery(selector, true);
|
||||
this.setState({ labelBrowserVisible: false });
|
||||
};
|
||||
|
||||
onChangeQuery = (value: string, override?: boolean) => {
|
||||
// Send text change to parent
|
||||
const { query, onChange, onRunQuery } = this.props;
|
||||
if (onChange) {
|
||||
const nextQuery = { ...query, expr: value };
|
||||
onChange(nextQuery);
|
||||
|
||||
if (override && onRunQuery) {
|
||||
onRunQuery();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onClickChooserButton = () => {
|
||||
this.setState((state) => ({ labelBrowserVisible: !state.labelBrowserVisible }));
|
||||
};
|
||||
|
||||
onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {
|
||||
const { datasource } = this.props;
|
||||
|
||||
if (!datasource.languageProvider) {
|
||||
return { suggestions: [] };
|
||||
}
|
||||
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const { history } = this.props;
|
||||
const { prefix, text, value, wrapperClasses, labelKey } = typeahead;
|
||||
|
||||
const result = await lokiLanguageProvider.provideCompletionItems(
|
||||
{ text, value, prefix, wrapperClasses, labelKey },
|
||||
{ history }
|
||||
);
|
||||
return result;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { ExtraFieldElement, query, datasource, runOnBlur } = this.props;
|
||||
const { labelsLoaded, labelBrowserVisible } = this.state;
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const cleanText = datasource.languageProvider ? lokiLanguageProvider.cleanText : undefined;
|
||||
const hasLogLabels = lokiLanguageProvider.getLabelKeys().length > 0;
|
||||
const chooserText = getChooserText(labelsLoaded, hasLogLabels);
|
||||
const buttonDisabled = !(labelsLoaded && hasLogLabels);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline gf-form-inline--xs-view-flex-column flex-grow-1">
|
||||
<button
|
||||
className="gf-form-label query-keyword pointer"
|
||||
onClick={this.onClickChooserButton}
|
||||
disabled={buttonDisabled}
|
||||
>
|
||||
{chooserText}
|
||||
<Icon name={labelBrowserVisible ? 'angle-down' : 'angle-right'} />
|
||||
</button>
|
||||
<div className="gf-form gf-form--grow flex-shrink-1 min-width-15">
|
||||
<QueryField
|
||||
additionalPlugins={this.plugins}
|
||||
cleanText={cleanText}
|
||||
query={query.expr}
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onChange={this.onChangeQuery}
|
||||
onBlur={this.props.onBlur}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a Loki query (run with Shift+Enter)"
|
||||
portalOrigin="loki"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{labelBrowserVisible && (
|
||||
<div className="gf-form">
|
||||
<LokiLabelBrowser languageProvider={lokiLanguageProvider} onChange={this.onChangeLogLabels} />
|
||||
</div>
|
||||
)}
|
||||
<LokiOptionFields
|
||||
queryType={query.instant ? 'instant' : 'range'}
|
||||
lineLimitValue={query?.maxLines?.toString() || ''}
|
||||
query={query}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
onChange={this.props.onChange}
|
||||
runOnBlur={runOnBlur}
|
||||
/>
|
||||
{ExtraFieldElement}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,27 @@
|
||||
|
||||
exports[`LokiExploreQueryEditor should render component 1`] = `
|
||||
<LokiQueryField
|
||||
ExtraFieldElement={
|
||||
<LokiOptionFields
|
||||
lineLimitValue="0"
|
||||
onChange={[MockFunction]}
|
||||
onRunQuery={[MockFunction]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
"maxLines": 0,
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
queryType="range"
|
||||
/>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1577836800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
data={
|
||||
Object {
|
||||
"request": Object {
|
||||
@ -98,15 +119,5 @@ exports[`LokiExploreQueryEditor should render component 1`] = `
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
range={
|
||||
Object {
|
||||
"from": "2020-01-01T00:00:00.000Z",
|
||||
"raw": Object {
|
||||
"from": "2020-01-01T00:00:00.000Z",
|
||||
"to": "2020-01-02T00:00:00.000Z",
|
||||
},
|
||||
"to": "2020-01-02T00:00:00.000Z",
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
@ -3,6 +3,21 @@
|
||||
exports[`Render LokiQueryEditor with legend should render 1`] = `
|
||||
<LokiQueryField
|
||||
ExtraFieldElement={
|
||||
<React.Fragment>
|
||||
<LokiOptionFields
|
||||
lineLimitValue=""
|
||||
onChange={[MockFunction]}
|
||||
onRunQuery={[MockFunction]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
"legendFormat": "My Legend",
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
queryType="range"
|
||||
runOnBlur={true}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-inline"
|
||||
>
|
||||
@ -26,6 +41,13 @@ exports[`Render LokiQueryEditor with legend should render 1`] = `
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1577836800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
datasource={Object {}}
|
||||
history={Array []}
|
||||
@ -39,19 +61,27 @@ exports[`Render LokiQueryEditor with legend should render 1`] = `
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
range={
|
||||
Object {
|
||||
"from": "2020-01-01T00:00:00.000Z",
|
||||
"to": "2020-01-02T00:00:00.000Z",
|
||||
}
|
||||
}
|
||||
runOnBlur={true}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`Render LokiQueryEditor with legend should update timerange 1`] = `
|
||||
<LokiQueryField
|
||||
ExtraFieldElement={
|
||||
<React.Fragment>
|
||||
<LokiOptionFields
|
||||
lineLimitValue=""
|
||||
onChange={[MockFunction]}
|
||||
onRunQuery={[MockFunction]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
"legendFormat": "My Legend",
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
queryType="range"
|
||||
runOnBlur={true}
|
||||
/>
|
||||
<div
|
||||
className="gf-form-inline"
|
||||
>
|
||||
@ -75,6 +105,13 @@ exports[`Render LokiQueryEditor with legend should update timerange 1`] = `
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
absoluteRange={
|
||||
Object {
|
||||
"from": 1546300800000,
|
||||
"to": 1577923200000,
|
||||
}
|
||||
}
|
||||
datasource={Object {}}
|
||||
history={Array []}
|
||||
@ -88,12 +125,5 @@ exports[`Render LokiQueryEditor with legend should update timerange 1`] = `
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
range={
|
||||
Object {
|
||||
"from": "2019-01-01T00:00:00.000Z",
|
||||
"to": "2020-01-02T00:00:00.000Z",
|
||||
}
|
||||
}
|
||||
runOnBlur={true}
|
||||
/>
|
||||
`;
|
||||
|
@ -110,7 +110,6 @@ export class PromQueryEditor extends PureComponent<Props, State> {
|
||||
const { formatOption, instant, interval, intervalFactorOption, legendFormat, exemplar } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PromQueryField
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
@ -119,8 +118,7 @@ export class PromQueryEditor extends PureComponent<Props, State> {
|
||||
onChange={this.onFieldChange}
|
||||
history={[]}
|
||||
data={data}
|
||||
/>
|
||||
|
||||
ExtraFieldElement={
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel
|
||||
@ -195,7 +193,8 @@ export class PromQueryEditor extends PureComponent<Props, State> {
|
||||
|
||||
<PromExemplarField isEnabled={exemplar} onChange={this.onExemplarChange} datasource={datasource} />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,8 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render PromQueryEditor with basic options should render 1`] = `
|
||||
<div>
|
||||
<PromQueryField
|
||||
datasource={
|
||||
Object {
|
||||
"createQuery": [MockFunction],
|
||||
"getPrometheusTime": [MockFunction],
|
||||
}
|
||||
}
|
||||
history={Array []}
|
||||
onChange={[Function]}
|
||||
onRunQuery={[Function]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<PromQueryField
|
||||
ExtraFieldElement={
|
||||
<div
|
||||
className="gf-form-inline"
|
||||
>
|
||||
@ -193,5 +177,21 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
datasource={
|
||||
Object {
|
||||
"createQuery": [MockFunction],
|
||||
"getPrometheusTime": [MockFunction],
|
||||
}
|
||||
}
|
||||
history={Array []}
|
||||
onChange={[Function]}
|
||||
onRunQuery={[Function]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
"refId": "A",
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user