mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
QueryField: Prevent query runs on blur in Explore (#20180)
As discussed in a UX feedback session, it's annoying that queries are automatically executed in Explore. This change adds props to override the blur behavior. - add `onBlur` to Explore query field props - Explore's query row will pass down an empty function for onBlur to the query fields - pass onBlur through to the QueryField component for Loki and Prometheus - add test to QueryField to make sure if onBlur is specified, the onRunQuery is not executed
This commit is contained in:
parent
620a3f2f9a
commit
9507eda9d1
@ -281,6 +281,7 @@ export interface ExploreQueryFieldProps<
|
||||
TOptions extends DataSourceJsonData = DataSourceJsonData
|
||||
> extends QueryEditorProps<DSType, TQuery, TOptions> {
|
||||
history: any[];
|
||||
onBlur?: () => void;
|
||||
onHint?: (action: QueryFixAction) => void;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { QueryField } from './QueryField';
|
||||
import { Editor } from 'slate';
|
||||
|
||||
describe('<QueryField />', () => {
|
||||
it('should render with null initial value', () => {
|
||||
@ -17,4 +18,35 @@ describe('<QueryField />', () => {
|
||||
const wrapper = shallow(<QueryField query="my query" onTypeahead={jest.fn()} portalOrigin="mock-origin" />);
|
||||
expect(wrapper.find('div').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should execute query on blur', () => {
|
||||
const onRun = jest.fn();
|
||||
const wrapper = shallow(
|
||||
<QueryField query="my query" onTypeahead={jest.fn()} onRunQuery={onRun} portalOrigin="mock-origin" />
|
||||
);
|
||||
const field = wrapper.instance() as QueryField;
|
||||
expect(onRun.mock.calls.length).toBe(0);
|
||||
field.handleBlur(new Event('bogus'), new Editor({}), () => {});
|
||||
expect(onRun.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should run custom on blur, but not necessarily execute query', () => {
|
||||
const onBlur = jest.fn();
|
||||
const onRun = jest.fn();
|
||||
const wrapper = shallow(
|
||||
<QueryField
|
||||
query="my query"
|
||||
onTypeahead={jest.fn()}
|
||||
onBlur={onBlur}
|
||||
onRunQuery={onRun}
|
||||
portalOrigin="mock-origin"
|
||||
/>
|
||||
);
|
||||
const field = wrapper.instance() as QueryField;
|
||||
expect(onBlur.mock.calls.length).toBe(0);
|
||||
expect(onRun.mock.calls.length).toBe(0);
|
||||
field.handleBlur(new Event('bogus'), new Editor({}), () => {});
|
||||
expect(onBlur.mock.calls.length).toBe(1);
|
||||
expect(onRun.mock.calls.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
@ -27,6 +27,7 @@ export interface QueryFieldProps {
|
||||
// creating a two way binding.
|
||||
query: string | null;
|
||||
onRunQuery?: () => void;
|
||||
onBlur?: () => void;
|
||||
onChange?: (value: string) => void;
|
||||
onTypeahead?: (typeahead: TypeaheadInput) => Promise<TypeaheadOutput>;
|
||||
onWillApplySuggestion?: (suggestion: string, state: SuggestionsState) => string;
|
||||
@ -171,11 +172,17 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
|
||||
* We need to handle blur events here mainly because of dashboard panels which expect to have query executed on blur.
|
||||
*/
|
||||
handleBlur = (event: Event, editor: CoreEditor, next: Function) => {
|
||||
const previousValue = this.lastExecutedValue ? Plain.serialize(this.lastExecutedValue) : null;
|
||||
const currentValue = Plain.serialize(editor.value);
|
||||
const { onBlur } = this.props;
|
||||
if (onBlur) {
|
||||
onBlur();
|
||||
} else {
|
||||
// Run query by default on blur
|
||||
const previousValue = this.lastExecutedValue ? Plain.serialize(this.lastExecutedValue) : null;
|
||||
const currentValue = Plain.serialize(editor.value);
|
||||
|
||||
if (previousValue !== currentValue) {
|
||||
this.runOnChangeAndRunQuery();
|
||||
if (previousValue !== currentValue) {
|
||||
this.runOnChangeAndRunQuery();
|
||||
}
|
||||
}
|
||||
return next();
|
||||
};
|
||||
|
@ -57,6 +57,9 @@ interface QueryRowState {
|
||||
textEditModeEnabled: boolean;
|
||||
}
|
||||
|
||||
// Empty function to override blur execution on query field
|
||||
const noopOnBlur = () => {};
|
||||
|
||||
export class QueryRow extends PureComponent<QueryRowProps, QueryRowState> {
|
||||
state: QueryRowState = {
|
||||
textEditModeEnabled: false,
|
||||
@ -159,6 +162,7 @@ export class QueryRow extends PureComponent<QueryRowProps, QueryRowState> {
|
||||
history={history}
|
||||
onRunQuery={this.onRunQuery}
|
||||
onHint={this.onClickHintFix}
|
||||
onBlur={noopOnBlur}
|
||||
onChange={this.onChange}
|
||||
data={queryResponse}
|
||||
absoluteRange={absoluteRange}
|
||||
|
@ -172,6 +172,7 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onChange={this.onChangeQuery}
|
||||
onBlur={this.props.onBlur}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a Loki query"
|
||||
portalOrigin="loki"
|
||||
|
@ -297,6 +297,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
query={query.expr}
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onBlur={this.props.onBlur}
|
||||
onChange={this.onChangeQuery}
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a PromQL query"
|
||||
|
Loading…
Reference in New Issue
Block a user