Add performance indicators to dashboard (https://github.com/woocommerce/woocommerce-admin/pull/1343)
* Add label and generated report URL to the performance indicator response. * Hook up performance indicators to the REST API * Handle PR feedback * Fix setting default values
This commit is contained in:
commit
2f60837ba5
|
@ -19,7 +19,7 @@ import { SummaryList, SummaryListPlaceholder, SummaryNumber } from '@woocommerce
|
|||
*/
|
||||
import { getSummaryNumbers } from 'store/reports/utils';
|
||||
import ReportError from 'analytics/components/report-error';
|
||||
import { calculateDelta, formatValue } from './utils';
|
||||
import { calculateDelta, formatValue } from 'lib/number';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/** @format */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { isFinite } from 'lodash';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
*/
|
||||
import { formatCurrency } from '@woocommerce/currency';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { numberFormat } from 'lib/number';
|
||||
|
||||
export function formatValue( type, value ) {
|
||||
if ( ! isFinite( value ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch ( type ) {
|
||||
case 'average':
|
||||
return Math.round( value );
|
||||
case 'currency':
|
||||
return formatCurrency( value );
|
||||
case 'number':
|
||||
return numberFormat( value );
|
||||
}
|
||||
}
|
||||
|
||||
export function calculateDelta( primaryValue, secondaryValue ) {
|
||||
if ( ! isFinite( primaryValue ) || ! isFinite( secondaryValue ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( secondaryValue === 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.round( ( primaryValue - secondaryValue ) / secondaryValue * 100 );
|
||||
}
|
|
@ -22,7 +22,7 @@ export default class Dashboard extends Component {
|
|||
<Fragment>
|
||||
<Header sections={ [ __( 'Dashboard', 'wc-admin' ) ] } />
|
||||
<ReportFilters query={ query } path={ path } />
|
||||
<StorePerformance />
|
||||
<StorePerformance query={ query } />
|
||||
<Leaderboards query={ query } />
|
||||
<DashboardCharts query={ query } path={ path } />
|
||||
</Fragment>
|
||||
|
|
|
@ -2,9 +2,19 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { ToggleControl } from '@wordpress/components';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
import moment from 'moment';
|
||||
import { find } from 'lodash';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
*/
|
||||
import { getCurrentDates, appendTimestamp, getDateParamsFromQuery } from '@woocommerce/date';
|
||||
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -16,99 +26,202 @@ import {
|
|||
MenuTitle,
|
||||
SectionHeader,
|
||||
SummaryList,
|
||||
SummaryListPlaceholder,
|
||||
SummaryNumber,
|
||||
} from '@woocommerce/components';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
import './style.scss';
|
||||
import { calculateDelta, formatValue } from 'lib/number';
|
||||
|
||||
class StorePerformance extends Component {
|
||||
constructor() {
|
||||
super( ...arguments );
|
||||
constructor( props ) {
|
||||
super( props );
|
||||
this.state = {
|
||||
showCustomers: true,
|
||||
showProducts: true,
|
||||
showOrders: true,
|
||||
userPrefs: props.userPrefs || [],
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind( this );
|
||||
}
|
||||
|
||||
toggle( type ) {
|
||||
toggle( statKey ) {
|
||||
return () => {
|
||||
this.setState( state => ( { [ type ]: ! state[ type ] } ) );
|
||||
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,
|
||||
};
|
||||
} );
|
||||
};
|
||||
}
|
||||
|
||||
renderMenu() {
|
||||
const { indicators } = this.props;
|
||||
return (
|
||||
<EllipsisMenu label={ __( 'Choose which analytics to display', 'wc-admin' ) }>
|
||||
<MenuTitle>{ __( 'Display Stats:', 'wc-admin' ) }</MenuTitle>
|
||||
<MenuItem onInvoke={ this.toggle( 'showCustomers' ) }>
|
||||
{ indicators.map( ( indicator, i ) => {
|
||||
const checked = ! this.state.userPrefs.includes( indicator.stat );
|
||||
return (
|
||||
<MenuItem onInvoke={ this.toggle( indicator.stat ) } key={ i }>
|
||||
<ToggleControl
|
||||
label={ __( 'Show Customers', 'wc-admin' ) }
|
||||
checked={ this.state.showCustomers }
|
||||
onChange={ this.toggle( 'showCustomers' ) }
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem onInvoke={ this.toggle( 'showProducts' ) }>
|
||||
<ToggleControl
|
||||
label={ __( 'Show Products', 'wc-admin' ) }
|
||||
checked={ this.state.showProducts }
|
||||
onChange={ this.toggle( 'showProducts' ) }
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem onInvoke={ this.toggle( 'showOrders' ) }>
|
||||
<ToggleControl
|
||||
label={ __( 'Show Orders', 'wc-admin' ) }
|
||||
checked={ this.state.showOrders }
|
||||
onChange={ this.toggle( 'showOrders' ) }
|
||||
label={ sprintf( __( 'Show %s', 'wc-admin' ), indicator.label ) }
|
||||
checked={ checked }
|
||||
onChange={ this.toggle( indicator.stat ) }
|
||||
/>
|
||||
</MenuItem>
|
||||
);
|
||||
} ) }
|
||||
</EllipsisMenu>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const totalOrders = 10;
|
||||
const totalProducts = 1000;
|
||||
const { showCustomers, showProducts, showOrders } = this.state;
|
||||
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>
|
||||
{ userIndicators.map( ( indicator, i ) => {
|
||||
const primaryItem = find( primaryData.data, data => data.stat === indicator.stat );
|
||||
const secondaryItem = find( secondaryData.data, data => data.stat === indicator.stat );
|
||||
|
||||
if ( ! primaryItem || ! secondaryItem ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const href =
|
||||
( primaryItem._links &&
|
||||
primaryItem._links.report[ 0 ] &&
|
||||
primaryItem._links.report[ 0 ].href ) ||
|
||||
'';
|
||||
const reportUrl =
|
||||
( href && getNewPath( persistedQuery, href, { chart: primaryItem.chart } ) ) || '';
|
||||
const delta = calculateDelta( primaryItem.value, secondaryItem.value );
|
||||
const primaryValue = formatValue( primaryItem.format, primaryItem.value );
|
||||
const secondaryValue = formatValue( secondaryItem.format, secondaryItem.value );
|
||||
|
||||
return (
|
||||
<SummaryNumber
|
||||
key={ i }
|
||||
href={ reportUrl }
|
||||
label={ indicator.label }
|
||||
value={ primaryValue }
|
||||
prevLabel={ prevLabel }
|
||||
prevValue={ secondaryValue }
|
||||
delta={ delta }
|
||||
/>
|
||||
);
|
||||
} ) }
|
||||
</SummaryList>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<SectionHeader title={ __( 'Store Performance', 'wc-admin' ) } menu={ this.renderMenu() } />
|
||||
<Card className="woocommerce-dashboard__store-performance">
|
||||
<SummaryList>
|
||||
{ showCustomers && (
|
||||
<SummaryNumber
|
||||
label={ __( 'New Customers', 'wc-admin' ) }
|
||||
value={ '2' }
|
||||
prevLabel={ __( 'Previous Week:', 'wc-admin' ) }
|
||||
prevValue={ 3 }
|
||||
delta={ -33 }
|
||||
/>
|
||||
) }
|
||||
{ showProducts && (
|
||||
<SummaryNumber
|
||||
label={ __( 'Total Products', 'wc-admin' ) }
|
||||
value={ totalProducts }
|
||||
prevLabel={ __( 'Previous Week:', 'wc-admin' ) }
|
||||
prevValue={ totalProducts }
|
||||
delta={ 0 }
|
||||
/>
|
||||
) }
|
||||
{ showOrders && (
|
||||
<SummaryNumber
|
||||
label={ __( 'Total Orders', 'wc-admin' ) }
|
||||
value={ totalOrders }
|
||||
prevLabel={ __( 'Previous Week:', 'wc-admin' ) }
|
||||
prevValue={ totalOrders }
|
||||
delta={ 0 }
|
||||
/>
|
||||
) }
|
||||
</SummaryList>
|
||||
</Card>
|
||||
<Card className="woocommerce-dashboard__store-performance">{ this.renderList() }</Card>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default compose(
|
||||
withSelect( ( select, props ) => {
|
||||
const { query } = props;
|
||||
const {
|
||||
getCurrentUserData,
|
||||
getReportItems,
|
||||
getReportItemsError,
|
||||
isReportItemsRequesting,
|
||||
} = select( 'wc-api' );
|
||||
const userData = getCurrentUserData();
|
||||
let userPrefs = userData.dashboard_performance_indicators;
|
||||
|
||||
export default StorePerformance;
|
||||
// Set default values for user preferences if none is set.
|
||||
// These columns are HIDDEN by default.
|
||||
if ( ! userPrefs ) {
|
||||
userPrefs = [ 'taxes/order_tax', 'taxes/shipping_tax', 'downloads/download_count' ];
|
||||
}
|
||||
|
||||
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( ',' );
|
||||
|
||||
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 );
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { get } from 'lodash';
|
||||
import { get, isFinite } from 'lodash';
|
||||
const number_format = require( 'locutus/php/strings/number_format' );
|
||||
import { formatCurrency } from '@woocommerce/currency';
|
||||
|
||||
/**
|
||||
* Formats a number using site's current locale
|
||||
|
@ -13,7 +14,6 @@ const number_format = require( 'locutus/php/strings/number_format' );
|
|||
* @param {int|null} [precision=null] optional decimal precision
|
||||
* @returns {?String} A formatted string.
|
||||
*/
|
||||
|
||||
export function numberFormat( number, precision = null ) {
|
||||
if ( 'number' !== typeof number ) {
|
||||
number = parseFloat( number );
|
||||
|
@ -34,3 +34,30 @@ export function numberFormat( number, precision = null ) {
|
|||
|
||||
return number_format( number, precision, decimalSeparator, thousandSeparator );
|
||||
}
|
||||
|
||||
export function formatValue( type, value ) {
|
||||
if ( ! isFinite( value ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch ( type ) {
|
||||
case 'average':
|
||||
return Math.round( value );
|
||||
case 'currency':
|
||||
return formatCurrency( value );
|
||||
case 'number':
|
||||
return numberFormat( value );
|
||||
}
|
||||
}
|
||||
|
||||
export function calculateDelta( primaryValue, secondaryValue ) {
|
||||
if ( ! isFinite( primaryValue ) || ! isFinite( secondaryValue ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( secondaryValue === 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.round( ( primaryValue - secondaryValue ) / secondaryValue * 100 );
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ const typeEndpointMap = {
|
|||
'report-items-query-downloads': 'downloads',
|
||||
'report-items-query-customers': 'customers',
|
||||
'report-items-query-stock': 'stock',
|
||||
'report-items-query-performance-indicators': 'performance-indicators',
|
||||
};
|
||||
|
||||
function read( resourceNames, fetch = apiFetch ) {
|
||||
|
|
|
@ -40,6 +40,7 @@ function updateCurrentUserData( resourceNames, data, fetch ) {
|
|||
'revenue_report_columns',
|
||||
'taxes_report_columns',
|
||||
'variations_report_columns',
|
||||
'dashboard_performance_indicators',
|
||||
'dashboard_charts',
|
||||
'dashboard_chart_type',
|
||||
'dashboard_chart_interval',
|
||||
|
|
|
@ -64,6 +64,7 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all reports.
|
||||
*
|
||||
|
@ -135,7 +136,36 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
|
|||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core.
|
||||
* Array items should be in format of array( 'slug' => 'downloads/stats', 'description' => '',
|
||||
* 'url' => '', and 'path' => '/wc-ext/v1/...'.
|
||||
*
|
||||
* @param array $endpoints The list of allowed reports..
|
||||
*/
|
||||
$reports = apply_filters( 'woocommerce_admin_reports', $reports );
|
||||
|
||||
foreach ( $reports as $report ) {
|
||||
if ( empty( $report['slug'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( empty( $report['path'] ) ) {
|
||||
$report['path'] = '/' . $this->namespace . '/reports/' . $report['slug'];
|
||||
}
|
||||
|
||||
// Allows a different admin page to be loaded here,
|
||||
// or allows an empty url if no report exists for a set of performance indicators.
|
||||
if ( ! isset( $report['url'] ) ) {
|
||||
if ( '/stats' === substr( $report['slug'], -6 ) ) {
|
||||
$url_slug = substr( $report['slug'], 0, -6 );
|
||||
} else {
|
||||
$url_slug = $report['slug'];
|
||||
}
|
||||
|
||||
$report['url'] = '/analytics/' . $url_slug;
|
||||
}
|
||||
|
||||
$item = $this->prepare_item_for_response( (object) $report, $request );
|
||||
$data[] = $this->prepare_response_for_collection( $item );
|
||||
}
|
||||
|
@ -154,6 +184,7 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
|
|||
$data = array(
|
||||
'slug' => $report->slug,
|
||||
'description' => $report->description,
|
||||
'path' => $report->path,
|
||||
);
|
||||
|
||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||
|
@ -165,7 +196,10 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
|
|||
$response->add_links(
|
||||
array(
|
||||
'self' => array(
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ),
|
||||
'href' => rest_url( $report->path ),
|
||||
),
|
||||
'report' => array(
|
||||
'href' => $report->url,
|
||||
),
|
||||
'collection' => array(
|
||||
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
|
||||
|
@ -208,6 +242,12 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
|
|||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'path' => array(
|
||||
'description' => __( 'API path.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -138,6 +138,8 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con
|
|||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'coupons_count' => array(
|
||||
'description' => __( 'Amount of coupons.', 'wc-admin' ),
|
||||
|
@ -146,10 +148,11 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con
|
|||
'readonly' => true,
|
||||
),
|
||||
'orders_count' => array(
|
||||
'description' => __( 'Amount of orders.', 'wc-admin' ),
|
||||
'description' => __( 'Amount of discounted orders.', 'wc-admin' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -143,6 +143,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C
|
|||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -146,18 +146,22 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report
|
|||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'avg_order_value' => array(
|
||||
'description' => __( 'Average order value.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'orders_count' => array(
|
||||
'description' => __( 'Amount of orders', 'wc-admin' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
),
|
||||
'avg_order_value' => array(
|
||||
'description' => __( 'Average order value.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'avg_items_per_order' => array(
|
||||
'description' => __( 'Average items per order', 'wc-admin' ),
|
||||
|
|
|
@ -31,6 +31,67 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
*/
|
||||
protected $rest_base = 'reports/performance-indicators';
|
||||
|
||||
/**
|
||||
* Contains a list of endpoints by report slug.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $endpoints = array();
|
||||
|
||||
/**
|
||||
* Contains a list of allowed stats.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowed_stats = array();
|
||||
|
||||
/**
|
||||
* Contains a list of stat labels.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $labels = array();
|
||||
|
||||
/**
|
||||
* Contains a list of endpoints by url.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $urls = array();
|
||||
|
||||
/**
|
||||
* Register the routes for reports.
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base,
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/allowed',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_allowed_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_allowed_item_schema' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps query arguments from the REST request.
|
||||
*
|
||||
|
@ -46,12 +107,15 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all allowed stats that can be returned from this endpoint.
|
||||
* Get information such as allowed stats, stat labels, and endpoint data from stats reports.
|
||||
*
|
||||
* @return array
|
||||
* @return WP_Error|True
|
||||
*/
|
||||
public function get_allowed_stats() {
|
||||
global $wp_rest_server;
|
||||
private function get_indicator_data() {
|
||||
// Data already retrieved.
|
||||
if ( ! empty( $this->endpoints ) && ! empty( $this->labels ) && ! empty( $this->allowed_stats ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/wc/v4/reports' );
|
||||
$response = rest_do_request( $request );
|
||||
|
@ -63,9 +127,10 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
|
||||
foreach ( $endpoints as $endpoint ) {
|
||||
if ( '/stats' === substr( $endpoint['slug'], -6 ) ) {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wc/v4/reports/' . $endpoint['slug'] );
|
||||
$request = new WP_REST_Request( 'OPTIONS', $endpoint['path'] );
|
||||
$response = rest_do_request( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$prefix = substr( $endpoint['slug'], 0, -6 );
|
||||
|
||||
if ( empty( $data['schema']['properties']['totals']['properties'] ) ) {
|
||||
|
@ -73,17 +138,113 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
}
|
||||
|
||||
foreach ( $data['schema']['properties']['totals']['properties'] as $property_key => $schema_info ) {
|
||||
$allowed_stats[] = $prefix . '/' . $property_key;
|
||||
if ( empty( $schema_info['indicator'] ) || ! $schema_info['indicator'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$stat = $prefix . '/' . $property_key;
|
||||
$allowed_stats[] = $stat;
|
||||
|
||||
$this->labels[ $stat ] = trim( preg_replace( '/\W+/', ' ', $schema_info['description'] ) );
|
||||
$this->formats[ $stat ] = isset( $schema_info['format'] ) ? $schema_info['format'] : 'number';
|
||||
}
|
||||
|
||||
$this->endpoints[ $prefix ] = $endpoint['path'];
|
||||
$this->urls[ $prefix ] = $endpoint['_links']['report'][0]['href'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->allowed_stats = $allowed_stats;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of allowed stats that can be returned via the performance indiciator endpoint.
|
||||
* Returns a list of allowed performance indicators.
|
||||
*
|
||||
* @param array $allowed_stats The list of allowed stats.
|
||||
* @param WP_REST_Request $request Request data.
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
return apply_filters( 'woocommerce_admin_performance_indicators_allowed_stats', $allowed_stats );
|
||||
public function get_allowed_items( $request ) {
|
||||
$indicator_data = $this->get_indicator_data();
|
||||
if ( is_wp_error( $indicator_data ) ) {
|
||||
return $indicator_data;
|
||||
}
|
||||
|
||||
$data = array();
|
||||
foreach ( $this->allowed_stats as $stat ) {
|
||||
$pieces = $this->get_stats_parts( $stat );
|
||||
$report = $pieces[0];
|
||||
$chart = $pieces[1];
|
||||
$data[] = (object) array(
|
||||
'stat' => $stat,
|
||||
'chart' => $chart,
|
||||
'label' => $this->labels[ $stat ],
|
||||
);
|
||||
}
|
||||
|
||||
usort( $data, array( $this, 'sort' ) );
|
||||
|
||||
$objects = array();
|
||||
foreach ( $data as $item ) {
|
||||
$prepared = $this->prepare_item_for_response( $item, $request );
|
||||
$objects[] = $this->prepare_response_for_collection( $prepared );
|
||||
}
|
||||
|
||||
$response = rest_ensure_response( $objects );
|
||||
$response->header( 'X-WP-Total', count( $data ) );
|
||||
$response->header( 'X-WP-TotalPages', 1 );
|
||||
|
||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list of stats. Sorted by custom arrangement.
|
||||
*
|
||||
* @see https://github.com/woocommerce/wc-admin/issues/1282
|
||||
* @param object $a First item.
|
||||
* @param object $b Second item.
|
||||
* @return order
|
||||
*/
|
||||
public function sort( $a, $b ) {
|
||||
/**
|
||||
* Custom ordering for store performance indicators.
|
||||
*
|
||||
* @see https://github.com/woocommerce/wc-admin/issues/1282
|
||||
* @param array $indicators A list of ordered indicators.
|
||||
*/
|
||||
$stat_order = apply_filters(
|
||||
'woocommerce_rest_report_sort_performance_indicators',
|
||||
array(
|
||||
'revenue/gross_revenue',
|
||||
'revenue/net_revenue',
|
||||
'orders/orders_count',
|
||||
'orders/avg_order_value',
|
||||
'products/items_sold',
|
||||
'revenue/refunds',
|
||||
'coupons/orders_count',
|
||||
'coupons/amount',
|
||||
'taxes/total_tax',
|
||||
'taxes/order_tax',
|
||||
'taxes/shipping_tax',
|
||||
'revenue/shipping',
|
||||
'downloads/download_count',
|
||||
)
|
||||
);
|
||||
|
||||
$a = array_search( $a->stat, $stat_order );
|
||||
$b = array_search( $b->stat, $stat_order );
|
||||
|
||||
if ( false === $a && false === $b ) {
|
||||
return 0;
|
||||
} elseif ( false === $a ) {
|
||||
return 1;
|
||||
} elseif ( false === $b ) {
|
||||
return -1;
|
||||
} else {
|
||||
return $a - $b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,10 +254,9 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$allowed_stats = $this->get_allowed_stats();
|
||||
|
||||
if ( is_wp_error( $allowed_stats ) ) {
|
||||
return $allowed_stats;
|
||||
$indicator_data = $this->get_indicator_data();
|
||||
if ( is_wp_error( $indicator_data ) ) {
|
||||
return $indicator_data;
|
||||
}
|
||||
|
||||
$query_args = $this->prepare_reports_query( $request );
|
||||
|
@ -105,51 +265,50 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
}
|
||||
|
||||
$stats = array();
|
||||
foreach ( $query_args['stats'] as $stat_request ) {
|
||||
foreach ( $query_args['stats'] as $stat ) {
|
||||
$is_error = false;
|
||||
|
||||
$pieces = explode( '/', $stat_request );
|
||||
$endpoint = $pieces[0];
|
||||
$stat = $pieces[1];
|
||||
$pieces = $this->get_stats_parts( $stat );
|
||||
$report = $pieces[0];
|
||||
$chart = $pieces[1];
|
||||
|
||||
if ( ! in_array( $stat_request, $allowed_stats ) ) {
|
||||
if ( ! in_array( $stat, $this->allowed_stats ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of allowed endpoints, so that data can be loaded from extensions rather than core.
|
||||
* These should be in the format of slug => path. Example: `bookings` => `/wc-bookings/v1/reports/bookings/stats`.
|
||||
*
|
||||
* @param array $endpoints The list of allowed endpoints.
|
||||
*/
|
||||
$stats_endpoints = apply_filters( 'woocommerce_admin_performance_indicators_stats_endpoints', array() );
|
||||
if ( ! empty( $stats_endpoints [ $endpoint ] ) ) {
|
||||
$request_url = $stats_endpoints [ $endpoint ];
|
||||
} else {
|
||||
$request_url = '/wc/v4/reports/' . $endpoint . '/stats';
|
||||
}
|
||||
|
||||
$request_url = $this->endpoints[ $report ];
|
||||
$request = new WP_REST_Request( 'GET', $request_url );
|
||||
$request->set_param( 'before', $query_args['before'] );
|
||||
$request->set_param( 'after', $query_args['after'] );
|
||||
|
||||
$response = rest_do_request( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
if ( 200 !== $response->get_status() || empty( $data['totals'][ $stat ] ) ) {
|
||||
$data = $response->get_data();
|
||||
$format = $this->formats[ $stat ];
|
||||
$label = $this->labels[ $stat ];
|
||||
|
||||
if ( 200 !== $response->get_status() || ! isset( $data['totals'][ $chart ] ) ) {
|
||||
$stats[] = (object) array(
|
||||
'stat' => $stat_request,
|
||||
'stat' => $stat,
|
||||
'chart' => $chart,
|
||||
'label' => $label,
|
||||
'format' => $format,
|
||||
'value' => null,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$stats[] = (object) array(
|
||||
'stat' => $stat_request,
|
||||
'value' => $data['totals'][ $stat ],
|
||||
'stat' => $stat,
|
||||
'chart' => $chart,
|
||||
'label' => $label,
|
||||
'format' => $format,
|
||||
'value' => $data['totals'][ $chart ],
|
||||
);
|
||||
}
|
||||
|
||||
usort( $stats, array( $this, 'sort' ) );
|
||||
|
||||
$objects = array();
|
||||
foreach ( $stats as $stat ) {
|
||||
$data = $this->prepare_item_for_response( $stat, $request );
|
||||
|
@ -201,25 +360,52 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
* @return array
|
||||
*/
|
||||
protected function prepare_links( $object ) {
|
||||
$pieces = explode( '/', $object->stat );
|
||||
$pieces = $this->get_stats_parts( $object->stat );
|
||||
$endpoint = $pieces[0];
|
||||
$stat = $pieces[1];
|
||||
$url = $this->urls[ $endpoint ];
|
||||
|
||||
$links = array(
|
||||
'api' => array(
|
||||
'href' => rest_url( $this->endpoints[ $endpoint ] ),
|
||||
),
|
||||
'report' => array(
|
||||
'href' => rest_url( sprintf( '/%s/reports/%s/stats', $this->namespace, $endpoint ) ),
|
||||
'href' => ! empty( $url ) ? $url : '',
|
||||
),
|
||||
);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the endpoint part of a stat request (prefix) and the actual stat total we want.
|
||||
* To allow extensions to namespace (example: fue/emails/sent), we break on the last forward slash.
|
||||
*
|
||||
* @param string $full_stat A stat request string like orders/avg_order_value or fue/emails/sent.
|
||||
* @return array Containing the prefix (endpoint) and suffix (stat).
|
||||
*/
|
||||
private function get_stats_parts( $full_stat ) {
|
||||
$endpoint = substr( $full_stat, 0, strrpos( $full_stat, '/' ) );
|
||||
$stat = substr( $full_stat, ( strrpos( $full_stat, '/' ) + 1 ) );
|
||||
return array(
|
||||
$endpoint,
|
||||
$stat,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Report's schema, conforming to JSON Schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
$indicator_data = $this->get_indicator_data();
|
||||
if ( is_wp_error( $indicator_data ) ) {
|
||||
$allowed_stats = array();
|
||||
} else {
|
||||
$allowed_stats = $this->allowed_stats;
|
||||
}
|
||||
|
||||
$schema = array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'report_performance_indicator',
|
||||
|
@ -230,6 +416,26 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'enum' => $allowed_stats,
|
||||
),
|
||||
'chart' => array(
|
||||
'description' => __( 'The specific chart this stat referrers to.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'label' => array(
|
||||
'description' => __( 'Human readable label for the stat.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'format' => array(
|
||||
'description' => __( 'Format of the stat.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'enum' => array( 'number', 'currency' ),
|
||||
),
|
||||
'value' => array(
|
||||
'description' => __( 'Value of the stat. Returns null if the stat does not exist or cannot be loaded.', 'wc-admin' ),
|
||||
|
@ -243,17 +449,29 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re
|
|||
return $this->add_additional_fields_schema( $schema );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schema for the list of allowed performance indicators.
|
||||
*
|
||||
* @return array $schema
|
||||
*/
|
||||
public function get_public_allowed_item_schema() {
|
||||
$schema = $this->get_public_item_schema();
|
||||
unset( $schema['properties']['value'] );
|
||||
unset( $schema['properties']['format'] );
|
||||
return $sceham;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query params for collections.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
$allowed_stats = $this->get_allowed_stats();
|
||||
if ( is_wp_error( $allowed_stats ) ) {
|
||||
$indicator_data = $this->get_indicator_data();
|
||||
if ( is_wp_error( $indicator_data ) ) {
|
||||
$allowed_stats = __( 'There was an issue loading the report endpoints', 'wc-admin' );
|
||||
} else {
|
||||
$allowed_stats = implode( ', ', $allowed_stats );
|
||||
$allowed_stats = implode( ', ', $this->allowed_stats );
|
||||
}
|
||||
|
||||
$params = array();
|
||||
|
|
|
@ -152,12 +152,14 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co
|
|||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
),
|
||||
'net_revenue' => array(
|
||||
'description' => __( 'Net revenue.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'orders_count' => array(
|
||||
'description' => __( 'Number of orders.', 'wc-admin' ),
|
||||
|
|
|
@ -136,51 +136,61 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con
|
|||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'net_revenue' => array(
|
||||
'description' => __( 'Net revenue.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'coupons' => array(
|
||||
'description' => __( 'Total of coupons.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'shipping' => array(
|
||||
'description' => __( 'Total of shipping.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'taxes' => array(
|
||||
'description' => __( 'Total of taxes.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'refunds' => array(
|
||||
'description' => __( 'Total of refunds.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'orders_count' => array(
|
||||
'description' => __( 'Amount of orders', 'wc-admin' ),
|
||||
'description' => __( 'Amount of orders.', 'wc-admin' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'num_items_sold' => array(
|
||||
'description' => __( 'Amount of orders', 'wc-admin' ),
|
||||
'description' => __( 'Items sold.', 'wc-admin' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'products' => array(
|
||||
'description' => __( 'Amount of orders', 'wc-admin' ),
|
||||
'description' => __( 'Products sold.', 'wc-admin' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
|
|
|
@ -167,18 +167,24 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr
|
|||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'order_tax' => array(
|
||||
'description' => __( 'Order tax.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'shipping_tax' => array(
|
||||
'description' => __( 'Shipping tax.', 'wc-admin' ),
|
||||
'type' => 'number',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'indicator' => true,
|
||||
'format' => 'currency',
|
||||
),
|
||||
'orders_count' => array(
|
||||
'description' => __( 'Amount of orders.', 'wc-admin' ),
|
||||
|
|
|
@ -399,6 +399,7 @@ function wc_admin_get_user_data_fields() {
|
|||
'revenue_report_columns',
|
||||
'taxes_report_columns',
|
||||
'variations_report_columns',
|
||||
'dashboard_performance_indicators',
|
||||
'dashboard_charts',
|
||||
'dashboard_chart_type',
|
||||
'dashboard_chart_interval',
|
||||
|
|
|
@ -154,6 +154,7 @@ function wc_admin_print_script_settings() {
|
|||
|
||||
$preload_data_endpoints = array(
|
||||
'countries' => '/wc/v4/data/countries',
|
||||
'performanceIndicators' => '/wc/v4/reports/performance-indicators/allowed',
|
||||
);
|
||||
|
||||
if ( function_exists( 'gutenberg_preload_api_request' ) ) {
|
||||
|
@ -169,7 +170,7 @@ function wc_admin_print_script_settings() {
|
|||
|
||||
$current_user_data = array();
|
||||
foreach ( wc_admin_get_user_data_fields() as $user_field ) {
|
||||
$current_user_data[ $user_field ] = get_user_meta( get_current_user_id(), 'wc_admin_' . $user_field, true );
|
||||
$current_user_data[ $user_field ] = json_decode( get_user_meta( get_current_user_id(), 'wc_admin_' . $user_field, true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# 1.4.1 (unreleased)
|
||||
- Chart component: format numbers and prices using store currency settings.
|
||||
- Make `href`/linking optional in SummaryNumber.
|
||||
|
||||
# 1.4.0
|
||||
- Add download log ip address autocompleter to search component
|
||||
|
|
|
@ -52,11 +52,14 @@ const SummaryNumber = ( {
|
|||
screenReaderLabel = sprintf( __( 'No change from %s', 'wc-admin' ), prevLabel );
|
||||
}
|
||||
|
||||
const Container = onToggle ? Button : Link;
|
||||
let Container;
|
||||
const containerProps = {
|
||||
className: classes,
|
||||
'aria-current': selected ? 'page' : null,
|
||||
};
|
||||
|
||||
if ( onToggle || href ) {
|
||||
Container = onToggle ? Button : Link;
|
||||
if ( ! onToggle ) {
|
||||
containerProps.href = href;
|
||||
containerProps.role = 'menuitem';
|
||||
|
@ -64,6 +67,9 @@ const SummaryNumber = ( {
|
|||
containerProps.onClick = onToggle;
|
||||
containerProps[ 'aria-expanded' ] = isOpen;
|
||||
}
|
||||
} else {
|
||||
Container = 'div';
|
||||
}
|
||||
|
||||
return (
|
||||
<li className={ liClasses }>
|
||||
|
@ -109,7 +115,7 @@ SummaryNumber.propTypes = {
|
|||
/**
|
||||
* An internal link to the report focused on this number.
|
||||
*/
|
||||
href: PropTypes.string.isRequired,
|
||||
href: PropTypes.string,
|
||||
/**
|
||||
* Boolean describing whether the menu list is open. Only applies in mobile view,
|
||||
* and only applies to the toggle-able item (first in the list).
|
||||
|
@ -147,7 +153,7 @@ SummaryNumber.propTypes = {
|
|||
};
|
||||
|
||||
SummaryNumber.defaultProps = {
|
||||
href: '/analytics',
|
||||
href: '',
|
||||
isOpen: false,
|
||||
prevLabel: __( 'Previous Period:', 'wc-admin' ),
|
||||
reverseTrend: false,
|
||||
|
|
|
@ -37,6 +37,7 @@ class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case
|
|||
$routes = $this->server->get_routes();
|
||||
|
||||
$this->assertArrayHasKey( $this->endpoint, $routes );
|
||||
$this->assertArrayHasKey( $this->endpoint . '/allowed', $routes );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,14 +97,19 @@ class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case
|
|||
$reports = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$this->assertEquals( 2, count( $reports ) );
|
||||
|
||||
$this->assertEquals( 'orders/orders_count', $reports[0]['stat'] );
|
||||
$this->assertEquals( 'Amount of orders', $reports[0]['label'] );
|
||||
$this->assertEquals( 1, $reports[0]['value'] );
|
||||
$this->assertEquals( 'orders_count', $reports[0]['chart'] );
|
||||
$this->assertEquals( '/analytics/orders', $response->data[0]['_links']['report'][0]['href'] );
|
||||
|
||||
$this->assertEquals( 'downloads/download_count', $reports[1]['stat'] );
|
||||
$this->assertEquals( 'Number of downloads', $reports[1]['label'] );
|
||||
$this->assertEquals( 2, $reports[1]['value'] );
|
||||
$this->assertEquals( 'download_count', $reports[1]['chart'] );
|
||||
$this->assertEquals( '/analytics/downloads', $response->data[1]['_links']['report'][0]['href'] );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,8 +154,11 @@ class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case
|
|||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
|
||||
$this->assertEquals( 2, count( $properties ) );
|
||||
$this->assertEquals( 5, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'stat', $properties );
|
||||
$this->assertArrayHasKey( 'chart', $properties );
|
||||
$this->assertArrayHasKey( 'label', $properties );
|
||||
$this->assertArrayHasKey( 'format', $properties );
|
||||
$this->assertArrayHasKey( 'value', $properties );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue