diff --git a/frontend/index.js b/frontend/index.js index d08aaf8e..1a793b50 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -79,6 +79,7 @@ render( + diff --git a/frontend/scenes/Search/Search.js b/frontend/scenes/Search/Search.js index 44291f8b..e423bc3e 100644 --- a/frontend/scenes/Search/Search.js +++ b/frontend/scenes/Search/Search.js @@ -3,6 +3,8 @@ import React from 'react'; import { observer } from 'mobx-react'; import _ from 'lodash'; import { Flex } from 'reflexbox'; +import { withRouter } from 'react-router'; +import { searchUrl } from 'utils/routeHelpers'; import SearchField from './components/SearchField'; import styles from './Search.scss'; @@ -13,6 +15,8 @@ import CenteredContent from 'components/CenteredContent'; import DocumentPreview from 'components/DocumentPreview'; type Props = { + history: Object, + match: Object, notFound: ?boolean, }; @@ -23,12 +27,31 @@ type Props = { constructor(props: Props) { super(props); this.store = new SearchStore(); + this.updateSearchResults(); } + componentDidUpdate(prevProps) { + if (prevProps.match.params.query !== this.props.match.params.query) { + this.updateSearchResults(); + } + } + + handleKeyDown = ev => { + if (ev.which === 27) { + ev.preventDefault(); + this.props.history.goBack(); + } + }; + + updateSearchResults = _.debounce(() => { + this.store.search(this.props.match.params.query); + }, 250); + + updateQuery = query => { + this.props.history.replace(searchUrl(query)); + }; + render() { - const search = _.debounce(searchTerm => { - this.store.search(searchTerm); - }, 250); const title = ; return ( @@ -55,15 +78,13 @@ type Props = { /> <SearchField searchTerm={this.store.searchTerm} - onChange={search} + onKeyDown={this.handleKeyDown} + onChange={this.updateQuery} /> </Flex> - {this.store.documents && - this.store.documents.map(document => { - return ( - <DocumentPreview key={document.id} document={document} /> - ); - })} + {this.store.documents.map(document => ( + <DocumentPreview key={document.id} document={document} /> + ))} </Flex> </CenteredContent> </Layout> @@ -71,4 +92,4 @@ type Props = { } } -export default Search; +export default withRouter(Search); diff --git a/frontend/scenes/Search/SearchStore.js b/frontend/scenes/Search/SearchStore.js index b77a2934..0800b34b 100644 --- a/frontend/scenes/Search/SearchStore.js +++ b/frontend/scenes/Search/SearchStore.js @@ -5,7 +5,7 @@ import { client } from 'utils/ApiClient'; import type { Document } from 'types'; class SearchStore { - @observable documents: ?(Document[]); + @observable documents: Array<Document> = []; @observable searchTerm: ?string = null; @observable isFetching = false; @@ -28,7 +28,7 @@ class SearchStore { console.error('Something went wrong'); } } else { - this.documents = null; + this.documents = []; } this.isFetching = false; diff --git a/frontend/scenes/Search/components/SearchField/SearchField.js b/frontend/scenes/Search/components/SearchField/SearchField.js index 0061cb9a..9730dd95 100644 --- a/frontend/scenes/Search/components/SearchField/SearchField.js +++ b/frontend/scenes/Search/components/SearchField/SearchField.js @@ -1,15 +1,13 @@ // @flow -import React, { PropTypes } from 'react'; -import { observer } from 'mobx-react'; - +import React, { Component } from 'react'; import styles from './SearchField.scss'; -@observer class SearchField extends React.Component { - static propTypes = { - onChange: PropTypes.func, +class SearchField extends Component { + props: { + onChange: Function, }; - onChange = (event: SyntheticEvent) => { + handleChange = (event: SyntheticEvent) => { event.currentTarget.value && this.props.onChange(event.currentTarget.value); }; @@ -17,7 +15,8 @@ import styles from './SearchField.scss'; return ( <div className={styles.container}> <input - onChange={this.onChange} + {...this.props} + onChange={this.handleChange} className={styles.field} placeholder="Search" autoFocus diff --git a/frontend/utils/routeHelpers.js b/frontend/utils/routeHelpers.js new file mode 100644 index 00000000..0e0d46b6 --- /dev/null +++ b/frontend/utils/routeHelpers.js @@ -0,0 +1,13 @@ +// @flow + +export function homeUrl() { + return '/dashboard'; +} + +export function newCollectionUrl() { + return '/collections/new'; +} + +export function searchUrl(query: string) { + return `/search/${query}`; +}