Merge pull request woocommerce/woocommerce-admin#107 from woocommerce/add/date-range-strings
Datepicker: Add strings for periods
This commit is contained in:
commit
3742fbd1e2
|
@ -13,7 +13,7 @@ import PropTypes from 'prop-types';
|
|||
*/
|
||||
import './style.scss';
|
||||
import DatePickerContent from './content';
|
||||
import { getDateValues, isoDateFormat } from 'lib/date';
|
||||
import { getCurrentDates, isoDateFormat } from 'lib/date';
|
||||
|
||||
class DatePicker extends Component {
|
||||
constructor( props ) {
|
||||
|
@ -67,7 +67,7 @@ class DatePicker extends Component {
|
|||
|
||||
getButtonLabel() {
|
||||
const queryWithDefaults = this.addQueryDefaults( this.props.query );
|
||||
const { primary, secondary } = getDateValues( queryWithDefaults );
|
||||
const { primary, secondary } = getCurrentDates( queryWithDefaults );
|
||||
return (
|
||||
<div className="woocommerce-date-picker__toggle-label">
|
||||
<p>
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
*/
|
||||
import moment from 'moment';
|
||||
import { find } from 'lodash';
|
||||
import { getSettings } from '@wordpress/date';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { date as datePHPFormat, getSettings } from '@wordpress/date';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -22,70 +23,6 @@ import { compareValues } from 'components/date-picker/compare-periods';
|
|||
* @property {moment.Moment} end - End of the date range.
|
||||
*/
|
||||
|
||||
/**
|
||||
* <---------- MORE TO COME IN THE NEXT PR ----------->
|
||||
* Get Date Value Objects for a primary and secondary date range
|
||||
*
|
||||
* @param {string} period - Indicates period, 'last_week', 'quarter', or 'custom'
|
||||
* @param {string} compare - Indicates the period to compare against, 'previous_period', previous_year'
|
||||
* @param {moment.Moment} [start] - If the period supplied is "custom", this is the start date
|
||||
* @param {moment.Moment} [end] - If the period supplied is "custom", this is the end date
|
||||
* @return {{primary: DateValue, secondary: DateValue}} - Primary and secondary DateValue objects
|
||||
*/
|
||||
export const getDateValues = ( { period, compare, start, end } ) => {
|
||||
const presetValue = find( presetValues, item => item.value === period );
|
||||
const compareValue = find( compareValues, item => item.value === compare );
|
||||
|
||||
let primaryStart = moment();
|
||||
let primaryEnd = moment();
|
||||
let secondaryStart = moment();
|
||||
let secondaryEnd = moment();
|
||||
|
||||
switch ( period ) {
|
||||
case 'today':
|
||||
break;
|
||||
case 'yesterday':
|
||||
break;
|
||||
case 'week':
|
||||
break;
|
||||
case 'last_week':
|
||||
break;
|
||||
case 'month':
|
||||
break;
|
||||
case 'last_month':
|
||||
break;
|
||||
case 'quarter':
|
||||
break;
|
||||
case 'last_quarter':
|
||||
break;
|
||||
case 'year':
|
||||
break;
|
||||
case 'last_year':
|
||||
break;
|
||||
case 'custom':
|
||||
// For now...
|
||||
primaryStart = start;
|
||||
primaryEnd = end;
|
||||
secondaryStart = start.subtract( 1, 'years' );
|
||||
secondaryEnd = end.subtract( 1, 'years' );
|
||||
break;
|
||||
}
|
||||
return {
|
||||
primary: {
|
||||
label: presetValue.label,
|
||||
range: '<-- date str -->',
|
||||
start: primaryStart,
|
||||
end: primaryEnd,
|
||||
},
|
||||
secondary: {
|
||||
label: compareValue.label,
|
||||
range: '<-- date str -->',
|
||||
start: secondaryStart,
|
||||
end: secondaryEnd,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const isoDateFormat = 'YYYY-MM-DD';
|
||||
|
||||
// This is temporary. This logic will be best addressed in Gutenberg's date package
|
||||
|
@ -157,6 +94,30 @@ function getMomentFormat( phpFormat ) {
|
|||
} );
|
||||
}
|
||||
|
||||
// When `wp.date.setSettings()` is called on page initialization, PHP formats
|
||||
// get saved to momentjs localeData. When react-dates attempts create date strings from
|
||||
// those formats, moment isn't able to handle them. So lets convert those to moment strings.
|
||||
// This logic should also live in Gutenberg. A PR will be made there.
|
||||
function applyMomentFormats() {
|
||||
const settings = getSettings();
|
||||
const longDateFormats = moment.localeData()._longDateFormat;
|
||||
const momentLongDateFormats = Object.keys( longDateFormats ).reduce( ( formats, item ) => {
|
||||
if ( longDateFormats[ item ] ) {
|
||||
formats[ item ] = getMomentFormat( longDateFormats[ item ] );
|
||||
}
|
||||
return formats;
|
||||
}, {} );
|
||||
moment.updateLocale( settings.l10n.locale, {
|
||||
longDateFormat: momentLongDateFormats,
|
||||
} );
|
||||
}
|
||||
|
||||
// i18n depends on this Gutenberg PR https://github.com/WordPress/gutenberg/pull/7542
|
||||
// If it has been merged, we need to applyMomentFormats().
|
||||
if ( ! moment.locale() ) {
|
||||
applyMomentFormats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to Moment object
|
||||
*
|
||||
|
@ -174,3 +135,200 @@ export function toMoment( str ) {
|
|||
}
|
||||
throw new Error( 'toMoment requires a string to be passed as an argument' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two dates, derive a string representation
|
||||
*
|
||||
* @param {Moment} start - start date
|
||||
* @param {Moment} end - end date
|
||||
* @return {string} - text value for the supplied date range
|
||||
*/
|
||||
function getRangeLabel( start, end ) {
|
||||
const isSameDay = start.isSame( end, 'day' );
|
||||
const isSameYear = start.year() === end.year();
|
||||
const isSameMonth = isSameYear && start.month() === end.month();
|
||||
// If the date format in settings have Full Text Month (F), replace it wtih 3 letter abbreviations (M)
|
||||
const PHPFormat = getSettings().formats.date.replace( 'F', 'M' );
|
||||
if ( isSameDay ) {
|
||||
return datePHPFormat( PHPFormat, start );
|
||||
} else if ( isSameMonth ) {
|
||||
const startDate = start.date();
|
||||
return datePHPFormat( PHPFormat, start ).replace(
|
||||
startDate,
|
||||
`${ startDate } - ${ end.date() }`
|
||||
);
|
||||
} else if ( isSameYear ) {
|
||||
return `${ start.format( __( 'MMM D', 'woo-dash' ) ) } - ${ datePHPFormat( PHPFormat, end ) }`;
|
||||
}
|
||||
return `${ datePHPFormat( PHPFormat, start ) } - ${ datePHPFormat( PHPFormat, end ) }`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DateValue object for a period prior to the current period.
|
||||
*
|
||||
* @param {string} period - the chosen period
|
||||
* @param {string} compare - `previous_period` or `previous_year`
|
||||
* @return {DateValue} - DateValue data about the selected period
|
||||
*/
|
||||
function getLastPeriod( period, compare ) {
|
||||
const primaryStart = moment()
|
||||
.startOf( period )
|
||||
.subtract( 1, period );
|
||||
const primaryEnd = primaryStart.clone().endOf( period );
|
||||
let secondaryStart;
|
||||
let secondaryEnd;
|
||||
|
||||
if ( 'previous_period' === compare ) {
|
||||
if ( 'year' === period ) {
|
||||
// Subtract two entire periods for years to take into account leap year
|
||||
secondaryStart = moment()
|
||||
.startOf( period )
|
||||
.subtract( 2, period );
|
||||
secondaryEnd = secondaryStart.clone().endOf( period );
|
||||
} else {
|
||||
// Otherwise, use days in primary period to figure out how far to go back
|
||||
const daysDiff = primaryEnd.diff( primaryStart, 'days' );
|
||||
secondaryEnd = primaryStart.clone().subtract( 1, 'days' );
|
||||
secondaryStart = secondaryEnd.clone().subtract( daysDiff, 'days' );
|
||||
}
|
||||
} else {
|
||||
secondaryStart =
|
||||
'week' === period
|
||||
? primaryStart
|
||||
.clone()
|
||||
.subtract( 1, 'years' )
|
||||
.week( primaryStart.week() )
|
||||
.startOf( 'week' )
|
||||
: primaryStart.clone().subtract( 1, 'years' );
|
||||
secondaryEnd = secondaryStart.clone().endOf( period );
|
||||
}
|
||||
return {
|
||||
primaryStart,
|
||||
primaryEnd,
|
||||
secondaryStart,
|
||||
secondaryEnd,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DateValue object for a curent period. The period begins on the first day of the period,
|
||||
* and ends on the current day.
|
||||
*
|
||||
* @param {string} period - the chosen period
|
||||
* @param {string} compare - `previous_period` or `previous_year`
|
||||
* @return {DateValue} - DateValue data about the selected period
|
||||
*/
|
||||
function getCurrentPeriod( period, compare ) {
|
||||
const primaryStart = moment().startOf( period );
|
||||
const primaryEnd = moment();
|
||||
const daysSoFar = primaryEnd.diff( primaryStart, 'days' );
|
||||
let secondaryStart;
|
||||
let secondaryEnd;
|
||||
|
||||
if ( 'previous_period' === compare ) {
|
||||
secondaryStart = primaryStart.clone().subtract( 1, period );
|
||||
secondaryEnd = primaryEnd.clone().subtract( 1, period );
|
||||
} else {
|
||||
secondaryStart =
|
||||
'week' === period
|
||||
? primaryStart
|
||||
.clone()
|
||||
.subtract( 1, 'years' )
|
||||
.week( primaryStart.week() )
|
||||
.startOf( 'week' )
|
||||
: primaryStart.clone().subtract( 1, 'years' );
|
||||
secondaryEnd = secondaryStart.clone().add( daysSoFar, 'days' );
|
||||
}
|
||||
return {
|
||||
primaryStart,
|
||||
primaryEnd,
|
||||
secondaryStart,
|
||||
secondaryEnd,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DateValue object for a period described by a period, compare value, and start/end
|
||||
* dates, for custom dates.
|
||||
*
|
||||
* @param {string} period - the chosen period
|
||||
* @param {string} compare - `previous_period` or `previous_year`
|
||||
* @param {Moment} [start] - start date if custom period
|
||||
* @param {Moment} [end] - end date if custom period
|
||||
* @return {DateValue} - DateValue data about the selected period
|
||||
*/
|
||||
function getDateValue( period, compare, start, end ) {
|
||||
switch ( period ) {
|
||||
case 'today':
|
||||
return getCurrentPeriod( 'day', compare );
|
||||
case 'yesterday':
|
||||
return getLastPeriod( 'day', compare );
|
||||
case 'week':
|
||||
return getCurrentPeriod( 'week', compare );
|
||||
case 'last_week':
|
||||
return getLastPeriod( 'week', compare );
|
||||
case 'month':
|
||||
return getCurrentPeriod( 'month', compare );
|
||||
case 'last_month':
|
||||
return getLastPeriod( 'month', compare );
|
||||
case 'quarter':
|
||||
return getCurrentPeriod( 'quarter', compare );
|
||||
case 'last_quarter':
|
||||
return getLastPeriod( 'quarter', compare );
|
||||
case 'year':
|
||||
return getCurrentPeriod( 'year', compare );
|
||||
case 'last_year':
|
||||
return getLastPeriod( 'year', compare );
|
||||
case 'custom':
|
||||
const difference = end.diff( start, 'days' );
|
||||
if ( 'previous_period' === compare ) {
|
||||
const secondaryEnd = start.clone().subtract( 1, 'days' );
|
||||
const secondaryStart = secondaryEnd.clone().subtract( difference, 'days' );
|
||||
return {
|
||||
primaryStart: start,
|
||||
primaryEnd: end,
|
||||
secondaryStart,
|
||||
secondaryEnd,
|
||||
};
|
||||
}
|
||||
return {
|
||||
primaryStart: start,
|
||||
primaryEnd: end,
|
||||
secondaryStart: start.clone().subtract( 1, 'years' ),
|
||||
secondaryEnd: end.clone().subtract( 1, 'years' ),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Date Value Objects for a primary and secondary date range
|
||||
*
|
||||
* @param {string} period - Indicates period, 'last_week', 'quarter', or 'custom'
|
||||
* @param {string} compare - Indicates the period to compare against, 'previous_period', previous_year'
|
||||
* @param {moment.Moment} [start] - If the period supplied is "custom", this is the start date
|
||||
* @param {moment.Moment} [end] - If the period supplied is "custom", this is the end date
|
||||
* @return {{primary: DateValue, secondary: DateValue}} - Primary and secondary DateValue objects
|
||||
*/
|
||||
export const getCurrentDates = ( { period, compare, start, end } ) => {
|
||||
const { primaryStart, primaryEnd, secondaryStart, secondaryEnd } = getDateValue(
|
||||
period,
|
||||
compare,
|
||||
start,
|
||||
end
|
||||
);
|
||||
|
||||
return {
|
||||
primary: {
|
||||
label: find( presetValues, item => item.value === period ).label,
|
||||
range: getRangeLabel( primaryStart, primaryEnd ),
|
||||
start: primaryStart,
|
||||
end: primaryEnd,
|
||||
},
|
||||
secondary: {
|
||||
label: find( compareValues, item => item.value === compare ).label,
|
||||
range: getRangeLabel( secondaryStart, secondaryEnd ),
|
||||
start: secondaryStart,
|
||||
end: secondaryEnd,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue