Introduce query bar update button with dirty checking (#24529)

Reintroduced submit button removed in the react migration of the query bar. Added dirty state indications.
This commit is contained in:
Matt Bargar 2018-10-24 18:05:40 -04:00 committed by GitHub
parent 3af1b2109f
commit c5dd537ec6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 366 additions and 236 deletions

View file

@ -2722,7 +2722,7 @@ main {
display: -ms-flexbox;
display: flex;
width: 100%;
margin-bottom: 10px; }
margin-bottom: 8px; }
.kuiLocalSearchInput {
-webkit-appearance: none;

View file

@ -1,7 +1,7 @@
.kuiLocalSearch {
display: flex;
width: 100%;
margin-bottom: 10px;
margin-bottom: 8px;
}
.kuiLocalSearchInput {

View file

@ -14,6 +14,7 @@ exports[`LanguageSwitcher should toggle off if language is lucene 1`] = `
Options
</EuiButtonEmpty>
}
className="eui-displayBlock"
closePopover={[Function]}
hasArrow={true}
id="popover"
@ -108,6 +109,7 @@ exports[`LanguageSwitcher should toggle on if language is kuery 1`] = `
Options
</EuiButtonEmpty>
}
className="eui-displayBlock"
closePopover={[Function]}
hasArrow={true}
id="popover"

View file

@ -1,217 +1,313 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`QueryBar Should disable autoFocus on EuiFieldText when disableAutoFocus prop is true 1`] = `
<EuiOutsideClickDetector
onOutsideClick={[Function]}
<EuiFlexGroup
alignItems="stretch"
component="div"
direction="row"
gutterSize="s"
justifyContent="flexStart"
responsive={false}
wrap={false}
>
<div
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
<EuiFlexItem
component="div"
grow={true}
>
<form
name="queryBarForm"
role="form"
<EuiOutsideClickDetector
onOutsideClick={[Function]}
>
<div
className="kuiLocalSearch"
role="search"
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
>
<div
className="kuiLocalSearchAssistedInput"
<form
name="queryBarForm"
role="form"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={false}
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
className="kuiLocalSearch"
role="search"
>
<QueryLanguageSwitcher
language="kuery"
onSelectLanguage={[Function]}
/>
<div
className="kuiLocalSearchAssistedInput"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={false}
className="kuiLocalSearchAssistedInput__input"
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
>
<QueryLanguageSwitcher
language="kuery"
onSelectLanguage={[Function]}
/>
</div>
</div>
</div>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
</EuiOutsideClickDetector>
</EuiFlexItem>
<EuiFlexItem
component="div"
grow={false}
>
<EuiButton
aria-label="Search"
color="primary"
data-test-subj="querySubmitButton"
fill={true}
iconSide="left"
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</EuiOutsideClickDetector>
type="button"
>
Refresh
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
`;
exports[`QueryBar Should pass the query language to the language switcher 1`] = `
<EuiOutsideClickDetector
onOutsideClick={[Function]}
<EuiFlexGroup
alignItems="stretch"
component="div"
direction="row"
gutterSize="s"
justifyContent="flexStart"
responsive={false}
wrap={false}
>
<div
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
<EuiFlexItem
component="div"
grow={true}
>
<form
name="queryBarForm"
role="form"
<EuiOutsideClickDetector
onOutsideClick={[Function]}
>
<div
className="kuiLocalSearch"
role="search"
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
>
<div
className="kuiLocalSearchAssistedInput"
<form
name="queryBarForm"
role="form"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={true}
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
className="kuiLocalSearch"
role="search"
>
<QueryLanguageSwitcher
language="lucene"
onSelectLanguage={[Function]}
/>
<div
className="kuiLocalSearchAssistedInput"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={true}
className="kuiLocalSearchAssistedInput__input"
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
>
<QueryLanguageSwitcher
language="lucene"
onSelectLanguage={[Function]}
/>
</div>
</div>
</div>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
</EuiOutsideClickDetector>
</EuiFlexItem>
<EuiFlexItem
component="div"
grow={false}
>
<EuiButton
aria-label="Search"
color="primary"
data-test-subj="querySubmitButton"
fill={true}
iconSide="left"
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</EuiOutsideClickDetector>
type="button"
>
Refresh
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
`;
exports[`QueryBar Should render the given query 1`] = `
<EuiOutsideClickDetector
onOutsideClick={[Function]}
<EuiFlexGroup
alignItems="stretch"
component="div"
direction="row"
gutterSize="s"
justifyContent="flexStart"
responsive={false}
wrap={false}
>
<div
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
<EuiFlexItem
component="div"
grow={true}
>
<form
name="queryBarForm"
role="form"
<EuiOutsideClickDetector
onOutsideClick={[Function]}
>
<div
className="kuiLocalSearch"
role="search"
aria-expanded={false}
aria-haspopup="true"
aria-owns="typeahead-items"
role="combobox"
style={
Object {
"position": "relative",
}
}
>
<div
className="kuiLocalSearchAssistedInput"
<form
name="queryBarForm"
role="form"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={true}
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
className="kuiLocalSearch"
role="search"
>
<QueryLanguageSwitcher
language="kuery"
onSelectLanguage={[Function]}
/>
<div
className="kuiLocalSearchAssistedInput"
>
<EuiFieldText
aria-activedescendant=""
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-label="Search input"
autoComplete="off"
autoFocus={true}
className="kuiLocalSearchAssistedInput__input"
compressed={false}
data-test-subj="queryInput"
fullWidth={true}
icon="console"
inputRef={[Function]}
isLoading={false}
onChange={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
placeholder="Search... (e.g. status:200 AND extension:PHP)"
role="textbox"
spellCheck={false}
type="text"
value="response:200"
/>
<div
className="kuiLocalSearchAssistedInput__assistance"
>
<QueryLanguageSwitcher
language="kuery"
onSelectLanguage={[Function]}
/>
</div>
</div>
</div>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</form>
<SuggestionsComponent
index={null}
loadMore={[Function]}
</EuiOutsideClickDetector>
</EuiFlexItem>
<EuiFlexItem
component="div"
grow={false}
>
<EuiButton
aria-label="Search"
color="primary"
data-test-subj="querySubmitButton"
fill={true}
iconSide="left"
onClick={[Function]}
onMouseEnter={[Function]}
show={false}
suggestions={Array []}
/>
</div>
</EuiOutsideClickDetector>
type="button"
>
Refresh
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
`;

