Merge pull request woocommerce/woocommerce-admin#457 from woocommerce/fix/advanced-filters-i18n
i18n: Advanced Filters strings
This commit is contained in:
commit
4bc8c82820
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __, _x } from '@wordpress/i18n';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -30,87 +30,123 @@ export const filters = [
|
||||||
{ label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' },
|
{ label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/*eslint-disable max-len*/
|
||||||
export const advancedFilterConfig = {
|
export const advancedFilterConfig = {
|
||||||
status: {
|
title: _x(
|
||||||
labels: {
|
'Orders Match {{select /}} Filters',
|
||||||
add: __( 'Order Status', 'wc-admin' ),
|
'A sentence describing filters for Orders. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ',
|
||||||
remove: __( 'Remove order status filter', 'wc-admin' ),
|
'wc-admin'
|
||||||
rule: __( 'Select an order status filter match', 'wc-admin' ),
|
),
|
||||||
title: __( 'Order Status', 'wc-admin' ),
|
filters: {
|
||||||
},
|
status: {
|
||||||
rules: [
|
labels: {
|
||||||
{ value: 'is', label: __( 'Is', 'wc-admin' ) },
|
add: __( 'Order Status', 'wc-admin' ),
|
||||||
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) },
|
remove: __( 'Remove order status filter', 'wc-admin' ),
|
||||||
],
|
rule: __( 'Select an order status filter match', 'wc-admin' ),
|
||||||
input: {
|
/* translators: A sentence describing an Order Status filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
component: 'SelectControl',
|
title: __( 'Order Status {{rule /}} {{filter /}}', 'wc-admin' ),
|
||||||
options: Object.keys( orderStatuses ).map( key => ( {
|
filter: __( 'Select an order status', 'wc-admin' ),
|
||||||
value: key,
|
},
|
||||||
label: orderStatuses[ key ],
|
rules: [
|
||||||
} ) ),
|
{
|
||||||
defaultOption: 'wc-cancelled',
|
value: 'is',
|
||||||
},
|
/* translators: Sentence fragment, logical, "Is" refers to searching for orders matching a chosen order status. Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
},
|
label: _x( 'Is', 'order status', 'wc-admin' ),
|
||||||
product_id: {
|
},
|
||||||
labels: {
|
{
|
||||||
add: __( 'Products', 'wc-admin' ),
|
value: 'is_not',
|
||||||
placeholder: __( 'Search products', 'wc-admin' ),
|
/* translators: Sentence fragment, logical, "Is Not" refers to searching for orders that don\'t match a chosen order status. Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
remove: __( 'Remove products filter', 'wc-admin' ),
|
label: _x( 'Is Not', 'order status', 'wc-admin' ),
|
||||||
rule: __( 'Select a product filter match', 'wc-admin' ),
|
},
|
||||||
title: __( 'Product', 'wc-admin' ),
|
|
||||||
},
|
|
||||||
rules: [
|
|
||||||
{ value: 'includes', label: __( 'Includes', 'wc-admin' ) },
|
|
||||||
{ value: 'excludes', label: __( 'Excludes', 'wc-admin' ) },
|
|
||||||
{ value: 'is', label: __( 'Is', 'wc-admin' ) },
|
|
||||||
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) },
|
|
||||||
],
|
|
||||||
input: {
|
|
||||||
component: 'Search',
|
|
||||||
type: 'products',
|
|
||||||
getLabels: getRequestByIdString( NAMESPACE + 'products', product => ( {
|
|
||||||
id: product.id,
|
|
||||||
label: product.name,
|
|
||||||
} ) ),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
code: {
|
|
||||||
labels: {
|
|
||||||
add: __( 'Coupon Codes', 'wc-admin' ),
|
|
||||||
placeholder: __( 'Search coupons', 'wc-admin' ),
|
|
||||||
remove: __( 'Remove coupon filter', 'wc-admin' ),
|
|
||||||
rule: __( 'Select a coupon filter match', 'wc-admin' ),
|
|
||||||
title: __( 'Coupon Code', 'wc-admin' ),
|
|
||||||
},
|
|
||||||
rules: [
|
|
||||||
{ value: 'includes', label: __( 'Includes', 'wc-admin' ) },
|
|
||||||
{ value: 'excludes', label: __( 'Excludes', 'wc-admin' ) },
|
|
||||||
{ value: 'is', label: __( 'Is', 'wc-admin' ) },
|
|
||||||
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) },
|
|
||||||
],
|
|
||||||
input: {
|
|
||||||
component: 'Search',
|
|
||||||
type: 'coupons',
|
|
||||||
getLabels: getRequestByIdString( NAMESPACE + 'coupons', coupon => ( {
|
|
||||||
id: coupon.id,
|
|
||||||
label: coupon.code,
|
|
||||||
} ) ),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
customer: {
|
|
||||||
labels: {
|
|
||||||
add: __( 'Customer Type', 'wc-admin' ),
|
|
||||||
remove: __( 'Remove customer filter', 'wc-admin' ),
|
|
||||||
rule: __( 'Select a customer filter match', 'wc-admin' ),
|
|
||||||
title: __( 'Customer is', 'wc-admin' ),
|
|
||||||
},
|
|
||||||
input: {
|
|
||||||
component: 'SelectControl',
|
|
||||||
options: [
|
|
||||||
{ value: 'new', label: __( 'New', 'wc-admin' ) },
|
|
||||||
{ value: 'returning', label: __( 'Returning', 'wc-admin' ) },
|
|
||||||
],
|
],
|
||||||
defaultOption: 'new',
|
input: {
|
||||||
|
component: 'SelectControl',
|
||||||
|
options: Object.keys( orderStatuses ).map( key => ( {
|
||||||
|
value: key,
|
||||||
|
label: orderStatuses[ key ],
|
||||||
|
} ) ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
product: {
|
||||||
|
labels: {
|
||||||
|
add: __( 'Products', 'wc-admin' ),
|
||||||
|
placeholder: __( 'Search products', 'wc-admin' ),
|
||||||
|
remove: __( 'Remove products filter', 'wc-admin' ),
|
||||||
|
rule: __( 'Select a product filter match', 'wc-admin' ),
|
||||||
|
/* translators: A sentence describing a Product filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
title: __( 'Product {{rule /}} {{filter /}}', 'wc-admin' ),
|
||||||
|
filter: __( 'Select products', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
value: 'includes',
|
||||||
|
/* translators: Sentence fragment, logical, "Includes" refers to orders including a given product(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
label: _x( 'Includes', 'products', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'excludes',
|
||||||
|
/* translators: Sentence fragment, logical, "Excludes" refers to orders excluding a given product(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
label: _x( 'Excludes', 'products', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
input: {
|
||||||
|
component: 'Search',
|
||||||
|
type: 'products',
|
||||||
|
getLabels: getRequestByIdString( NAMESPACE + 'products', product => ( {
|
||||||
|
id: product.id,
|
||||||
|
label: product.name,
|
||||||
|
} ) ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
code: {
|
||||||
|
labels: {
|
||||||
|
add: __( 'Coupon Codes', 'wc-admin' ),
|
||||||
|
placeholder: __( 'Search coupons', 'wc-admin' ),
|
||||||
|
remove: __( 'Remove coupon filter', 'wc-admin' ),
|
||||||
|
rule: __( 'Select a coupon filter match', 'wc-admin' ),
|
||||||
|
/* translators: A sentence describing a Coupon filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
title: __( 'Coupon Code {{rule /}} {{filter /}}', 'wc-admin' ),
|
||||||
|
filter: __( 'Select coupon codes', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
value: 'includes',
|
||||||
|
/* translators: Sentence fragment, logical, "Includes" refers to orders including a given coupon code(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
label: _x( 'Includes', 'coupon code', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'excludes',
|
||||||
|
/* translators: Sentence fragment, logical, "Excludes" refers to orders excluding a given coupon code(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
label: _x( 'Excludes', 'coupon code', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
input: {
|
||||||
|
component: 'Search',
|
||||||
|
type: 'coupons',
|
||||||
|
getLabels: getRequestByIdString( NAMESPACE + 'coupons', coupon => ( {
|
||||||
|
id: coupon.id,
|
||||||
|
label: coupon.code,
|
||||||
|
} ) ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
labels: {
|
||||||
|
add: __( 'Customer Type', 'wc-admin' ),
|
||||||
|
remove: __( 'Remove customer filter', 'wc-admin' ),
|
||||||
|
rule: __( 'Select a customer filter match', 'wc-admin' ),
|
||||||
|
/* translators: A sentence describing a Customer filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
|
||||||
|
title: __( 'Customer is {{filter /}}', 'wc-admin' ),
|
||||||
|
filter: __( 'Select a customer type', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
component: 'SelectControl',
|
||||||
|
options: [
|
||||||
|
{ value: 'new', label: __( 'New', 'wc-admin' ) },
|
||||||
|
{ value: 'returning', label: __( 'Returning', 'wc-admin' ) },
|
||||||
|
],
|
||||||
|
defaultOption: 'new',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
/*eslint-enable max-len*/
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Component, Fragment, createRef } from '@wordpress/element';
|
import { Component, createRef } from '@wordpress/element';
|
||||||
import { SelectControl, Button, Dropdown, IconButton } from '@wordpress/components';
|
import { SelectControl, Button, Dropdown, IconButton } from '@wordpress/components';
|
||||||
import { partial, findIndex, difference } from 'lodash';
|
import { partial, findIndex, difference } from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Gridicon from 'gridicons';
|
import Gridicon from 'gridicons';
|
||||||
|
import interpolateComponents from 'interpolate-components';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -37,7 +38,7 @@ class AdvancedFilters extends Component {
|
||||||
super( ...arguments );
|
super( ...arguments );
|
||||||
this.state = {
|
this.state = {
|
||||||
match: query.match || 'all',
|
match: query.match || 'all',
|
||||||
activeFilters: getActiveFiltersFromQuery( query, config ),
|
activeFilters: getActiveFiltersFromQuery( query, config.filters ),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.filterListRef = createRef();
|
this.filterListRef = createRef();
|
||||||
|
@ -75,30 +76,31 @@ class AdvancedFilters extends Component {
|
||||||
|
|
||||||
getTitle() {
|
getTitle() {
|
||||||
const { match } = this.state;
|
const { match } = this.state;
|
||||||
const { filterTitle } = this.props;
|
const { config } = this.props;
|
||||||
return (
|
return interpolateComponents( {
|
||||||
<Fragment>
|
mixedString: config.title,
|
||||||
<span>{ sprintf( __( '%s Match', 'wc-admin' ), filterTitle ) }</span>
|
components: {
|
||||||
<SelectControl
|
select: (
|
||||||
className="woocommerce-filters-advanced__title-select"
|
<SelectControl
|
||||||
options={ matches }
|
className="woocommerce-filters-advanced__title-select"
|
||||||
value={ match }
|
options={ matches }
|
||||||
onChange={ this.onMatchChange }
|
value={ match }
|
||||||
aria-label={ __( 'Match any or all filters', 'wc-admin' ) }
|
onChange={ this.onMatchChange }
|
||||||
/>
|
aria-label={ __( 'Choose to apply any or all filters', 'wc-admin' ) }
|
||||||
<span>{ __( 'Filters', 'wc-admin' ) }</span>
|
/>
|
||||||
</Fragment>
|
),
|
||||||
);
|
},
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvailableFilterKeys() {
|
getAvailableFilterKeys() {
|
||||||
const { config } = this.props;
|
const { config } = this.props;
|
||||||
const activeFilterKeys = this.state.activeFilters.map( f => f.key );
|
const activeFilterKeys = this.state.activeFilters.map( f => f.key );
|
||||||
return difference( Object.keys( config ), activeFilterKeys );
|
return difference( Object.keys( config.filters ), activeFilterKeys );
|
||||||
}
|
}
|
||||||
|
|
||||||
addFilter( key, onClose ) {
|
addFilter( key, onClose ) {
|
||||||
const filterConfig = this.props.config[ key ];
|
const filterConfig = this.props.config.filters[ key ];
|
||||||
const newFilter = { key };
|
const newFilter = { key };
|
||||||
if ( Array.isArray( filterConfig.rules ) && filterConfig.rules.length ) {
|
if ( Array.isArray( filterConfig.rules ) && filterConfig.rules.length ) {
|
||||||
newFilter.rule = filterConfig.rules[ 0 ].value;
|
newFilter.rule = filterConfig.rules[ 0 ].value;
|
||||||
|
@ -131,46 +133,47 @@ class AdvancedFilters extends Component {
|
||||||
|
|
||||||
getUpdateHref( activeFilters, matchValue ) {
|
getUpdateHref( activeFilters, matchValue ) {
|
||||||
const { path, query, config } = this.props;
|
const { path, query, config } = this.props;
|
||||||
const updatedQuery = getQueryFromActiveFilters( activeFilters, query, config );
|
const updatedQuery = getQueryFromActiveFilters( activeFilters, query, config.filters );
|
||||||
const match = matchValue === 'all' ? undefined : matchValue;
|
const match = matchValue === 'all' ? undefined : matchValue;
|
||||||
return getNewPath( { ...updatedQuery, match }, path, query );
|
return getNewPath( { ...updatedQuery, match }, path, query );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEnglish() {
|
||||||
|
const { siteLocale } = wcSettings;
|
||||||
|
return /en-/.test( siteLocale );
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { config } = this.props;
|
const { config } = this.props;
|
||||||
const { activeFilters, match } = this.state;
|
const { activeFilters, match } = this.state;
|
||||||
const availableFilterKeys = this.getAvailableFilterKeys();
|
const availableFilterKeys = this.getAvailableFilterKeys();
|
||||||
const updateHref = this.getUpdateHref( activeFilters, match );
|
const updateHref = this.getUpdateHref( activeFilters, match );
|
||||||
const updateDisabled = window.location.hash && window.location.hash.substr( 1 ) === updateHref;
|
const updateDisabled = window.location.hash && window.location.hash.substr( 1 ) === updateHref;
|
||||||
|
const isEnglish = this.isEnglish();
|
||||||
return (
|
return (
|
||||||
<Card className="woocommerce-filters-advanced" title={ this.getTitle() }>
|
<Card className="woocommerce-filters-advanced" title={ this.getTitle() }>
|
||||||
<ul className="woocommerce-filters-advanced__list" ref={ this.filterListRef }>
|
<ul className="woocommerce-filters-advanced__list" ref={ this.filterListRef }>
|
||||||
{ activeFilters.map( filter => {
|
{ activeFilters.map( filter => {
|
||||||
const { key } = filter;
|
const { key } = filter;
|
||||||
const { input, labels } = config[ key ];
|
const { input, labels } = config.filters[ key ];
|
||||||
return (
|
return (
|
||||||
<li className="woocommerce-filters-advanced__list-item" key={ key }>
|
<li className="woocommerce-filters-advanced__list-item" key={ key }>
|
||||||
{ /*eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex*/ }
|
{ 'SelectControl' === input.component && (
|
||||||
<fieldset tabIndex="0">
|
<SelectFilter
|
||||||
{ /*eslint-enable-next-line jsx-a11y/no-noninteractive-tabindex*/ }
|
filter={ filter }
|
||||||
<legend className="screen-reader-text">{ labels.title }</legend>
|
config={ config.filters[ key ] }
|
||||||
<div className="woocommerce-filters-advanced__fieldset">
|
onFilterChange={ this.onFilterChange }
|
||||||
{ 'SelectControl' === input.component && (
|
isEnglish={ isEnglish }
|
||||||
<SelectFilter
|
/>
|
||||||
filter={ filter }
|
) }
|
||||||
config={ config[ key ] }
|
{ 'Search' === input.component && (
|
||||||
onFilterChange={ this.onFilterChange }
|
<SearchFilter
|
||||||
/>
|
filter={ filter }
|
||||||
) }
|
config={ config.filters[ key ] }
|
||||||
{ 'Search' === input.component && (
|
onFilterChange={ this.onFilterChange }
|
||||||
<SearchFilter
|
isEnglish={ isEnglish }
|
||||||
filter={ filter }
|
/>
|
||||||
config={ config[ key ] }
|
) }
|
||||||
onFilterChange={ this.onFilterChange }
|
|
||||||
/>
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
className="woocommerce-filters-advanced__remove"
|
className="woocommerce-filters-advanced__remove"
|
||||||
label={ labels.remove }
|
label={ labels.remove }
|
||||||
|
@ -201,7 +204,7 @@ class AdvancedFilters extends Component {
|
||||||
{ availableFilterKeys.map( key => (
|
{ availableFilterKeys.map( key => (
|
||||||
<li key={ key }>
|
<li key={ key }>
|
||||||
<Button onClick={ partial( this.addFilter, key, onClose ) }>
|
<Button onClick={ partial( this.addFilter, key, onClose ) }>
|
||||||
{ config[ key ].labels.add }
|
{ config.filters[ key ].labels.add }
|
||||||
</Button>
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
) ) }
|
) ) }
|
||||||
|
@ -239,25 +242,25 @@ AdvancedFilters.propTypes = {
|
||||||
/**
|
/**
|
||||||
* The configuration object required to render filters.
|
* The configuration object required to render filters.
|
||||||
*/
|
*/
|
||||||
config: PropTypes.objectOf(
|
config: PropTypes.shape( {
|
||||||
PropTypes.shape( {
|
title: PropTypes.string,
|
||||||
labels: PropTypes.shape( {
|
filters: PropTypes.objectOf(
|
||||||
add: PropTypes.string,
|
PropTypes.shape( {
|
||||||
placeholder: PropTypes.string,
|
labels: PropTypes.shape( {
|
||||||
remove: PropTypes.string,
|
add: PropTypes.string,
|
||||||
title: PropTypes.string,
|
remove: PropTypes.string,
|
||||||
} ),
|
rule: PropTypes.string,
|
||||||
rules: PropTypes.arrayOf( PropTypes.object ),
|
title: PropTypes.string,
|
||||||
input: PropTypes.object,
|
filter: PropTypes.string,
|
||||||
} )
|
} ),
|
||||||
).isRequired,
|
rules: PropTypes.arrayOf( PropTypes.object ),
|
||||||
|
input: PropTypes.object,
|
||||||
|
} )
|
||||||
|
),
|
||||||
|
} ).isRequired,
|
||||||
/**
|
/**
|
||||||
* Name of this filter, used in translations.
|
* Name of this filter, used in translations.
|
||||||
*/
|
*/
|
||||||
filterTitle: PropTypes.string.isRequired,
|
|
||||||
/**
|
|
||||||
* The `path` parameter supplied by React-Router.
|
|
||||||
*/
|
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
/**
|
/**
|
||||||
* The query string represented in object form.
|
* The query string represented in object form.
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import { SelectControl } from '@wordpress/components';
|
import { SelectControl } from '@wordpress/components';
|
||||||
import { partial } from 'lodash';
|
import { find, partial } from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withInstanceId } from '@wordpress/compose';
|
import interpolateComponents from 'interpolate-components';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -41,40 +42,66 @@ class SearchFilter extends Component {
|
||||||
onFilterChange( filter.key, 'value', idList );
|
onFilterChange( filter.key, 'value', idList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLegend( filter, config ) {
|
||||||
|
const { selected } = this.state;
|
||||||
|
const rule = find( config.rules, { value: filter.rule } ) || {};
|
||||||
|
const filterStr = selected.map( item => item.label ).join( ', ' );
|
||||||
|
|
||||||
|
return interpolateComponents( {
|
||||||
|
mixedString: config.labels.title,
|
||||||
|
components: {
|
||||||
|
filter: <span>{ filterStr }</span>,
|
||||||
|
rule: <span>{ rule.label }</span>,
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { config, filter, instanceId, onFilterChange } = this.props;
|
const { config, filter, onFilterChange, isEnglish } = this.props;
|
||||||
const { selected } = this.state;
|
const { selected } = this.state;
|
||||||
const { key, rule } = filter;
|
const { key, rule } = filter;
|
||||||
const { input, labels, rules } = config;
|
const { input, labels, rules } = config;
|
||||||
return (
|
const children = interpolateComponents( {
|
||||||
<Fragment>
|
mixedString: labels.title,
|
||||||
<div
|
components: {
|
||||||
id={ `${ key }-${ instanceId }` }
|
rule: (
|
||||||
className="woocommerce-filters-advanced__fieldset-legend"
|
|
||||||
>
|
|
||||||
{ labels.title }
|
|
||||||
</div>
|
|
||||||
{ rule && (
|
|
||||||
<SelectControl
|
<SelectControl
|
||||||
className="woocommerce-filters-advanced__list-specifier"
|
className="woocommerce-filters-advanced__rule"
|
||||||
options={ rules }
|
options={ rules }
|
||||||
value={ rule }
|
value={ rule }
|
||||||
onChange={ partial( onFilterChange, key, 'rule' ) }
|
onChange={ partial( onFilterChange, key, 'rule' ) }
|
||||||
aria-label={ labels.rule }
|
aria-label={ labels.rule }
|
||||||
/>
|
/>
|
||||||
) }
|
),
|
||||||
<div className="woocommerce-filters-advanced__list-selector">
|
filter: (
|
||||||
<Search
|
<Search
|
||||||
|
className="woocommerce-filters-advanced__input"
|
||||||
onChange={ this.onSearchChange }
|
onChange={ this.onSearchChange }
|
||||||
type={ input.type }
|
type={ input.type }
|
||||||
placeholder={ labels.placeholder }
|
placeholder={ labels.placeholder }
|
||||||
selected={ selected }
|
selected={ selected }
|
||||||
ariaLabelledby={ `${ key }-${ instanceId }` }
|
|
||||||
inlineTags
|
inlineTags
|
||||||
|
aria-label={ labels.filter }
|
||||||
/>
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
|
||||||
|
return (
|
||||||
|
<fieldset tabIndex="0">
|
||||||
|
<legend className="screen-reader-text">
|
||||||
|
{ this.getLegend( filter, config, selected ) }
|
||||||
|
</legend>
|
||||||
|
<div
|
||||||
|
className={ classnames( 'woocommerce-filters-advanced__fieldset', {
|
||||||
|
'is-english': isEnglish,
|
||||||
|
} ) }
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</fieldset>
|
||||||
);
|
);
|
||||||
|
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,4 +132,4 @@ SearchFilter.propTypes = {
|
||||||
onFilterChange: PropTypes.func.isRequired,
|
onFilterChange: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withInstanceId( SearchFilter );
|
export default SearchFilter;
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import { SelectControl, Spinner } from '@wordpress/components';
|
import { SelectControl, Spinner } from '@wordpress/components';
|
||||||
import { partial } from 'lodash';
|
import { find, partial } from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withInstanceId } from '@wordpress/compose';
|
import interpolateComponents from 'interpolate-components';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -40,42 +41,62 @@ class SelectFilter extends Component {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLegend( filter, config ) {
|
||||||
|
const rule = find( config.rules, { value: filter.rule } ) || {};
|
||||||
|
const value = find( config.input.options, { value: filter.value } ) || {};
|
||||||
|
return interpolateComponents( {
|
||||||
|
mixedString: config.labels.title,
|
||||||
|
components: {
|
||||||
|
filter: <span>{ value.label }</span>,
|
||||||
|
rule: <span>{ rule.label }</span>,
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { config, filter, instanceId, onFilterChange } = this.props;
|
const { config, filter, onFilterChange, isEnglish } = this.props;
|
||||||
const { options } = this.state;
|
const { options } = this.state;
|
||||||
const { key, rule, value } = filter;
|
const { key, rule, value } = filter;
|
||||||
const { labels, rules } = config;
|
const { labels, rules } = config;
|
||||||
return (
|
const children = interpolateComponents( {
|
||||||
<Fragment>
|
mixedString: labels.title,
|
||||||
<div
|
components: {
|
||||||
id={ `${ key }-${ instanceId }` }
|
rule: (
|
||||||
className="woocommerce-filters-advanced__fieldset-legend"
|
|
||||||
>
|
|
||||||
{ labels.title }
|
|
||||||
</div>
|
|
||||||
{ rule && (
|
|
||||||
<SelectControl
|
<SelectControl
|
||||||
className="woocommerce-filters-advanced__list-specifier"
|
className="woocommerce-filters-advanced__rule"
|
||||||
options={ rules }
|
options={ rules }
|
||||||
value={ rule }
|
value={ rule }
|
||||||
onChange={ partial( onFilterChange, key, 'rule' ) }
|
onChange={ partial( onFilterChange, key, 'rule' ) }
|
||||||
aria-label={ labels.rule }
|
aria-label={ labels.rule }
|
||||||
/>
|
/>
|
||||||
) }
|
),
|
||||||
<div className="woocommerce-filters-advanced__list-selector">
|
filter: options ? (
|
||||||
{ ! options && <Spinner /> }
|
<SelectControl
|
||||||
{ options && (
|
className="woocommerce-filters-advanced__input"
|
||||||
<SelectControl
|
options={ options }
|
||||||
className="woocommerce-filters-advanced__list-select"
|
value={ value }
|
||||||
options={ options }
|
onChange={ partial( onFilterChange, filter.key, 'value' ) }
|
||||||
value={ value }
|
aria-label={ labels.filter }
|
||||||
onChange={ partial( onFilterChange, filter.key, 'value' ) }
|
/>
|
||||||
aria-labelledby={ `${ key }-${ instanceId }` }
|
) : (
|
||||||
/>
|
<Spinner />
|
||||||
) }
|
),
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
|
||||||
|
return (
|
||||||
|
<fieldset tabIndex="0">
|
||||||
|
<legend className="screen-reader-text">{ this.getLegend( filter, config ) }</legend>
|
||||||
|
<div
|
||||||
|
className={ classnames( 'woocommerce-filters-advanced__fieldset', {
|
||||||
|
'is-english': isEnglish,
|
||||||
|
} ) }
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</fieldset>
|
||||||
);
|
);
|
||||||
|
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +108,7 @@ SelectFilter.propTypes = {
|
||||||
labels: PropTypes.shape( {
|
labels: PropTypes.shape( {
|
||||||
rule: PropTypes.string,
|
rule: PropTypes.string,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
|
filter: PropTypes.string,
|
||||||
} ),
|
} ),
|
||||||
rules: PropTypes.arrayOf( PropTypes.object ),
|
rules: PropTypes.arrayOf( PropTypes.object ),
|
||||||
input: PropTypes.object,
|
input: PropTypes.object,
|
||||||
|
@ -105,4 +127,4 @@ SelectFilter.propTypes = {
|
||||||
onFilterChange: PropTypes.func.isRequired,
|
onFilterChange: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withInstanceId( SelectFilter );
|
export default SelectFilter;
|
||||||
|
|
|
@ -41,17 +41,13 @@
|
||||||
border-bottom: 1px solid $core-grey-light-700;
|
border-bottom: 1px solid $core-grey-light-700;
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
padding: $gap-smaller $gap;
|
padding: $gap-smaller $gap-smaller $gap-smaller $gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $core-grey-light-200;
|
background-color: $core-grey-light-200;
|
||||||
}
|
}
|
||||||
|
|
||||||
.components-base-control {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-filters-advanced__remove {
|
.woocommerce-filters-advanced__remove {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
|
@ -85,22 +81,41 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-filters-advanced__fieldset {
|
.woocommerce-filters-advanced__fieldset {
|
||||||
display: grid;
|
& > div {
|
||||||
grid-template-columns: 100px 150px auto;
|
padding: 0 $gap-smallest;
|
||||||
|
|
||||||
|
@include breakpoint( '<782px' ) {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: $gap-smallest 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
@include breakpoint( '<782px' ) {
|
@include breakpoint( '<782px' ) {
|
||||||
display: flex;
|
display: block;
|
||||||
flex-direction: column;
|
}
|
||||||
|
|
||||||
|
&.is-english {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 100px 150px auto;
|
||||||
|
|
||||||
|
@include breakpoint( '<782px' ) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-filters-advanced__fieldset-legend {
|
.woocommerce-filters-advanced__rule {
|
||||||
align-self: center;
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
@include breakpoint( '<782px' ) {
|
.woocommerce-filters-advanced__input {
|
||||||
align-self: initial;
|
width: 100%;
|
||||||
padding: $gap-smallest 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-filters-advanced__add-filter-dropdown {
|
.woocommerce-filters-advanced__add-filter-dropdown {
|
||||||
|
@ -156,35 +171,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-filters-advanced__list-selector {
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
padding: $gap-smallest 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.components-spinner {
|
|
||||||
margin: auto;
|
|
||||||
display: block;
|
|
||||||
float: none;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-filters-advanced__list-specifier {
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
padding: $gap-smallest 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& + .woocommerce-filters-advanced__list-selector {
|
|
||||||
padding: 0 0 0 $gap-smaller;
|
|
||||||
|
|
||||||
@include breakpoint( '<782px' ) {
|
|
||||||
padding: $gap-smallest 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,12 +45,7 @@ class ReportFilters extends Component {
|
||||||
if ( 'advanced' === query.filter ) {
|
if ( 'advanced' === query.filter ) {
|
||||||
return (
|
return (
|
||||||
<div className="woocommerce-filters__advanced-filters">
|
<div className="woocommerce-filters__advanced-filters">
|
||||||
<AdvancedFilters
|
<AdvancedFilters config={ advancedConfig } path={ path } query={ query } />
|
||||||
config={ advancedConfig }
|
|
||||||
filterTitle={ __( 'Orders', 'wc-admin' ) }
|
|
||||||
path={ path }
|
|
||||||
query={ query }
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.components-base-control__field {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-filters-date,
|
.woocommerce-filters-date,
|
||||||
|
|
|
@ -113,14 +113,14 @@ class Search extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const autocompleter = this.getAutocompleter();
|
const autocompleter = this.getAutocompleter();
|
||||||
const { placeholder, inlineTags, selected, instanceId } = this.props;
|
const { placeholder, inlineTags, selected, instanceId, className } = this.props;
|
||||||
const { value = '', isActive } = this.state;
|
const { value = '', isActive } = this.state;
|
||||||
const aria = {
|
const aria = {
|
||||||
'aria-labelledby': this.props[ 'aria-labelledby' ],
|
'aria-labelledby': this.props[ 'aria-labelledby' ],
|
||||||
'aria-label': this.props[ 'aria-label' ],
|
'aria-label': this.props[ 'aria-label' ],
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="woocommerce-search">
|
<div className={ classnames( 'woocommerce-search', className ) }>
|
||||||
<Gridicon className="woocommerce-search__icon" icon="search" size={ 18 } />
|
<Gridicon className="woocommerce-search__icon" icon="search" size={ 18 } />
|
||||||
<Autocomplete completer={ autocompleter } onSelect={ this.selectResult }>
|
<Autocomplete completer={ autocompleter } onSelect={ this.selectResult }>
|
||||||
{ ( { listBoxId, activeId, onChange } ) =>
|
{ ( { listBoxId, activeId, onChange } ) =>
|
||||||
|
@ -186,6 +186,10 @@ class Search extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
Search.propTypes = {
|
Search.propTypes = {
|
||||||
|
/**
|
||||||
|
* Class name applied to parent div.
|
||||||
|
*/
|
||||||
|
className: PropTypes.string,
|
||||||
/**
|
/**
|
||||||
* Function called when selected results change, passed result list.
|
* Function called when selected results change, passed result list.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -78,8 +78,8 @@
|
||||||
"history": "^4.7.2",
|
"history": "^4.7.2",
|
||||||
"html-to-react": "^1.3.3",
|
"html-to-react": "^1.3.3",
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"interpolate-components": "1.1.1",
|
|
||||||
"marked": "^0.5.0",
|
"marked": "^0.5.0",
|
||||||
|
"interpolate-components": "^1.1.1",
|
||||||
"node-sass": "^4.9.3",
|
"node-sass": "^4.9.3",
|
||||||
"postcss-color-function": "^4.0.1",
|
"postcss-color-function": "^4.0.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
|
|
Loading…
Reference in New Issue