* Add leaderboard section to dashboard

* Add rows per table user preference

* Pass in rowsPerTable to leaderboards to adjust total rows

* Add styling for rows select dropdown

* Set default for total rows if tableQuery is undefined

* Remove double localization on leaderboard labels

* Simplify toggle logic for hidden leaderboards

* Move updateCurrentUserData outside of setState callback
This commit is contained in:
Joshua T Flowers 2019-01-08 15:20:01 +08:00 committed by GitHub
parent 9fef5d4f5d
commit ef6d7ec4cb
10 changed files with 200 additions and 14 deletions

View File

@ -23,9 +23,18 @@ import './style.scss';
export class Leaderboard extends Component {
render() {
const { getHeadersContent, getRowsContent, isRequesting, isError, items, title } = this.props;
const {
getHeadersContent,
getRowsContent,
isRequesting,
isError,
items,
tableQuery,
title,
} = this.props;
const data = get( items, [ 'data' ], [] );
const rows = getRowsContent( data );
const totalRows = tableQuery ? tableQuery.per_page : 5;
if ( isError ) {
return <ReportError className="woocommerce-leaderboard" isError />;
@ -47,9 +56,9 @@ export class Leaderboard extends Component {
headers={ getHeadersContent() }
isLoading={ isRequesting }
rows={ rows }
rowsPerPage={ 5 }
rowsPerPage={ totalRows }
title={ title }
totalRows={ 5 }
totalRows={ totalRows }
/>
);
}

View File

@ -9,11 +9,11 @@ import { Component, Fragment } from '@wordpress/element';
* Internal dependencies
*/
import './style.scss';
import Header from 'header';
import StorePerformance from './store-performance';
import TopSellingProducts from './top-selling-products';
import DashboardCharts from './dashboard-charts';
import Header from 'header';
import Leaderboards from './leaderboards';
import { ReportFilters } from '@woocommerce/components';
import StorePerformance from './store-performance';
export default class Dashboard extends Component {
render() {
@ -23,11 +23,7 @@ export default class Dashboard extends Component {
<Header sections={ [ __( 'Dashboard', 'wc-admin' ) ] } />
<ReportFilters query={ query } path={ path } />
<StorePerformance />
<div className="woocommerce-dashboard__columns">
<div>
<TopSellingProducts query={ query } />
</div>
</div>
<Leaderboards query={ query } />
<DashboardCharts query={ query } path={ path } />
</Fragment>
);

View File

@ -0,0 +1,165 @@
/** @format */
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component, Fragment } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { isEqual, xor } from 'lodash';
import PropTypes from 'prop-types';
import { SelectControl, ToggleControl } from '@wordpress/components';
import { withDispatch } from '@wordpress/data';
/**
* WooCommerce dependencies
*/
import { EllipsisMenu, MenuItem, MenuTitle, SectionHeader } from '@woocommerce/components';
/**
* Internal dependencies
*/
import withSelect from 'wc-api/with-select';
import TopSellingProducts from './top-selling-products';
import './style.scss';
class Leaderboards extends Component {
constructor( props ) {
super( ...arguments );
this.state = {
hiddenLeaderboardKeys: props.userPrefLeaderboards || [],
rowsPerTable: props.userPrefLeaderboardRows || 5,
};
this.toggle = this.toggle.bind( this );
}
componentDidUpdate( {
userPrefLeaderboardRows: prevUserPrefLeaderboardRows,
userPrefLeaderboards: prevUserPrefLeaderboards,
} ) {
const { userPrefLeaderboardRows, userPrefLeaderboards } = this.props;
if ( userPrefLeaderboards && ! isEqual( userPrefLeaderboards, prevUserPrefLeaderboards ) ) {
/* eslint-disable react/no-did-update-set-state */
this.setState( {
hiddenLeaderboardKeys: userPrefLeaderboards,
} );
/* eslint-enable react/no-did-update-set-state */
}
if (
userPrefLeaderboardRows &&
parseInt( userPrefLeaderboardRows ) !== parseInt( prevUserPrefLeaderboardRows )
) {
/* eslint-disable react/no-did-update-set-state */
this.setState( {
rowsPerTable: parseInt( userPrefLeaderboardRows ),
} );
/* eslint-enable react/no-did-update-set-state */
}
}
toggle( key ) {
return () => {
const hiddenLeaderboardKeys = xor( this.state.hiddenLeaderboardKeys, [ key ] );
this.setState( { hiddenLeaderboardKeys } );
const userDataFields = {
[ 'dashboard_leaderboards' ]: hiddenLeaderboardKeys,
};
this.props.updateCurrentUserData( userDataFields );
};
}
setRowsPerTable = rows => {
this.setState( { rowsPerTable: parseInt( rows ) } );
const userDataFields = {
[ 'dashboard_leaderboard_rows' ]: parseInt( rows ),
};
this.props.updateCurrentUserData( userDataFields );
};
renderMenu() {
const { hiddenLeaderboardKeys, rowsPerTable } = this.state;
const allLeaderboards = [
{
key: 'top-products',
label: __( 'Top Products', 'wc-admin' ),
},
{
key: 'top-categories',
label: __( 'Top Categories', 'wc-admin' ),
},
{
key: 'top-coupons',
label: __( 'Top Coupons', 'wc-admin' ),
},
];
return (
<EllipsisMenu label={ __( 'Choose which leaderboards to display', 'wc-admin' ) }>
<Fragment>
<MenuTitle>{ __( 'Leaderboards', 'wc-admin' ) }</MenuTitle>
{ allLeaderboards.map( leaderboard => {
return (
<MenuItem onInvoke={ this.toggle( leaderboard.key ) } key={ leaderboard.key }>
<ToggleControl
label={ leaderboard.label }
checked={ ! hiddenLeaderboardKeys.includes( leaderboard.key ) }
onChange={ this.toggle( leaderboard.key ) }
/>
</MenuItem>
);
} ) }
<MenuTitle>{ __( 'Rows Per Table', 'wc-admin' ) }</MenuTitle>
<SelectControl
className="woocommerce-ellipsis-menu__item"
value={ rowsPerTable }
options={ Array.from( { length: 20 }, ( v, key ) => ( {
v: key + 1,
label: key + 1,
} ) ) }
onChange={ this.setRowsPerTable }
/>
</Fragment>
</EllipsisMenu>
);
}
render() {
const { hiddenLeaderboardKeys, rowsPerTable } = this.state;
return (
<Fragment>
<div className="woocommerce-dashboard__dashboard-leaderboards">
<SectionHeader title={ __( 'Leaderboards', 'wc-admin' ) } menu={ this.renderMenu() } />
<div className="woocommerce-dashboard__columns">
<div>
{ ! hiddenLeaderboardKeys.includes( 'top-products' ) && (
<TopSellingProducts query={ this.props.query } totalRows={ rowsPerTable } />
) }
</div>
</div>
</div>
</Fragment>
);
}
}
Leaderboards.propTypes = {
query: PropTypes.object.isRequired,
};
export default compose(
withSelect( select => {
const { getCurrentUserData } = select( 'wc-api' );
const userData = getCurrentUserData();
return {
userPrefLeaderboards: userData.dashboard_leaderboards,
userPrefLeaderboardRows: userData.dashboard_leaderboard_rows,
};
} ),
withDispatch( dispatch => {
const { updateCurrentUserData } = dispatch( 'wc-api' );
return {
updateCurrentUserData,
};
} )
)( Leaderboards );

View File

@ -0,0 +1,11 @@
/** @format */
.woocommerce-dashboard__dashboard-leaderboards {
.components-base-control__field {
width: 100%;
}
.components-select-control__input {
border: 1px solid $core-grey-light-700;
height: 34px;
}
}

View File

@ -16,7 +16,7 @@ import { getAdminLink } from '@woocommerce/navigation';
* Internal dependencies
*/
import { numberFormat } from 'lib/number';
import Leaderboard from 'dashboard/leaderboard';
import Leaderboard from 'analytics/components/leaderboard';
export class TopSellingProducts extends Component {
constructor( props ) {
@ -88,10 +88,11 @@ export class TopSellingProducts extends Component {
}
render() {
const { query, totalRows } = this.props;
const tableQuery = {
orderby: 'items_sold',
order: 'desc',
per_page: 5, //TODO replace with user configured leaderboard per page value.
per_page: totalRows,
extended_info: true,
};
@ -100,7 +101,7 @@ export class TopSellingProducts extends Component {
endpoint="products"
getHeadersContent={ this.getHeadersContent }
getRowsContent={ this.getRowsContent }
query={ this.props.query }
query={ query }
tableQuery={ tableQuery }
title={ __( 'Top Selling Products', 'wc-admin' ) }
/>

View File

@ -42,6 +42,8 @@ function updateCurrentUserData( resourceNames, data, fetch ) {
'variations_report_columns',
'dashboard_charts',
'dashboard_chart_type',
'dashboard_leaderboards',
'dashboard_leaderboard_rows',
];
if ( resourceNames.includes( resourceName ) ) {

View File

@ -401,6 +401,8 @@ function wc_admin_get_user_data_fields() {
'variations_report_columns',
'dashboard_charts',
'dashboard_chart_type',
'dashboard_leaderboards',
'dashboard_leaderboard_rows',
);
return apply_filters( 'wc_admin_get_user_data_fields', $user_data_fields );