application/components/search.js
import React from 'react';
import {connect} from 'react-redux';
import {browserHistory} from 'react-router';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import Divider from 'material-ui/Divider';
import LoadingIndicator from './common/loading-indicator';
import {Row, Col} from './flexbox';
import Config from './../config';
import CurrentUser from './../current-user';
import Request from './../util/request';
import SearchResultsTable from './search/result-table';
import ReduxPaginator from './common/redux-paginator';
import {ENTER_KEY} from '../util/key-codes';
import {parameterize} from '../util/strings';
import {
globalSearchFetch
} from './../redux/actions/global-search-actions';
export function buildQuery(query) {
const req = {
keywords: query.q
};
let filter = {};
if (query.type && query.type !== 'undefined') {
req['type'] = query.type;
}
if (query.has_attachment && query.has_attachment !== 'undefined') {
req['has_attachment'] = query.has_attachment;
}
if (query.filter_content_type && query.filter_content_type !== 'undefined') {
filter = Object.assign({}, filter, {
'content_type': query.filter_content_type
});
}
if (query.author && query.author !== 'undefined') {
req['author'] = query.author;
}
if (query.tag && query.tag !== 'undefined') {
req['tag'] = query.tag;
}
if (query.page && query.page !== 'undefined') {
req['page'] = query.page;
}
if (query.limit && query.limit !== 'undefined') {
req['limit'] = query.limit;
}
if (query.sort && query.sort !== 'undefined') {
req['sort'] = query.sort;
}
if (filter) {
req['filters'] = filter;
}
return req;
}
class Search extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedType: null
};
}
componentDidMount() {
if (this.props.router.location.query.q ) {
this.runSearch.call(this);
}
if (this.props.router.location.query.filter_content_type) {
this.setState({
'selectedType':
this.props.router.location.query.filter_content_type
});
}
}
handlePagination(page) {
// Use setQuery here so we don't replace existing bits
const url = '/ceo/search?' + Request.setQuery({'page': page});
browserHistory.push(url);
}
runSearch() {
const {dispatch} = this.props;
const query = buildQuery(this.props.router.location.query);
dispatch(globalSearchFetch(query));
}
handleTypeChange(e, index, value) {
this.setState({'selectedType': value});
}
handleAdvancedSearch(e) {
let query = {
q: this.refs.keywords.input.value,
author: this.refs.author.input.value,
tag: this.refs.tag.input.value
};
const selectedType = this.state.selectedType;
if (selectedType) {
query['filter_content_type'] = selectedType;
}
// Use parameterize here because we want to replace everything
const url = '/ceo/search?' + parameterize(query);
browserHistory.push(url);
}
handleKeyUp(e) {
if (e.keyCode !== ENTER_KEY) {
return;
}
this.handleAdvancedSearch.call(this);
}
render() {
return (
<div className='search-root'>
<Row>
<Col xs={12}>
<Paper className='padded'>
<Row>
<Col xs={3}>
<TextField
floatingLabelText='Keywords'
ref='keywords'
defaultValue={this.props.router.location.query.q ? this.props.router.location.query.q : null}
onKeyUp={this.handleKeyUp.bind(this)}
fullWidth={true}
/>
<SelectField
floatingLabelText='Type'
ref='type'
value={this.state.selectedType}
onChange={this.handleTypeChange.bind(this)}
fullWidth={true}
>
<MenuItem value={null} />
<MenuItem value='article' primaryText='Article' />
<MenuItem value='media' primaryText='Media' />
<MenuItem value='post' primaryText='Post' />
<MenuItem value='page' primaryText='Page' />
</SelectField>
<TextField
floatingLabelText='Tag'
ref='tag'
defaultValue={this.props.router.location.query.tag ? this.props.router.location.query.tag : null}
onKeyUp={this.handleKeyUp.bind(this)}
fullWidth={true}
/>
<TextField
floatingLabelText='Author'
ref='author'
defaultValue={this.props.router.location.query.author ? this.props.router.location.query.author : null}
onKeyUp={this.handleKeyUp.bind(this)}
fullWidth={true}
/>
<RaisedButton
className='clear-top'
label='Search'
primary={true}
onClick={this.handleAdvancedSearch.bind(this)}
/>
</Col>
<Col xs={9}>
{
!this.props.globalSearch.didSearch
? (
<div className='clear-top'>
<p>
Search all CEO content.
</p>
</div>
)
: (
<div>
<Row bottom='xs'>
<Col xs={4}>
Found {parseInt(this.props.globalSearch.pagination.total_items)} result(s)
</Col>
<Col xs={8} end='xs'>
<ReduxPaginator pagination={this.props.globalSearch.pagination} onPaginate={this.handlePagination.bind(this)} />
</Col>
</Row>
{
this.props.globalSearch.isFetching
? <LoadingIndicator />
: <SearchResultsTable />
}
</div>
)
}
</Col>
</Row>
</Paper>
</Col>
</Row>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
globalSearch: state.globalSearch
}
}
export default connect(mapStateToProps)(Search);