Search improves (#67)
* ESC should go back from search using direct onKeyDown here as react-keydown does not trigger within an input * Addressable search urls
This commit is contained in:
parent
87adccb816
commit
3353eb913a
|
@ -79,6 +79,7 @@ render(
|
|||
<Route exact path="/d/:id/new" component={DocumentNewChild} />
|
||||
|
||||
<Route exact path="/search" component={Search} />
|
||||
<Route exact path="/search/:query" component={Search} />
|
||||
<Route exact path="/settings" component={Settings} />
|
||||
|
||||
<Route exact path="/auth/slack" component={SlackAuth} />
|
||||
|
|
|
@ -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 = <Title content="Search" />;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// @flow
|
||||
|
||||
export function homeUrl() {
|
||||
return '/dashboard';
|
||||
}
|
||||
|
||||
export function newCollectionUrl() {
|
||||
return '/collections/new';
|
||||
}
|
||||
|
||||
export function searchUrl(query: string) {
|
||||
return `/search/${query}`;
|
||||
}
|
Reference in New Issue