View file

@ -63,6 +63,7 @@ export class QueryLanguageSwitcher extends Component<Props, State> {
return (
<EuiPopover
id="popover"
className="eui-displayBlock"
ownFocus
anchorPosition="downRight"
button={button}

View file

@ -40,7 +40,13 @@ import { matchPairs } from '../lib/match_pairs';
import { QueryLanguageSwitcher } from './language_switcher';
import { SuggestionsComponent } from './typeahead/suggestions_component';
import { EuiFieldText, EuiOutsideClickDetector } from '@elastic/eui';
import {
EuiButton,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiOutsideClickDetector,
} from '@elastic/eui';
const KEY_CODES = {
LEFT: 37,
@ -137,6 +143,10 @@ export class QueryBar extends Component<Props, State> {
private componentIsUnmounting = false;
private persistedLog: PersistedLog | null = null;
public isDirty = () => {
return this.state.query.query !== this.props.query.query;
};
public increaseLimit = () => {
this.setState({
suggestionLimit: this.state.suggestionLimit + 50,
@ -264,6 +274,10 @@ export class QueryBar extends Component<Props, State> {
}
};
public onClickSubmitButton = (event: React.MouseEvent<HTMLButtonElement>) => {
this.onSubmit(() => event.preventDefault());
};
public onClickSuggestion = (suggestion: AutocompleteSuggestion) => {
if (!this.inputRef) {
return;
@ -437,65 +451,81 @@ export class QueryBar extends Component<Props, State> {
public render() {
return (
<EuiOutsideClickDetector onOutsideClick={this.onOutsideClick}>
{/* position:relative required on container so the suggestions appear under the query bar*/}
<div
style={{ position: 'relative' }}
role="combobox"
aria-haspopup="true"
aria-expanded={this.state.isSuggestionsVisible}
aria-owns="typeahead-items"
>
<form role="form" name="queryBarForm">
<div className="kuiLocalSearch" role="search">
<div className="kuiLocalSearchAssistedInput">
<EuiFieldText
placeholder="Search... (e.g. status:200 AND extension:PHP)"
value={this.state.query.query}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
onChange={this.onChange}
onClick={this.onClickInput}
fullWidth
autoFocus={!this.props.disableAutoFocus}
inputRef={node => {
if (node) {
this.inputRef = node;
}
}}
autoComplete="off"
spellCheck={false}
icon="console"
aria-label="Search input"
type="text"
data-test-subj="queryInput"
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-activedescendant={
this.state.isSuggestionsVisible ? 'suggestion-' + this.state.index : ''
}
role="textbox"
/>
<div className="kuiLocalSearchAssistedInput__assistance">
<QueryLanguageSwitcher
language={this.state.query.language}
onSelectLanguage={this.onSelectLanguage}
/>
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiFlexItem>
<EuiOutsideClickDetector onOutsideClick={this.onOutsideClick}>
{/* position:relative required on container so the suggestions appear under the query bar*/}
<div
style={{ position: 'relative' }}
role="combobox"
aria-haspopup="true"
aria-expanded={this.state.isSuggestionsVisible}
aria-owns="typeahead-items"
>
<form role="form" name="queryBarForm">
<div className="kuiLocalSearch" role="search">
<div className="kuiLocalSearchAssistedInput">
<EuiFieldText
className="kuiLocalSearchAssistedInput__input"
placeholder="Search... (e.g. status:200 AND extension:PHP)"
value={this.state.query.query}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
onChange={this.onChange}
onClick={this.onClickInput}
fullWidth
autoFocus={!this.props.disableAutoFocus}
inputRef={node => {
if (node) {
this.inputRef = node;
}
}}
autoComplete="off"
spellCheck={false}
icon="console"
aria-label="Search input"
type="text"
data-test-subj="queryInput"
aria-autocomplete="list"
aria-controls="typeahead-items"
aria-activedescendant={
this.state.isSuggestionsVisible ? 'suggestion-' + this.state.index : ''
}
role="textbox"
/>
<div className="kuiLocalSearchAssistedInput__assistance">
<QueryLanguageSwitcher
language={this.state.query.language}
onSelectLanguage={this.onSelectLanguage}
/>
</div>
</div>
</div>
</div>
</div>
</form>
</form>
<SuggestionsComponent
show={this.state.isSuggestionsVisible}
suggestions={this.state.suggestions.slice(0, this.state.suggestionLimit)}
index={this.state.index}
onClick={this.onClickSuggestion}
onMouseEnter={this.onMouseEnterSuggestion}
loadMore={this.increaseLimit}
/>
</div>
</EuiOutsideClickDetector>
<SuggestionsComponent
show={this.state.isSuggestionsVisible}
suggestions={this.state.suggestions.slice(0, this.state.suggestionLimit)}
index={this.state.index}
onClick={this.onClickSuggestion}
onMouseEnter={this.onMouseEnterSuggestion}
loadMore={this.increaseLimit}
/>
</div>
</EuiOutsideClickDetector>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
aria-label="Search"
data-test-subj="querySubmitButton"
color={this.isDirty() ? 'secondary' : 'primary'}
fill
onClick={this.onClickSubmitButton}
>
{this.isDirty() ? 'Update' : 'Refresh'}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
);
}
}

View file

@ -8,7 +8,7 @@
color: $euiTextColor;
background-color: $euiColorEmptyShade;
position: absolute;
top: -10px;
top: -8px;
z-index: $euiZContentMenu;
width: 100%;
border-radius: $euiBorderRadius;

View file

@ -3,6 +3,7 @@
* won't overlap if the user increases their default browser font size
* This is sized for the 'Uses lucene query syntax' link
*/
.kuiLocalSearchInput {
.kuiLocalSearchInput,
.kuiLocalSearchAssistedInput__input {
padding-right: 6em; /* 1 */
}