2018-05-03 18:23:17 +00:00
|
|
|
/** @format */
|
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2019-01-17 14:08:59 +00:00
|
|
|
import { __, sprintf } from '@wordpress/i18n';
|
2018-08-01 19:07:17 +00:00
|
|
|
import { ToggleControl } from '@wordpress/components';
|
2018-10-31 02:07:16 +00:00
|
|
|
import { Component, Fragment } from '@wordpress/element';
|
2019-01-17 14:08:59 +00:00
|
|
|
import { compose } from '@wordpress/compose';
|
|
|
|
import { withDispatch } from '@wordpress/data';
|
|
|
|
import moment from 'moment';
|
|
|
|
import { find } from 'lodash';
|
2018-05-03 18:23:17 +00:00
|
|
|
|
2019-01-18 13:52:10 +00:00
|
|
|
/**
|
|
|
|
* WooCommerce dependencies
|
|
|
|
*/
|
|
|
|
import { getCurrentDates, appendTimestamp, getDateParamsFromQuery } from '@woocommerce/date';
|
|
|
|
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
|
2019-01-29 16:48:46 +00:00
|
|
|
import { calculateDelta, formatValue } from '@woocommerce/number';
|
|
|
|
import { formatCurrency } from '@woocommerce/currency';
|
2019-01-18 13:52:10 +00:00
|
|
|
|
2018-05-10 19:23:41 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
2018-08-20 21:18:13 +00:00
|
|
|
import {
|
|
|
|
Card,
|
|
|
|
EllipsisMenu,
|
|
|
|
MenuItem,
|
|
|
|
MenuTitle,
|
2018-10-31 02:07:16 +00:00
|
|
|
SectionHeader,
|
2018-08-20 21:18:13 +00:00
|
|
|
SummaryList,
|
2019-01-17 14:08:59 +00:00
|
|
|
SummaryListPlaceholder,
|
2018-08-20 21:18:13 +00:00
|
|
|
SummaryNumber,
|
|
|
|
} from '@woocommerce/components';
|
2019-01-17 14:08:59 +00:00
|
|
|
import withSelect from 'wc-api/with-select';
|
2018-06-29 18:27:18 +00:00
|
|
|
import './style.scss';
|
2018-05-10 19:23:41 +00:00
|
|
|
|
2018-07-02 18:08:50 +00:00
|
|
|
class StorePerformance extends Component {
|
2019-01-17 14:08:59 +00:00
|
|
|
constructor( props ) {
|
|
|
|
super( props );
|
2018-05-14 15:47:42 +00:00
|
|
|
this.state = {
|
2019-01-17 14:08:59 +00:00
|
|
|
userPrefs: props.userPrefs || [],
|
2018-05-14 15:47:42 +00:00
|
|
|
};
|
|
|
|
this.toggle = this.toggle.bind( this );
|
|
|
|
}
|
|
|
|
|
2019-01-17 14:08:59 +00:00
|
|
|
toggle( statKey ) {
|
2018-05-14 15:47:42 +00:00
|
|
|
return () => {
|
2019-01-17 14:08:59 +00:00
|
|
|
this.setState( state => {
|
|
|
|
const prefs = [ ...state.userPrefs ];
|
|
|
|
let newPrefs = [];
|
|
|
|
if ( ! prefs.includes( statKey ) ) {
|
|
|
|
prefs.push( statKey );
|
|
|
|
newPrefs = prefs;
|
|
|
|
} else {
|
|
|
|
newPrefs = prefs.filter( pref => pref !== statKey );
|
|
|
|
}
|
|
|
|
this.props.updateCurrentUserData( {
|
|
|
|
dashboard_performance_indicators: newPrefs,
|
|
|
|
} );
|
|
|
|
return {
|
|
|
|
userPrefs: newPrefs,
|
|
|
|
};
|
|
|
|
} );
|
2018-05-14 15:47:42 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
renderMenu() {
|
2019-01-17 14:08:59 +00:00
|
|
|
const { indicators } = this.props;
|
2018-05-14 15:47:42 +00:00
|
|
|
return (
|
2018-07-10 12:48:06 +00:00
|
|
|
<EllipsisMenu label={ __( 'Choose which analytics to display', 'wc-admin' ) }>
|
|
|
|
<MenuTitle>{ __( 'Display Stats:', 'wc-admin' ) }</MenuTitle>
|
2019-01-17 14:08:59 +00:00
|
|
|
{ indicators.map( ( indicator, i ) => {
|
|
|
|
const checked = ! this.state.userPrefs.includes( indicator.stat );
|
|
|
|
return (
|
|
|
|
<MenuItem onInvoke={ this.toggle( indicator.stat ) } key={ i }>
|
|
|
|
<ToggleControl
|
|
|
|
label={ sprintf( __( 'Show %s', 'wc-admin' ), indicator.label ) }
|
|
|
|
checked={ checked }
|
|
|
|
onChange={ this.toggle( indicator.stat ) }
|
|
|
|
/>
|
|
|
|
</MenuItem>
|
|
|
|
);
|
|
|
|
} ) }
|
2018-05-14 15:47:42 +00:00
|
|
|
</EllipsisMenu>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-01-17 14:08:59 +00:00
|
|
|
renderList() {
|
|
|
|
const {
|
|
|
|
query,
|
|
|
|
primaryRequesting,
|
|
|
|
secondaryRequesting,
|
|
|
|
primaryError,
|
|
|
|
secondaryError,
|
|
|
|
primaryData,
|
|
|
|
secondaryData,
|
|
|
|
userIndicators,
|
|
|
|
} = this.props;
|
|
|
|
if ( primaryRequesting || secondaryRequesting ) {
|
|
|
|
return <SummaryListPlaceholder numberOfItems={ userIndicators.length } />;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( primaryError || secondaryError ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
const persistedQuery = getPersistedQuery( query );
|
|
|
|
|
|
|
|
const { compare } = getDateParamsFromQuery( query );
|
|
|
|
const prevLabel =
|
|
|
|
'previous_period' === compare
|
|
|
|
? __( 'Previous Period:', 'wc-admin' )
|
|
|
|
: __( 'Previous Year:', 'wc-admin' );
|
|
|
|
return (
|
|
|
|
<SummaryList>
|
2019-01-17 03:28:41 +00:00
|
|
|
{ () =>
|
|
|
|
userIndicators.map( ( indicator, i ) => {
|
|
|
|
const primaryItem = find( primaryData.data, data => data.stat === indicator.stat );
|
|
|
|
const secondaryItem = find( secondaryData.data, data => data.stat === indicator.stat );
|
2018-05-14 15:47:42 +00:00
|
|
|
|
2019-01-17 03:28:41 +00:00
|
|
|
if ( ! primaryItem || ! secondaryItem ) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-01-17 14:08:59 +00:00
|
|
|
|
2019-01-17 03:28:41 +00:00
|
|
|
const href =
|
|
|
|
( primaryItem._links &&
|
|
|
|
primaryItem._links.report[ 0 ] &&
|
|
|
|
primaryItem._links.report[ 0 ].href ) ||
|
|
|
|
'';
|
|
|
|
const reportUrl =
|
|
|
|
( href && getNewPath( persistedQuery, href, { chart: primaryItem.chart } ) ) || '';
|
2019-01-29 16:48:46 +00:00
|
|
|
const isCurrency = 'currency' === primaryItem.format;
|
|
|
|
|
2019-01-17 03:28:41 +00:00
|
|
|
const delta = calculateDelta( primaryItem.value, secondaryItem.value );
|
2019-01-29 16:48:46 +00:00
|
|
|
const primaryValue = isCurrency
|
|
|
|
? formatCurrency( primaryItem.value )
|
|
|
|
: formatValue( primaryItem.format, primaryItem.value );
|
|
|
|
const secondaryValue = isCurrency
|
|
|
|
? formatCurrency( secondaryItem.value )
|
|
|
|
: formatValue( secondaryItem.format, secondaryItem.value );
|
2019-01-17 14:08:59 +00:00
|
|
|
|
2019-01-17 03:28:41 +00:00
|
|
|
return (
|
|
|
|
<SummaryNumber
|
|
|
|
key={ i }
|
|
|
|
href={ reportUrl }
|
|
|
|
label={ indicator.label }
|
|
|
|
value={ primaryValue }
|
|
|
|
prevLabel={ prevLabel }
|
|
|
|
prevValue={ secondaryValue }
|
|
|
|
delta={ delta }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
} )
|
|
|
|
}
|
2019-01-17 14:08:59 +00:00
|
|
|
</SummaryList>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2018-05-03 18:23:17 +00:00
|
|
|
return (
|
2018-10-31 02:07:16 +00:00
|
|
|
<Fragment>
|
|
|
|
<SectionHeader title={ __( 'Store Performance', 'wc-admin' ) } menu={ this.renderMenu() } />
|
2019-01-17 14:08:59 +00:00
|
|
|
<Card className="woocommerce-dashboard__store-performance">{ this.renderList() }</Card>
|
2018-10-31 02:07:16 +00:00
|
|
|
</Fragment>
|
2018-05-03 18:23:17 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2019-01-17 14:08:59 +00:00
|
|
|
export default compose(
|
|
|
|
withSelect( ( select, props ) => {
|
|
|
|
const { query } = props;
|
|
|
|
const {
|
|
|
|
getCurrentUserData,
|
|
|
|
getReportItems,
|
|
|
|
getReportItemsError,
|
|
|
|
isReportItemsRequesting,
|
|
|
|
} = select( 'wc-api' );
|
|
|
|
const userData = getCurrentUserData();
|
2019-01-18 17:10:25 +00:00
|
|
|
let userPrefs = userData.dashboard_performance_indicators;
|
|
|
|
|
|
|
|
// Set default values for user preferences if none is set.
|
|
|
|
// These columns are HIDDEN by default.
|
|
|
|
if ( ! userPrefs ) {
|
2019-01-18 20:11:38 +00:00
|
|
|
userPrefs = [ 'taxes/order_tax', 'taxes/shipping_tax', 'downloads/download_count' ];
|
2019-01-18 17:10:25 +00:00
|
|
|
}
|
2019-01-17 14:08:59 +00:00
|
|
|
|
|
|
|
const datesFromQuery = getCurrentDates( query );
|
|
|
|
const endPrimary = datesFromQuery.primary.before;
|
|
|
|
const endSecondary = datesFromQuery.secondary.before;
|
|
|
|
|
|
|
|
const indicators = wcSettings.dataEndpoints.performanceIndicators;
|
|
|
|
const userIndicators = indicators.filter( indicator => ! userPrefs.includes( indicator.stat ) );
|
|
|
|
const statKeys = userIndicators.map( indicator => indicator.stat ).join( ',' );
|
2018-05-03 18:23:17 +00:00
|
|
|
|
2019-01-17 14:08:59 +00:00
|
|
|
const primaryQuery = {
|
|
|
|
after: appendTimestamp( datesFromQuery.primary.after, 'start' ),
|
|
|
|
before: appendTimestamp( endPrimary, endPrimary.isSame( moment(), 'day' ) ? 'now' : 'end' ),
|
|
|
|
stats: statKeys,
|
|
|
|
};
|
|
|
|
|
|
|
|
const secondaryQuery = {
|
|
|
|
after: appendTimestamp( datesFromQuery.secondary.after, 'start' ),
|
|
|
|
before: appendTimestamp(
|
|
|
|
endSecondary,
|
|
|
|
endSecondary.isSame( moment(), 'day' ) ? 'now' : 'end'
|
|
|
|
),
|
|
|
|
stats: statKeys,
|
|
|
|
};
|
|
|
|
|
|
|
|
const primaryData = getReportItems( 'performance-indicators', primaryQuery );
|
|
|
|
const primaryError = getReportItemsError( 'performance-indicators', primaryQuery ) || null;
|
|
|
|
const primaryRequesting = isReportItemsRequesting( 'performance-indicators', primaryQuery );
|
|
|
|
|
|
|
|
const secondaryData = getReportItems( 'performance-indicators', secondaryQuery );
|
|
|
|
const secondaryError = getReportItemsError( 'performance-indicators', secondaryQuery ) || null;
|
|
|
|
const secondaryRequesting = isReportItemsRequesting( 'performance-indicators', secondaryQuery );
|
|
|
|
|
|
|
|
return {
|
|
|
|
userPrefs,
|
|
|
|
userIndicators,
|
|
|
|
indicators,
|
|
|
|
primaryData,
|
|
|
|
primaryError,
|
|
|
|
primaryRequesting,
|
|
|
|
secondaryData,
|
|
|
|
secondaryError,
|
|
|
|
secondaryRequesting,
|
|
|
|
};
|
|
|
|
} ),
|
|
|
|
withDispatch( dispatch => {
|
|
|
|
const { updateCurrentUserData } = dispatch( 'wc-api' );
|
|
|
|
|
|
|
|
return {
|
|
|
|
updateCurrentUserData,
|
|
|
|
};
|
|
|
|
} )
|
|
|
|
)( StorePerformance );
|