Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,33 @@
/**
* External dependencies
*/
import { h, Component } from 'preact';
import { h, createRef, Component } from 'preact';
import strip from 'strip';
import { getCheckedInputNames } from '../lib/dom';

export default class SearchFilterPostTypes extends Component {
constructor( props ) {
super( props );
this.state = { selected: this.props.initialValue };
this.filtersList = createRef();
}

toggleFilter = () => {
const selected = getCheckedInputNames( this.filtersList.current );
this.setState( { selected }, () => {
this.props.onChange( 'postTypes', selected );
} );
};

renderPostType = ( { key, doc_count: count } ) => {
const name = this.props.postTypes[ key ];
const name = key in this.props.postTypes ? this.props.postTypes[ key ] : key;
return (
<div>
<input
disabled
checked={ this.state.selected.includes( key ) }
id={ `jp-instant-search-filter-post-types-${ key }` }
name={ key }
onChange={ this.toggleFilter }
type="checkbox"
/>
<label htmlFor={ `jp-instant-search-filter-post-types-${ key }` }>
Expand All @@ -26,8 +41,10 @@ export default class SearchFilterPostTypes extends Component {
render() {
return (
<div>
<h4 className="jetpack-search-filters-widget__sub-heading">{ this.props.filter.name }</h4>
<ul className="jetpack-search-filters-widget__filter-list">
<h4 className="jetpack-search-filters-widget__sub-heading">
{ this.props.configuration.name }
</h4>
<ul className="jetpack-search-filters-widget__filter-list" ref={ this.filtersList }>
{ this.props.aggregation &&
'buckets' in this.props.aggregation &&
this.props.aggregation.buckets.map( this.renderPostType ) }
Expand Down
20 changes: 13 additions & 7 deletions modules/search/instant-search/components/search-filters-widget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@ import SearchFilterTaxonomies from './search-filter-taxonomies';
import SearchFilterPostTypes from './search-filter-post-types';

export default class SearchFiltersWidget extends Component {
renderFilterComponent = ( { filter, results } ) => {
switch ( filter.type ) {
renderFilterComponent = ( { configuration, results } ) => {
switch ( configuration.type ) {
case 'date_histogram':
return results && <SearchFilterDates aggregation={ results } filter={ filter } />;
return results && <SearchFilterDates aggregation={ results } filter={ configuration } />;
case 'taxonomy':
return results && <SearchFilterTaxonomies aggregation={ results } filter={ filter } />;
return (
results && <SearchFilterTaxonomies aggregation={ results } filter={ configuration } />
);
case 'post_type':
return (
results && (
<SearchFilterPostTypes
aggregation={ results }
filter={ filter }
configuration={ configuration }
initialValue={ this.props.initialValues.postTypes }
onChange={ this.props.onChange }
postTypes={ this.props.postTypes }
/>
)
Expand All @@ -41,8 +45,10 @@ export default class SearchFiltersWidget extends Component {
return (
<div className="jetpack-instant-search__filters-widget">
{ get( this.props.widget, 'filters' )
.map( filter =>
aggregations ? { filter, results: aggregations[ filter.filter_id ] } : null
.map( configuration =>
aggregations
? { configuration, results: aggregations[ configuration.filter_id ] }
: null
)
.filter( data => !! data )
.filter(
Expand Down
25 changes: 16 additions & 9 deletions modules/search/instant-search/components/search-widget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import debounce from 'lodash/debounce';
import SearchResults from './search-results';
import SearchFiltersWidget from './search-filters-widget';
import { search, buildFilterAggregations } from '../lib/api';
import { setSearchQuery } from '../lib/query-string';
import { setSearchQuery, setFilterQuery, getFilterQuery } from '../lib/query-string';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a drive by-comment, but to save on the bundle size, it might make sense to rely on external @wordpress/url

import { removeChildren, hideSearchHeader } from '../lib/dom';

class SearchApp extends Component {
Expand All @@ -32,7 +32,7 @@ class SearchApp extends Component {
results: {},
};
this.getResults = debounce( this.getResults, 500 );
this.getResults( this.props.initialValue );
this.getResults( this.state.query, getFilterQuery() );
}

componentDidMount() {
Expand All @@ -54,18 +54,23 @@ class SearchApp extends Component {
this.getResults( query );
};

getResults = query => {
onChangeFilter = ( filterName, filterValue ) => {
setFilterQuery( filterName, filterValue );
this.getResults( this.state.query, getFilterQuery() );
};

getResults = ( query, filter ) => {
if ( query ) {
this.requestId++;
const requestId = this.requestId;

search(
this.props.options.siteId,
search( {
aggregations: this.props.aggregations,
filter,
query,
this.props.aggregations,
{},
this.props.options.resultFormat
)
resultFormat: this.props.options.resultFormat,
siteId: this.props.options.siteId,
} )
.then( response => response.json() )
.then( json => {
if ( this.requestId === requestId ) {
Expand Down Expand Up @@ -102,6 +107,8 @@ class SearchApp extends Component {
</div>
<div className="jetpack-search-sort-wrapper" />
<SearchFiltersWidget
initialValues={ this.props.initialFilters }
onChange={ this.onChangeFilter }
postTypes={ this.props.options.postTypes }
results={ this.state.results }
widget={ widget }
Expand Down
7 changes: 4 additions & 3 deletions modules/search/instant-search/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import { h, render } from 'preact';
* Internal dependencies
*/
import SearchWidget from './components/search-widget';
import { getSearchQuery } from './lib/query-string';
import { getSearchQuery, getFilterQuery } from './lib/query-string';

const injectSearchWidget = ( initialValue, grabFocus ) => {
const injectSearchWidget = grabFocus => {
render(
<SearchWidget
grabFocus={ grabFocus }
initialValue={ initialValue }
initialFilters={ getFilterQuery() }
initialValue={ getSearchQuery() }
options={ window.JetpackInstantSearchOptions }
/>,
document.body
Expand Down
18 changes: 16 additions & 2 deletions modules/search/instant-search/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,21 @@ export function buildFilterAggregations( widgets = [] ) {
return aggregation;
}

export function search( siteId, query, aggregations, filter, resultFormat ) {
function buildFilterObject( filterQuery ) {
if ( ! filterQuery ) {
return {};
}

const filter = { bool: { must: [] } };
if ( Array.isArray( filterQuery.postTypes ) && filterQuery.postTypes.length > 0 ) {
filterQuery.postTypes.forEach( postType => {
filter.bool.must.push( { term: { post_type: postType } } );
} );
}
return filter;
}

export function search( { aggregations, filter, query, resultFormat, siteId } ) {
let fields = [];
let highlight_fields = [];
switch ( resultFormat ) {
Expand All @@ -62,7 +76,7 @@ export function search( siteId, query, aggregations, filter, resultFormat ) {
aggregations,
fields,
highlight_fields,
filter,
filter: buildFilterObject( filter ),
query: encodeURIComponent( query ),
} )
);
Expand Down
6 changes: 6 additions & 0 deletions modules/search/instant-search/lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ export function hideSearchHeader() {
title.style.display = 'none';
}
}

export function getCheckedInputNames( parentDom ) {
return [ ...parentDom.querySelectorAll( 'input[type="checkbox"]' ).values() ]
.filter( input => input.checked )
.map( input => input.name );
}
27 changes: 27 additions & 0 deletions modules/search/instant-search/lib/query-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,30 @@ export function setSearchQuery( searchValue ) {
query.s = searchValue;
pushQueryString( encode( query ) );
}

function getFilterQueryByKey( filterKey ) {
const query = getQuery();
if ( ! ( filterKey in query ) ) {
return [];
}
if ( typeof query[ filterKey ] === 'string' ) {
return [ query[ filterKey ] ];
}
return query[ filterKey ];
}

export function getFilterQuery( filterKey ) {
if ( filterKey ) {
return getFilterQueryByKey( filterKey );
}

return {
postTypes: getFilterQueryByKey( 'postTypes' ),
};
}

export function setFilterQuery( filterKey, filterValue ) {
const query = getQuery();
query[ filterKey ] = filterValue;
pushQueryString( encode( query ) );
}