X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/f87e91a3d8cfbcd1bebf116701423c2c54bc5e19..040d25dbcc9ec46c4c21c945ccf02dcf1bf44c26:/src/components/main-app-bar/search-bar/search-bar.tsx?ds=sidebyside diff --git a/src/components/main-app-bar/search-bar/search-bar.tsx b/src/components/main-app-bar/search-bar/search-bar.tsx index c07ddca844..f9e93d679c 100644 --- a/src/components/main-app-bar/search-bar/search-bar.tsx +++ b/src/components/main-app-bar/search-bar/search-bar.tsx @@ -3,57 +3,87 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, Paper, Input, StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core'; -import NotificationsIcon from '@material-ui/icons/Notifications'; -import PersonIcon from '@material-ui/icons/Person'; -import HelpIcon from '@material-ui/icons/Help'; +import { IconButton, Paper, StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core'; import SearchIcon from '@material-ui/icons/Search'; -import { AppBarProps } from '@material-ui/core/AppBar'; interface SearchBarDataProps { value: string; } interface SearchBarActionProps { - onChange: (value: string) => any; - onSubmit: () => any; + onSearch: (value: string) => any; + debounce?: number; } -type SearchBarProps = SearchBarDataProps & SearchBarActionProps & WithStyles +type SearchBarProps = SearchBarDataProps & SearchBarActionProps & WithStyles; + +interface SearchBarState { + value: string; +} + +export const DEFAULT_SEARCH_DEBOUNCE = 1000; class SearchBar extends React.Component { + + state: SearchBarState = { + value: "" + }; + + timeout: NodeJS.Timer; + render() { - const { classes } = this.props + const { classes } = this.props; return
-
+ ; + } + + componentDidMount() { + this.setState({value: this.props.value}); + } + + componentWillReceiveProps(nextProps: SearchBarProps) { + if (nextProps.value !== this.props.value) { + this.setState({ value: nextProps.value }); + } + } + + componentWillUnmount() { + clearTimeout(this.timeout); } handleSubmit = (event: React.FormEvent) => { event.preventDefault(); - this.props.onSubmit(); + clearTimeout(this.timeout); + this.props.onSearch(this.state.value); } handleChange = (event: React.ChangeEvent) => { - this.props.onChange(event.target.value); + clearTimeout(this.timeout); + this.setState({ value: event.target.value }); + this.timeout = setTimeout( + () => this.props.onSearch(this.state.value), + this.props.debounce || DEFAULT_SEARCH_DEBOUNCE + ); + } } -type CssRules = 'container' | 'input' | 'button' +type CssRules = 'container' | 'input' | 'button'; const styles: StyleRulesCallback = theme => { - const { unit } = theme.spacing + const { unit } = theme.spacing; return { container: { position: 'relative', @@ -74,7 +104,7 @@ const styles: StyleRulesCallback = theme => { width: unit * 3, height: unit * 3 } - } -} + }; +}; -export default withStyles(styles)(SearchBar) \ No newline at end of file +export default withStyles(styles)(SearchBar); \ No newline at end of file