Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
Add calendar to date advanced filter
Browse files Browse the repository at this point in the history
  • Loading branch information
psealock committed Jan 1, 2019
1 parent 090088f commit 49272c1
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 3 deletions.
30 changes: 30 additions & 0 deletions client/analytics/report/customers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,36 @@ export const advancedFilters = {
component: 'Currency',
},
},
registered: {
labels: {
add: __( 'Registered', 'wc-admin' ),
remove: __( 'Remove registered filter', 'wc-admin' ),
rule: __( 'Select a registered filter match', 'wc-admin' ),
/* translators: A sentence describing a Product filter. See screen shot for context: https://cloudup.com/cCsm3GeXJbE */
title: __( 'Registered {{rule /}} {{filter /}}', 'wc-admin' ),
filter: __( 'Select registered date', 'wc-admin' ),
},
rules: [
{
value: 'before',
/* translators: Sentence fragment, logical, "Before" refers to customers registered before a given date. Screenshot for context: https://cloudup.com/cCsm3GeXJbE */
label: _x( 'Before', 'date', 'wc-admin' ),
},
{
value: 'after',
/* translators: Sentence fragment, logical, "Excludes" refers to customers registered after a given date. Screenshot for context: https://cloudup.com/cCsm3GeXJbE */
label: _x( 'After', 'date', 'wc-admin' ),
},
{
value: 'between',
/* translators: Sentence fragment, logical, "Excludes" refers to customers registered between given dates. Screenshot for context: https://cloudup.com/cCsm3GeXJbE */
label: _x( 'Between', 'date', 'wc-admin' ),
},
],
input: {
component: 'Date',
},
},
},
};
/*eslint-enable max-len*/
199 changes: 199 additions & 0 deletions packages/components/src/filters/advanced/date-filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/** @format */
/**
* External dependencies
*/
import { Component } from '@wordpress/element';
import interpolateComponents from 'interpolate-components';
import { SelectControl } from '@wordpress/components';
import { find, partial } from 'lodash';
import classnames from 'classnames';
import { __, _x } from '@wordpress/i18n';
import moment from 'moment';

/**
* WooCommerce dependencies
*/
import { isoDateFormat, toMoment } from '@woocommerce/date';

/**
* Internal dependencies
*/
import DatePicker from '../../calendar/date-picker';

const dateStringFormat = __( 'MMM D, YYYY', 'wc-admin' );
const dateFormat = __( 'MM/DD/YYYY', 'wc-admin' );

