2018-11-26 14:01:20 +00:00
|
|
|
/** @format */
|
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2018-12-05 01:44:32 +00:00
|
|
|
import { applyFilters } from '@wordpress/hooks';
|
2018-11-26 14:01:20 +00:00
|
|
|
import { Component } from '@wordpress/element';
|
|
|
|
import { compose } from '@wordpress/compose';
|
2018-12-12 12:55:10 +00:00
|
|
|
import { first, get, orderBy } from 'lodash';
|
2018-11-26 14:01:20 +00:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* WooCommerce dependencies
|
|
|
|
*/
|
|
|
|
import { TableCard } from '@woocommerce/components';
|
|
|
|
import { onQueryChange } from '@woocommerce/navigation';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import ReportError from 'analytics/components/report-error';
|
|
|
|
import { getReportChartData, getReportTableData } from 'store/reports/utils';
|
2018-12-05 17:10:54 +00:00
|
|
|
import withSelect from 'wc-api/with-select';
|
2018-11-26 14:01:20 +00:00
|
|
|
|
2018-12-05 01:44:32 +00:00
|
|
|
const TABLE_FILTER = 'woocommerce_admin_report_table';
|
|
|
|
|
2018-11-26 14:01:20 +00:00
|
|
|
class ReportTable extends Component {
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
getHeadersContent,
|
|
|
|
getRowsContent,
|
|
|
|
getSummary,
|
|
|
|
itemIdField,
|
|
|
|
primaryData,
|
|
|
|
tableData,
|
|
|
|
// These two props are not used in the render function, but are destructured
|
|
|
|
// so they are not included in the `tableProps` variable.
|
|
|
|
endpoint,
|
|
|
|
tableQuery,
|
|
|
|
...tableProps
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
const { items, query } = tableData;
|
|
|
|
|
|
|
|
const isError = tableData.isError || primaryData.isError;
|
|
|
|
|
|
|
|
if ( isError ) {
|
|
|
|
return <ReportError isError />;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isRequesting = tableData.isRequesting || primaryData.isRequesting;
|
2018-11-29 14:03:04 +00:00
|
|
|
const orderedItems = orderBy( items.data, query.orderby, query.order );
|
2018-11-26 14:01:20 +00:00
|
|
|
const totals = get( primaryData, [ 'data', 'totals' ], null );
|
2018-12-04 19:29:58 +00:00
|
|
|
const totalCount = items.totalCount || 0;
|
2018-12-05 01:44:32 +00:00
|
|
|
const { headers, ids, rows, summary } = applyFilters( TABLE_FILTER, {
|
|
|
|
endpoint: endpoint,
|
|
|
|
headers: getHeadersContent(),
|
|
|
|
orderedItems: orderedItems,
|
|
|
|
ids: itemIdField ? orderedItems.map( item => item[ itemIdField ] ) : null,
|
|
|
|
rows: getRowsContent( orderedItems ),
|
|
|
|
totals: totals,
|
|
|
|
summary: getSummary ? getSummary( totals, totalCount ) : null,
|
|
|
|
} );
|
2018-11-26 14:01:20 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<TableCard
|
|
|
|
downloadable
|
|
|
|
headers={ headers }
|
|
|
|
ids={ ids }
|
|
|
|
isLoading={ isRequesting }
|
|
|
|
onQueryChange={ onQueryChange }
|
|
|
|
rows={ rows }
|
2018-12-04 00:00:13 +00:00
|
|
|
rowsPerPage={ parseInt( query.per_page ) }
|
2018-11-26 14:01:20 +00:00
|
|
|
summary={ summary }
|
2018-12-04 19:29:58 +00:00
|
|
|
totalRows={ totalCount }
|
2018-11-26 14:01:20 +00:00
|
|
|
{ ...tableProps }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReportTable.propTypes = {
|
|
|
|
/**
|
|
|
|
* The endpoint to use in API calls.
|
|
|
|
*/
|
2018-12-03 03:40:57 +00:00
|
|
|
endpoint: PropTypes.string,
|
2018-12-12 12:55:10 +00:00
|
|
|
/**
|
|
|
|
* Method names used to load more data for table items. If omitted, no call will
|
|
|
|
* be made and only the data returned by the reports endpoint will be used.
|
|
|
|
*/
|
|
|
|
extendItemsMethodNames: PropTypes.shape( {
|
|
|
|
isError: PropTypes.string,
|
|
|
|
isRequesting: PropTypes.string,
|
|
|
|
load: PropTypes.string,
|
|
|
|
} ),
|
2018-11-26 14:01:20 +00:00
|
|
|
/**
|
|
|
|
* A function that returns the headers object to build the table.
|
|
|
|
*/
|
|
|
|
getHeadersContent: PropTypes.func.isRequired,
|
|
|
|
/**
|
|
|
|
* A function that returns the rows array to build the table.
|
|
|
|
*/
|
|
|
|
getRowsContent: PropTypes.func.isRequired,
|
|
|
|
/**
|
|
|
|
* A function that returns the summary object to build the table.
|
|
|
|
*/
|
|
|
|
getSummary: PropTypes.func,
|
|
|
|
/**
|
|
|
|
* The name of the property in the item object which contains the id.
|
|
|
|
*/
|
2018-12-03 03:40:57 +00:00
|
|
|
itemIdField: PropTypes.string,
|
2018-11-26 14:01:20 +00:00
|
|
|
/**
|
|
|
|
* Primary data of that report.
|
|
|
|
*/
|
|
|
|
primaryData: PropTypes.object.isRequired,
|
|
|
|
/**
|
|
|
|
* Table data of that report.
|
|
|
|
*/
|
|
|
|
tableData: PropTypes.object.isRequired,
|
|
|
|
/**
|
|
|
|
* Properties to be added to the query sent to the report table endpoint.
|
|
|
|
*/
|
|
|
|
tableQuery: PropTypes.object,
|
|
|
|
/**
|
|
|
|
* String to display as the title of the table.
|
|
|
|
*/
|
|
|
|
title: PropTypes.string.isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
ReportTable.defaultProps = {
|
2018-12-10 15:51:11 +00:00
|
|
|
tableData: {},
|
2018-11-26 14:01:20 +00:00
|
|
|
tableQuery: {},
|
|
|
|
};
|
|
|
|
|
2018-12-12 12:55:10 +00:00
|
|
|
const extendTableData = ( select, props, queriedTableData ) => {
|
|
|
|
const { extendItemsMethodNames, itemIdField, query } = props;
|
|
|
|
const itemsData = queriedTableData.items.data;
|
|
|
|
if (
|
|
|
|
! Array.isArray( itemsData ) ||
|
|
|
|
! itemsData.length ||
|
|
|
|
! extendItemsMethodNames ||
|
|
|
|
! itemIdField
|
|
|
|
) {
|
|
|
|
return queriedTableData;
|
|
|
|
}
|
|
|
|
|
|
|
|
const {
|
|
|
|
[ extendItemsMethodNames.isError ]: isErrorMethod,
|
|
|
|
[ extendItemsMethodNames.isRequesting ]: isRequestingMethod,
|
|
|
|
[ extendItemsMethodNames.load ]: loadMethod,
|
|
|
|
} = select( 'wc-api' );
|
|
|
|
const extendQuery = {
|
|
|
|
include: itemsData.map( item => item[ itemIdField ] ).join( ',' ),
|
|
|
|
per_page: itemsData.length,
|
|
|
|
...query,
|
|
|
|
};
|
|
|
|
const extendedItems = loadMethod( extendQuery );
|
|
|
|
const isExtendedItemsRequesting = isRequestingMethod ? isRequestingMethod( extendQuery ) : false;
|
|
|
|
const isExtendedItemsError = isErrorMethod ? isErrorMethod( extendQuery ) : false;
|
|
|
|
|
|
|
|
const extendedItemsData = itemsData.map( item => {
|
|
|
|
const extendedItemData = first(
|
|
|
|
extendedItems.filter( extendedItem => item.id === extendedItem.id )
|
|
|
|
);
|
|
|
|
return {
|
|
|
|
...item,
|
|
|
|
...extendedItemData,
|
|
|
|
};
|
|
|
|
} );
|
|
|
|
|
|
|
|
const isRequesting = queriedTableData.isRequesting || isExtendedItemsRequesting;
|
|
|
|
const isError = queriedTableData.isError || isExtendedItemsError;
|
|
|
|
|
|
|
|
return {
|
|
|
|
...queriedTableData,
|
|
|
|
isRequesting,
|
|
|
|
isError,
|
|
|
|
items: {
|
|
|
|
...queriedTableData.items,
|
|
|
|
data: extendedItemsData,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-11-26 14:01:20 +00:00
|
|
|
export default compose(
|
|
|
|
withSelect( ( select, props ) => {
|
2018-12-03 03:40:57 +00:00
|
|
|
const { endpoint, getSummary, query, tableData, tableQuery } = props;
|
2018-11-26 02:58:19 +00:00
|
|
|
const chartEndpoint = 'variations' === endpoint ? 'products' : endpoint;
|
2018-12-03 03:40:57 +00:00
|
|
|
const primaryData = getSummary
|
|
|
|
? getReportChartData( chartEndpoint, 'primary', query, select )
|
|
|
|
: {};
|
|
|
|
const queriedTableData = tableData || getReportTableData( endpoint, query, select, tableQuery );
|
2018-12-12 12:55:10 +00:00
|
|
|
const extendedTableData = extendTableData( select, props, queriedTableData );
|
2018-11-26 14:01:20 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
primaryData,
|
2018-12-12 12:55:10 +00:00
|
|
|
tableData: extendedTableData,
|
2018-11-26 14:01:20 +00:00
|
|
|
};
|
|
|
|
} )
|
|
|
|
)( ReportTable );
|