Add single category filter to products report (https://github.com/woocommerce/woocommerce-admin/pull/1350)
* Add namespace v4 for WC product/categories endpoint * Update categories wc-api to use v4 namespace constant * Add single product category filter to product categories report * Add link to filtered product report from category report * Use persistedQuery for category links * Check if category is defined before displaying category link * Remove selectedTags when filter does not match queried filter
This commit is contained in:
parent
4869401ec4
commit
3ac97e00c4
|
@ -11,6 +11,8 @@ import { map } from 'lodash';
|
||||||
* WooCommerce dependencies
|
* WooCommerce dependencies
|
||||||
*/
|
*/
|
||||||
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
|
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
|
||||||
|
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
|
||||||
|
import { Link } from '@woocommerce/components';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -68,8 +70,9 @@ class CategoriesReportTable extends Component {
|
||||||
getRowsContent( categoryStats ) {
|
getRowsContent( categoryStats ) {
|
||||||
return map( categoryStats, categoryStat => {
|
return map( categoryStats, categoryStat => {
|
||||||
const { category_id, items_sold, net_revenue, products_count, orders_count } = categoryStat;
|
const { category_id, items_sold, net_revenue, products_count, orders_count } = categoryStat;
|
||||||
const categories = this.props.categories;
|
const { categories, query } = this.props;
|
||||||
const category = categories[ category_id ];
|
const category = categories[ category_id ];
|
||||||
|
const persistedQuery = getPersistedQuery( query );
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -85,7 +88,17 @@ class CategoriesReportTable extends Component {
|
||||||
value: getCurrencyFormatDecimal( net_revenue ),
|
value: getCurrencyFormatDecimal( net_revenue ),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
display: numberFormat( products_count ),
|
display: category && (
|
||||||
|
<Link
|
||||||
|
href={ getNewPath( persistedQuery, 'categories', {
|
||||||
|
filter: 'single_category',
|
||||||
|
categories: category.id,
|
||||||
|
} ) }
|
||||||
|
type="wc-admin"
|
||||||
|
>
|
||||||
|
{ numberFormat( products_count ) }
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
value: products_count,
|
value: products_count,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,6 +60,31 @@ const filterConfig = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: __( 'Single Product Category', 'wc-admin' ),
|
||||||
|
value: 'select_category',
|
||||||
|
chartMode: 'item-comparison',
|
||||||
|
subFilters: [
|
||||||
|
{
|
||||||
|
component: 'Search',
|
||||||
|
value: 'single_category',
|
||||||
|
chartMode: 'item-comparison',
|
||||||
|
path: [ 'select_category' ],
|
||||||
|
settings: {
|
||||||
|
type: 'categories',
|
||||||
|
param: 'categories',
|
||||||
|
getLabels: getRequestByIdString( NAMESPACE + 'products/categories', category => ( {
|
||||||
|
id: category.id,
|
||||||
|
label: category.name,
|
||||||
|
} ) ),
|
||||||
|
labels: {
|
||||||
|
placeholder: __( 'Type to search for a product category', 'wc-admin' ),
|
||||||
|
button: __( 'Single Product Category', 'wc-admin' ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: __( 'Product Comparison', 'wc-admin' ),
|
label: __( 'Product Comparison', 'wc-admin' ),
|
||||||
value: 'compare-products',
|
value: 'compare-products',
|
||||||
|
|
|
@ -14,13 +14,14 @@ import { stringifyQuery } from '@woocommerce/navigation';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { isResourcePrefix, getResourceIdentifier, getResourceName } from '../utils';
|
import { isResourcePrefix, getResourceIdentifier, getResourceName } from '../utils';
|
||||||
|
import { NAMESPACE } from '../constants';
|
||||||
|
|
||||||
function read( resourceNames, fetch = apiFetch ) {
|
function read( resourceNames, fetch = apiFetch ) {
|
||||||
const filteredNames = resourceNames.filter( name => isResourcePrefix( name, 'category-query' ) );
|
const filteredNames = resourceNames.filter( name => isResourcePrefix( name, 'category-query' ) );
|
||||||
|
|
||||||
return filteredNames.map( async resourceName => {
|
return filteredNames.map( async resourceName => {
|
||||||
const query = getResourceIdentifier( resourceName );
|
const query = getResourceIdentifier( resourceName );
|
||||||
const url = `/wc/v3/products/categories${ stringifyQuery( query ) }`;
|
const url = NAMESPACE + `/products/categories${ stringifyQuery( query ) }`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const categories = await fetch( {
|
const categories = await fetch( {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Categories Controller
|
||||||
|
*
|
||||||
|
* Handles requests to /products/categories.
|
||||||
|
*
|
||||||
|
* @package WooCommerce Admin/API
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product categories controller.
|
||||||
|
*
|
||||||
|
* @package WooCommerce Admin/API
|
||||||
|
* @extends WC_REST_Product_Categories_Controller
|
||||||
|
*/
|
||||||
|
class WC_Admin_REST_Product_Categories_Controller extends WC_REST_Product_Categories_Controller {
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v4';
|
||||||
|
|
||||||
|
}
|
|
@ -162,6 +162,7 @@ class WC_Admin_Api_Init {
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-data-download-ips-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-data-download-ips-controller.php';
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-orders-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-orders-controller.php';
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-products-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-products-controller.php';
|
||||||
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-product-categories-controller.php';
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-product-reviews-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-product-reviews-controller.php';
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-controller.php';
|
||||||
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-system-status-tools-controller.php';
|
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-system-status-tools-controller.php';
|
||||||
|
@ -194,6 +195,7 @@ class WC_Admin_Api_Init {
|
||||||
'WC_Admin_REST_Data_Download_Ips_Controller',
|
'WC_Admin_REST_Data_Download_Ips_Controller',
|
||||||
'WC_Admin_REST_Orders_Controller',
|
'WC_Admin_REST_Orders_Controller',
|
||||||
'WC_Admin_REST_Products_Controller',
|
'WC_Admin_REST_Products_Controller',
|
||||||
|
'WC_Admin_REST_Product_Categories_Controller',
|
||||||
'WC_Admin_REST_Product_Reviews_Controller',
|
'WC_Admin_REST_Product_Reviews_Controller',
|
||||||
'WC_Admin_REST_Reports_Controller',
|
'WC_Admin_REST_Reports_Controller',
|
||||||
'WC_Admin_REST_System_Status_Tools_Controller',
|
'WC_Admin_REST_System_Status_Tools_Controller',
|
||||||
|
@ -339,6 +341,17 @@ class WC_Admin_Api_Init {
|
||||||
$endpoints['/wc/v4/products/(?P<id>[\d]+)'][2] = $endpoints['/wc/v4/products/(?P<id>[\d]+)'][5];
|
$endpoints['/wc/v4/products/(?P<id>[\d]+)'][2] = $endpoints['/wc/v4/products/(?P<id>[\d]+)'][5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override /wc/v4/products/categories.
|
||||||
|
if ( isset( $endpoints['/wc/v4/products/categories'] )
|
||||||
|
&& isset( $endpoints['/wc/v4/products/categories'][3] )
|
||||||
|
&& isset( $endpoints['/wc/v4/products/categories'][2] )
|
||||||
|
&& $endpoints['/wc/v4/products/categories'][2]['callback'][0] instanceof WC_Admin_REST_Product_categories_Controller
|
||||||
|
&& $endpoints['/wc/v4/products/categories'][3]['callback'][0] instanceof WC_Admin_REST_Product_categories_Controller
|
||||||
|
) {
|
||||||
|
$endpoints['/wc/v4/products/categories'][0] = $endpoints['/wc/v4/products/categories'][2];
|
||||||
|
$endpoints['/wc/v4/products/categories'][1] = $endpoints['/wc/v4/products/categories'][3];
|
||||||
|
}
|
||||||
|
|
||||||
// Override /wc/v4/products/reviews.
|
// Override /wc/v4/products/reviews.
|
||||||
if ( isset( $endpoints['/wc/v4/products/reviews'] )
|
if ( isset( $endpoints['/wc/v4/products/reviews'] )
|
||||||
&& isset( $endpoints['/wc/v4/products/reviews'][3] )
|
&& isset( $endpoints['/wc/v4/products/reviews'][3] )
|
||||||
|
|
|
@ -134,7 +134,9 @@ class FilterPicker extends Component {
|
||||||
renderButton( filter, onClose ) {
|
renderButton( filter, onClose ) {
|
||||||
if ( filter.component ) {
|
if ( filter.component ) {
|
||||||
const { type, labels } = filter.settings;
|
const { type, labels } = filter.settings;
|
||||||
const { selectedTag } = this.state;
|
const persistedFilter = this.getFilter();
|
||||||
|
const selectedTag = persistedFilter.value === filter.value ? this.state.selectedTag : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Search
|
<Search
|
||||||
className="woocommerce-filters-filter__search"
|
className="woocommerce-filters-filter__search"
|
||||||
|
|
Loading…
Reference in New Issue