class DateFilter extends Component {
constructor( { filter } ) {
super( ...arguments );

const [ isoAfter, isoBefore ] = ( filter.value || '' ).split( ',' );
const after = isoAfter ? toMoment( isoDateFormat, isoAfter ) : null;
const before = isoBefore ? toMoment( isoDateFormat, isoBefore ) : null;

this.state = {
before,
beforeText: before ? before.format( dateFormat ) : '',
beforeError: null,
after,
afterText: after ? after.format( dateFormat ) : '',
afterError: null,
};

this.onSingleDateChange = this.onSingleDateChange.bind( this );
this.onRangeDateChange = this.onRangeDateChange.bind( this );
}

getBetweenString() {
return _x(
'{{after /}}{{span}}and{{/span}}{{before /}}',
'Date range inputs arranged on a single line',
'wc-admin'
);
}

getLegend( filter, config ) {
const date = moment(); // For now...
const rule = find( config.rules, { value: filter.rule } ) || {};
const filterStr = date && date.format( dateStringFormat );

return interpolateComponents( {
mixedString: config.labels.title,
components: {
filter: <span>{ filterStr }</span>,
rule: <span>{ rule.label }</span>,
},
} );
}

onSingleDateChange( { date, text, error } ) {
const { filter, onFilterChange } = this.props;
this.setState( { before: date, beforeText: text, beforeError: error } );

if ( date ) {
onFilterChange( filter.key, 'value', date.format( isoDateFormat ) );
}
}

onRangeDateChange( input, { date, text, error } ) {
const { filter, onFilterChange } = this.props;

this.setState( {
[ input ]: date,
[ input + 'Text' ]: text,
[ input + 'Error' ]: error,
} );

if ( date ) {
const { before, after } = this.state;
let nextAfter = null;
let nextBefore = null;

if ( 'after' === input ) {
nextAfter = date.format( isoDateFormat );
nextBefore = before ? before.format( isoDateFormat ) : null;
}

if ( 'before' === input ) {
nextAfter = after ? after.format( isoDateFormat ) : null;
nextBefore = date.format( isoDateFormat );
}

if ( nextAfter && nextBefore ) {
onFilterChange( filter.key, 'value', [ nextAfter, nextBefore ].join( ',' ) );
}
}
}

getFilterInputs() {
const { filter } = this.props;
const { before, beforeText, beforeError, after, afterText, afterError } = this.state;

if ( 'between' === filter.rule ) {
return interpolateComponents( {
mixedString: this.getBetweenString(),
components: {
after: (
<DatePicker
date={ after }
text={ afterText }
error={ afterError }
onUpdate={ partial( this.onRangeDateChange, 'after' ) }
dateFormat={ dateFormat }
invalidDays="none"
/>
),
before: (
<DatePicker
date={ before }
text={ beforeText }
error={ beforeError }
onUpdate={ partial( this.onRangeDateChange, 'before' ) }
dateFormat={ dateFormat }
invalidDays="none"
/>
),
span: <span className="separator" />,
},
} );
}

return (
<DatePicker
date={ before }
text={ beforeText }
error={ beforeError }
onUpdate={ this.onSingleDateChange }
dateFormat={ dateFormat }
invalidDays="none"
/>
);
}

render() {
const { config, filter, onFilterChange, isEnglish } = this.props;
const { key, rule } = filter;
const { labels, rules } = config;
const children = interpolateComponents( {
mixedString: labels.title,
components: {
rule: (
<SelectControl
className="woocommerce-filters-advanced__rule"
options={ rules }
value={ rule }
onChange={ partial( onFilterChange, key, 'rule' ) }
aria-label={ labels.rule }
/>
),
filter: (
<div
className={ classnames( 'woocommerce-filters-advanced__input-range', {
'is-between': 'between' === rule,
} ) }
>
{ this.getFilterInputs() }
</div>
),
},
} );
/*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>
</fieldset>
);
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
}
}

export default DateFilter;
10 changes: 10 additions & 0 deletions packages/components/src/filters/advanced/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Link from '../../link';
import SelectFilter from './select-filter';
import SearchFilter from './search-filter';
import NumberFilter from './number-filter';
import DateFilter from './date-filter';

const matches = [
{ value: 'all', label: __( 'All', 'wc-admin' ) },
Expand Down Expand Up @@ -210,6 +211,15 @@ class AdvancedFilters extends Component {
query={ query }
/>
) }
{ 'Date' === input.component && (
<DateFilter
filter={ filter }
config={ config.filters[ key ] }
onFilterChange={ this.onFilterChange }
isEnglish={ isEnglish }
query={ query }
/>
) }
<IconButton
className="woocommerce-filters-advanced__remove"
label={ labels.remove }
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/filters/advanced/number-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class NumberFilter extends Component {
),
filter: (
<div
className={ classnames( 'woocommerce-filters-advanced__input-numeric-range', {
className={ classnames( 'woocommerce-filters-advanced__input-range', {
'is-between': 'between' === rule,
} ) }
>
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/filters/advanced/search-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class SearchFilter extends Component {
return (
<fieldset tabIndex="0">
<legend className="screen-reader-text">
{ this.getLegend( filter, config, selected ) }
{ this.getLegend( filter, config ) }
</legend>
<div
className={ classnames( 'woocommerce-filters-advanced__fieldset', {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/filters/advanced/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
}
}

.woocommerce-filters-advanced__input-numeric-range {
.woocommerce-filters-advanced__input-range {
align-items: center;
display: grid;
grid-template-columns: 1fr;
Expand Down

0 comments on commit 49272c1

Please sign in to comment.