Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
5cf5d89d
Unverified
Commit
5cf5d89d
authored
Oct 15, 2019
by
Andrej Ocenas
Committed by
GitHub
Oct 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix: clicking outside of some query editors required 2 clicks (#19822)
parent
573e78fe
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
49 additions
and
41 deletions
+49
-41
public/app/features/explore/QueryField.test.tsx
+3
-3
public/app/features/explore/QueryField.tsx
+43
-35
public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx
+1
-1
public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx
+1
-1
public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
+1
-1
No files found.
public/app/features/explore/QueryField.test.tsx
View file @
5cf5d89d
...
...
@@ -4,17 +4,17 @@ import { QueryField } from './QueryField';
describe
(
'<QueryField />'
,
()
=>
{
it
(
'should render with null initial value'
,
()
=>
{
const
wrapper
=
shallow
(<
QueryField
initialQ
uery=
{
null
}
/>);
const
wrapper
=
shallow
(<
QueryField
q
uery=
{
null
}
/>);
expect
(
wrapper
.
find
(
'div'
).
exists
()).
toBeTruthy
();
});
it
(
'should render with empty initial value'
,
()
=>
{
const
wrapper
=
shallow
(<
QueryField
initialQ
uery=
""
/>);
const
wrapper
=
shallow
(<
QueryField
q
uery=
""
/>);
expect
(
wrapper
.
find
(
'div'
).
exists
()).
toBeTruthy
();
});
it
(
'should render with initial value'
,
()
=>
{
const
wrapper
=
shallow
(<
QueryField
initialQ
uery=
"my query"
/>);
const
wrapper
=
shallow
(<
QueryField
q
uery=
"my query"
/>);
expect
(
wrapper
.
find
(
'div'
).
exists
()).
toBeTruthy
();
});
});
public/app/features/explore/QueryField.tsx
View file @
5cf5d89d
...
...
@@ -15,18 +15,18 @@ import IndentationPlugin from './slate-plugins/indentation';
import
ClipboardPlugin
from
'./slate-plugins/clipboard'
;
import
RunnerPlugin
from
'./slate-plugins/runner'
;
import
SuggestionsPlugin
,
{
SuggestionsState
}
from
'./slate-plugins/suggestions'
;
import
{
Typeahead
}
from
'./Typeahead'
;
import
{
makeValue
,
SCHEMA
}
from
'@grafana/ui'
;
export
const
HIGHLIGHT_WAIT
=
500
;
export
interface
QueryFieldProps
{
additionalPlugins
?:
Plugin
[];
cleanText
?:
(
text
:
string
)
=>
string
;
disabled
?:
boolean
;
initialQuery
:
string
|
null
;
// We have both value and local state. This is usually an antipattern but we need to keep local state
// for perf reasons and also have outside value in for example in Explore redux that is mutable from logs
// creating a two way binding.
query
:
string
|
null
;
onRunQuery
?:
()
=>
void
;
onChange
?:
(
value
:
string
)
=>
void
;
onTypeahead
?:
(
typeahead
:
TypeaheadInput
)
=>
Promise
<
TypeaheadOutput
>
;
...
...
@@ -43,7 +43,6 @@ export interface QueryFieldState {
typeaheadPrefix
:
string
;
typeaheadText
:
string
;
value
:
Value
;
lastExecutedValue
:
Value
;
}
export
interface
TypeaheadInput
{
...
...
@@ -62,18 +61,19 @@ export interface TypeaheadInput {
* Implement props.onTypeahead to use suggestions, see PromQueryField.tsx as an example.
*/
export
class
QueryField
extends
React
.
PureComponent
<
QueryFieldProps
,
QueryFieldState
>
{
menuEl
:
HTMLElement
|
null
;
plugins
:
Plugin
[];
resetTimer
:
NodeJS
.
Timer
;
mounted
:
boolean
;
updateHighlightsTimer
:
Function
;
runOnChangeDebounced
:
Function
;
editor
:
Editor
;
// Is required by SuggestionsPlugin
typeaheadRef
:
Typeahead
;
lastExecutedValue
:
Value
|
null
=
null
;
constructor
(
props
:
QueryFieldProps
,
context
:
Context
<
any
>
)
{
super
(
props
,
context
);
this
.
updateHighlightsTimer
=
_
.
debounce
(
this
.
updateLogsHighlights
,
HIGHLIGHT_WAIT
);
this
.
runOnChangeDebounced
=
_
.
debounce
(
this
.
runOnChange
,
500
);
const
{
onTypeahead
,
cleanText
,
portalOrigin
,
onWillApplySuggestion
}
=
props
;
...
...
@@ -82,7 +82,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
NewlinePlugin
(),
SuggestionsPlugin
({
onTypeahead
,
cleanText
,
portalOrigin
,
onWillApplySuggestion
,
component
:
this
}),
ClearPlugin
(),
RunnerPlugin
({
handler
:
this
.
executeOnChangeAndRunQueries
}),
RunnerPlugin
({
handler
:
this
.
runOnChangeAndRunQuery
}),
SelectionShortcutsPlugin
(),
IndentationPlugin
(),
ClipboardPlugin
(),
...
...
@@ -94,8 +94,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
typeaheadContext
:
null
,
typeaheadPrefix
:
''
,
typeaheadText
:
''
,
value
:
makeValue
(
props
.
initialQuery
||
''
,
props
.
syntax
),
lastExecutedValue
:
null
,
value
:
makeValue
(
props
.
query
||
''
,
props
.
syntax
),
};
}
...
...
@@ -109,14 +108,15 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
}
componentDidUpdate
(
prevProps
:
QueryFieldProps
,
prevState
:
QueryFieldState
)
{
const
{
initialQ
uery
,
syntax
}
=
this
.
props
;
const
{
q
uery
,
syntax
}
=
this
.
props
;
const
{
value
}
=
this
.
state
;
// Handle two way binging between local state and outside prop.
// if query changed from the outside
if
(
initialQuery
!==
prevProps
.
initialQ
uery
)
{
if
(
query
!==
prevProps
.
q
uery
)
{
// and we have a version that differs
if
(
initialQ
uery
!==
Plain
.
serialize
(
value
))
{
this
.
setState
({
value
:
makeValue
(
initialQ
uery
||
''
,
syntax
)
});
if
(
q
uery
!==
Plain
.
serialize
(
value
))
{
this
.
setState
({
value
:
makeValue
(
q
uery
||
''
,
syntax
)
});
}
}
}
...
...
@@ -129,25 +129,31 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
}
}
onChange
=
(
value
:
Value
,
invokeParentOnValueChanged
?:
boolean
)
=>
{
/**
* Update local state, propagate change upstream and optionally run the query afterwards.
*/
onChange
=
(
value
:
Value
,
runQuery
?:
boolean
)
=>
{
const
documentChanged
=
value
.
document
!==
this
.
state
.
value
.
document
;
const
prevValue
=
this
.
state
.
value
;
//
Control editor loop, then pass text change up to parent
//
Update local state with new value and optionally change value upstream.
this
.
setState
({
value
},
()
=>
{
// The diff is needed because the actual value of editor have much more metadata (for example text selection)
// that is not passed upstream so every change of editor value does not mean change of the query text.
if
(
documentChanged
)
{
const
textChanged
=
Plain
.
serialize
(
prevValue
)
!==
Plain
.
serialize
(
value
);
if
(
textChanged
&&
invokeParentOnValueChanged
)
{
this
.
executeOnChangeAndRunQueries
();
if
(
textChanged
&&
runQuery
)
{
this
.
runOnChangeAndRunQuery
();
}
if
(
textChanged
&&
!
invokeParentOnValueChanged
)
{
this
.
updateHighlightsTimer
();
if
(
textChanged
&&
!
runQuery
)
{
// Debounce change propagation by default for perf reasons.
this
.
runOnChangeDebounced
();
}
}
});
};
updateLogsHighlights
=
()
=>
{
runOnChange
=
()
=>
{
const
{
onChange
}
=
this
.
props
;
if
(
onChange
)
{
...
...
@@ -155,30 +161,32 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
}
};
executeOnChangeAndRunQueries
=
()
=>
{
// Send text change to parent
const
{
onChange
,
onRunQuery
}
=
this
.
props
;
if
(
onChange
)
{
onChange
(
Plain
.
serialize
(
this
.
state
.
value
));
}
runOnRunQuery
=
()
=>
{
const
{
onRunQuery
}
=
this
.
props
;
if
(
onRunQuery
)
{
onRunQuery
();
this
.
setState
({
lastExecutedValue
:
this
.
state
.
value
})
;
this
.
lastExecutedValue
=
this
.
state
.
value
;
}
};
runOnChangeAndRunQuery
=
()
=>
{
// onRunQuery executes query from Redux in Explore so it needs to be updated sync in case we want to run
// the query.
this
.
runOnChange
();
this
.
runOnRunQuery
();
};
/**
* 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
{
lastExecutedValue
}
=
this
.
state
;
const
previousValue
=
lastExecutedValue
?
Plain
.
serialize
(
this
.
state
.
lastExecutedValue
)
:
null
;
const
previousValue
=
this
.
lastExecutedValue
?
Plain
.
serialize
(
this
.
lastExecutedValue
)
:
null
;
const
currentValue
=
Plain
.
serialize
(
editor
.
value
);
if
(
previousValue
!==
currentValue
)
{
this
.
executeOnChangeAndRunQueries
();
this
.
runOnChangeAndRunQuery
();
}
editor
.
blur
();
return
next
();
};
...
...
public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx
View file @
5cf5d89d
...
...
@@ -71,7 +71,7 @@ class ElasticsearchQueryField extends React.PureComponent<Props, State> {
<
div
className=
"gf-form gf-form--grow flex-shrink-1"
>
<
QueryField
additionalPlugins=
{
this
.
plugins
}
initialQ
uery=
{
query
.
query
}
q
uery=
{
query
.
query
}
onChange=
{
this
.
onChangeQuery
}
onRunQuery=
{
this
.
props
.
onRunQuery
}
placeholder=
"Enter a Lucene query"
...
...
public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx
View file @
5cf5d89d
...
...
@@ -184,7 +184,7 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
<
QueryField
additionalPlugins=
{
this
.
plugins
}
cleanText=
{
cleanText
}
initialQ
uery=
{
query
.
expr
}
q
uery=
{
query
.
expr
}
onTypeahead=
{
this
.
onTypeahead
}
onWillApplySuggestion=
{
willApplySuggestion
}
onChange=
{
this
.
onChangeQuery
}
...
...
public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
View file @
5cf5d89d
...
...
@@ -312,7 +312,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
<
QueryField
additionalPlugins=
{
this
.
plugins
}
cleanText=
{
cleanText
}
initialQ
uery=
{
query
.
expr
}
q
uery=
{
query
.
expr
}
onTypeahead=
{
this
.
onTypeahead
}
onWillApplySuggestion=
{
willApplySuggestion
}
onChange=
{
this
.
onChangeQuery
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment