Filters: fix updates and configs

This commit is contained in:
Paul Sealock 2018-10-16 13:45:41 +13:00
parent 74d8d431e4
commit aa603eabab
5 changed files with 119 additions and 46 deletions

View File

@ -14,6 +14,11 @@ const { orderStatuses } = wcSettings;
export const filters = [ export const filters = [
{ label: __( 'All Orders', 'wc-admin' ), value: 'all' }, { label: __( 'All Orders', 'wc-admin' ), value: 'all' },
{ label: __( 'New Customers', 'wc-admin' ), value: 'new_customers' },
{
label: __( 'Returning Customers', 'wc-admin' ),
value: 'returning_customers',
},
{ label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' }, { label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' },
]; ];

View File

@ -14,12 +14,24 @@ export const filters = [
{ label: __( 'All Products', 'wc-admin' ), value: 'all' }, { label: __( 'All Products', 'wc-admin' ), value: 'all' },
{ {
label: __( 'Single Product', 'wc-admin' ), label: __( 'Single Product', 'wc-admin' ),
value: 'single', value: 'single_product',
subFilters: [ subFilters: [
{ {
component: 'Search', component: 'Search',
value: 'single_search', value: 'product',
path: [ 'single' ], path: [ 'single_product' ],
settings: {
type: 'products',
param: 'product',
getLabels: getRequestByIdString( NAMESPACE + 'products', product => ( {
id: product.id,
label: product.name,
} ) ),
labels: {
placeholder: __( 'Type to search for a product', 'wc-admin' ),
button: __( 'Single Product', 'wc-admin' ),
},
},
}, },
], ],
}, },
@ -59,6 +71,12 @@ export const filters = [
}, },
}, },
}, },
{ label: __( 'Top Products by Items Sold', 'wc-admin' ), value: 'top_items' }, {
{ label: __( 'Top Products by Gross Sales', 'wc-admin' ), value: 'top_sales' }, label: __( 'Top Products by Items Sold', 'wc-admin' ),
value: 'top_items',
},
{
label: __( 'Top Products by Gross Sales', 'wc-admin' ),
value: 'top_sales',
},
]; ];

View File

@ -41,7 +41,7 @@ class CompareFilter extends Component {
/* eslint-disable react/no-did-update-set-state */ /* eslint-disable react/no-did-update-set-state */
this.setState( { selected: [] } ); this.setState( { selected: [] } );
/* eslint-enable react/no-did-update-set-state */ /* eslint-enable react/no-did-update-set-state */
updateQueryString( { [ param ]: '' }, path, query ); updateQueryString( { [ param ]: undefined }, path, query );
return; return;
} }

View File

