1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
13 InputAdornment, Input,
14 ListItem, ListItemText, ListItemSecondaryAction,
16 } from '@material-ui/core';
17 import SearchIcon from '@material-ui/icons/Search';
18 import { RemoveIcon } from '~/components/icon/icon';
19 import { SearchView } from '~/store/search-bar/search-bar-reducer';
20 import { SearchBarBasicView } from '~/views-components/search-bar/search-bar-basic-view';
21 import { SearchBarAdvancedView } from '~/views-components/search-bar/search-bar-advanced-view';
22 import { SearchBarAutocompleteView } from '~/views-components/search-bar/search-bar-autocomplete-view';
24 type CssRules = 'container' | 'input' | 'searchBar';
26 const styles: StyleRulesCallback<CssRules> = theme => {
35 padding: `0px ${theme.spacing.unit}px`
43 interface SearchBarDataProps {
49 interface SearchBarActionProps {
50 onSearch: (value: string) => any;
52 onSetView: (currentView: string) => void;
54 closeView: () => void;
57 type SearchBarProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
59 interface SearchBarState {
63 interface RenderQueriesProps {
67 export const RenderRecentQueries = (props: RenderQueriesProps) => {
68 return <ListItem button>
69 <ListItemText secondary={props.text} />
74 export const RenderSavedQueries = (props: RenderQueriesProps) => {
75 return <ListItem button>
76 <ListItemText secondary={props.text} />
77 <ListItemSecondaryAction>
78 <Tooltip title="Remove">
79 <IconButton aria-label="Remove">
83 </ListItemSecondaryAction>
87 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
89 export const SearchBarView = withStyles(styles)(
90 class extends React.Component<SearchBarProps> {
91 state: SearchBarState = {
98 const { classes, currentView, openView, closeView, open } = this.props;
99 return <ClickAwayListener onClickAway={() => closeView()}>
100 <Paper className={classes.container} >
101 <form onSubmit={this.handleSubmit} className={classes.searchBar}>
103 className={classes.input}
104 onChange={this.handleChange}
106 value={this.state.value}
108 disableUnderline={true}
109 onClick={() => openView()}
111 <InputAdornment position="end">
112 <Tooltip title='Search'>
119 {open && this.getView(currentView)}
122 </ClickAwayListener>;
125 componentDidMount() {
126 this.setState({ value: this.props.value });
129 componentWillReceiveProps(nextProps: SearchBarProps) {
130 if (nextProps.value !== this.props.value) {
131 this.setState({ value: nextProps.value });
135 componentWillUnmount() {
136 clearTimeout(this.timeout);
139 getView = (currentView: string) => {
140 switch (currentView) {
141 case SearchView.BASIC:
142 return <SearchBarBasicView setView={this.props.onSetView} />;
143 case SearchView.ADVANCED:
144 return <SearchBarAdvancedView setView={this.props.onSetView} />;
145 case SearchView.AUTOCOMPLETE:
146 return <SearchBarAutocompleteView />;
148 return <SearchBarBasicView setView={this.props.onSetView} />;
152 handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
153 event.preventDefault();
154 clearTimeout(this.timeout);
155 this.props.onSearch(this.state.value);
158 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
159 clearTimeout(this.timeout);
160 this.setState({ value: event.target.value });
161 this.timeout = window.setTimeout(
162 () => this.props.onSearch(this.state.value),
163 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE
165 if (event.target.value.length > 0) {
166 this.props.onSetView(SearchView.AUTOCOMPLETE);
168 this.props.onSetView(SearchView.BASIC);