@ -5,8 +5,8 @@
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { Button, Dropdown, IconButton } from '@wordpress/components'; import { Button, Dropdown, IconButton } from '@wordpress/components';
import classnames from 'classnames'; import classnames from 'classnames';
import { Component, Fragment } from '@wordpress/element'; import { Component } from '@wordpress/element';
import { find, omit, partial } from 'lodash'; import { find, omit, partial, pick, last, get, includes } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
/** /**
@ -14,6 +14,7 @@ import PropTypes from 'prop-types';
*/ */
import AnimationSlider from 'components/animation-slider'; import AnimationSlider from 'components/animation-slider';
import DropdownButton from 'components/dropdown-button'; import DropdownButton from 'components/dropdown-button';
import Search from 'components/search';
import { updateQueryString } from 'lib/nav-utils'; import { updateQueryString } from 'lib/nav-utils';
import './style.scss'; import './style.scss';
@ -27,15 +28,28 @@ class FilterPicker extends Component {
constructor( props ) { constructor( props ) {
super( props ); super( props );
const { path = [] } = this.getFilter(); const selectedFilter = this.getFilter();
this.state = { this.state = {
nav: path, nav: selectedFilter.path || [],
animate: null, animate: null,
selectedTag: null,
}; };
this.selectSubFilters = this.selectSubFilters.bind( this ); this.selectSubFilter = this.selectSubFilter.bind( this );
this.getVisibleFilters = this.getVisibleFilters.bind( this ); this.getVisibleFilters = this.getVisibleFilters.bind( this );
this.updateSelectedTag = this.updateSelectedTag.bind( this );
this.onTagChange = this.onTagChange.bind( this );
this.goBack = this.goBack.bind( this ); this.goBack = this.goBack.bind( this );
if ( selectedFilter.settings && selectedFilter.settings.getLabels ) {
const { query } = this.props;
const { param, getLabels } = selectedFilter.settings;
getLabels( query[ param ] ).then( this.updateSelectedTag );
}
}
updateSelectedTag( tags ) {
this.setState( { selectedTag: tags[ 0 ] } );
} }
getAllFilters( filters ) { getAllFilters( filters ) {
@ -59,8 +73,11 @@ class FilterPicker extends Component {
return find( allFilters, { value } ) || {}; return find( allFilters, { value } ) || {};
} }
getLabels( selectedFilter ) { getButtonLabel( selectedFilter ) {
// @TODO: handle single product secondary labels if ( 'Search' === selectedFilter.component ) {
const { selectedTag } = this.state;
return [ selectedTag && selectedTag.label, get( selectedFilter, 'settings.labels.button' ) ];
}
return selectedFilter ? [ selectedFilter.label ] : []; return selectedFilter ? [ selectedFilter.label ] : [];
} }
@ -73,7 +90,7 @@ class FilterPicker extends Component {
return this.getVisibleFilters( nextFilters && nextFilters.subFilters, nav.slice( 1 ) ); return this.getVisibleFilters( nextFilters && nextFilters.subFilters, nav.slice( 1 ) );
} }
selectSubFilters( value ) { selectSubFilter( value ) {
// Add the value onto the nav path // Add the value onto the nav path
this.setState( prevState => ( { nav: [ ...prevState.nav, value ], animate: 'left' } ) ); this.setState( prevState => ( { nav: [ ...prevState.nav, value ], animate: 'left' } ) );
} }
@ -83,41 +100,59 @@ class FilterPicker extends Component {
this.setState( prevState => ( { nav: prevState.nav.slice( 0, -1 ), animate: 'right' } ) ); this.setState( prevState => ( { nav: prevState.nav.slice( 0, -1 ), animate: 'right' } ) );
} }
renderButton( filter, onClose ) { update( value, additionalQueries = {} ) {
if ( filter.subFilters ) {
return (
<Button
className="woocommerce-filters-filter__button"
onClick={ partial( this.selectSubFilters, filter.value ) }
>
{ filter.label }
</Button>
);
}
if ( filter.component ) {
return (
<Fragment>
{ filter.label && (
<span className="woocommerce-filters-filter__button">{ filter.label }</span>
) }
<input
type="text"
style={ { width: '100%', margin: '0' } }
placeholder="Search Placeholder"
/>
</Fragment>
);
}
const { path, query } = this.props; const { path, query } = this.props;
const onClick = event => { // Keep only time related queries when updating to a new filter
const timeRelatedQueries = pick( query, [ 'period', 'compare', 'before', 'after' ] );
const update = {
filter: 'all' === value ? undefined : value,
...additionalQueries,
};
updateQueryString( update, path, timeRelatedQueries );
}
onTagChange( filter, onClose, tags ) {
const tag = last( tags );
const { value, settings } = filter;
const { param } = settings;
if ( tag ) {
this.update( value, { [ param ]: tag.id } );
onClose();
} else {
this.update( 'all' );
}
this.updateSelectedTag( [ tag ] );
}
renderButton( filter, onClose ) {
if ( filter.component ) {
const { type, labels } = filter.settings;
const { selectedTag } = this.state;
return (
<Search
className="woocommerce-filters-filter__search"
type={ type }
placeholder={ labels.placeholder }
selected={ selectedTag ? [ selectedTag ] : [] }
onChange={ partial( this.onTagChange, filter, onClose ) }
inlineTags
/>
);
}
const selectFilter = event => {
onClose( event ); onClose( event );
updateQueryString( { filter: filter.value }, path, query ); this.update( filter.value );
this.setState( { selectedTag: null } );
}; };
const selectSubFilter = partial( this.selectSubFilter, filter.value );
return ( return (
<Button className="woocommerce-filters-filter__button" onClick={ onClick }> <Button
className="woocommerce-filters-filter__button"
onClick={ filter.subFilters ? selectSubFilter : selectFilter }
>
{ filter.label } { filter.label }
</Button> </Button>
); );
@ -141,7 +176,7 @@ class FilterPicker extends Component {
<DropdownButton <DropdownButton
onClick={ onToggle } onClick={ onToggle }
isOpen={ isOpen } isOpen={ isOpen }
labels={ this.getLabels( selectedFilter ) } labels={ this.getButtonLabel( selectedFilter ) }
/> />
) } ) }
renderContent={ ( { onClose } ) => ( renderContent={ ( { onClose } ) => (
@ -163,7 +198,9 @@ class FilterPicker extends Component {
<li <li
key={ filter.value } key={ filter.value }
className={ classnames( 'woocommerce-filters-filter__content-list-item', { className={ classnames( 'woocommerce-filters-filter__content-list-item', {
'is-selected': selectedFilter.value === filter.value, 'is-selected':
selectedFilter.value === filter.value ||
( selectedFilter.path && includes( selectedFilter.path, filter.value ) ),
} ) } } ) }
> >
{ this.renderButton( filter, onClose ) } { this.renderButton( filter, onClose ) }

View File

@ -72,3 +72,16 @@
margin-right: $gap; margin-right: $gap;
} }
} }
.woocommerce-filters-filter__search {
.woocommerce-search__autocomplete-results {
position: static;
}
.woocommerce-search__inline-container {
overflow: hidden;
&:not(.is-active) {
border: none;
}
}
}