From e067da06be8bd1d18e6cb0953520eab0522881b4 Mon Sep 17 00:00:00 2001 From: Joshua T Flowers Date: Tue, 8 Jan 2019 09:49:11 +0800 Subject: [PATCH] Add dashboard chart user preferences (https://github.com/woocommerce/woocommerce-admin/pull/1225) * Add user preferences for shown dashboard charts * Add user preferences for dashboard chart type * Check if user preferences are set before assigning to state * Move API update methods out of callbacks and use xor --- .../dashboard/dashboard-charts/config.js | 10 +-- .../dashboard/dashboard-charts/index.js | 87 ++++++++++++++----- .../client/wc-api/user/operations.js | 2 + plugins/woocommerce-admin/lib/admin.php | 2 + 4 files changed, 72 insertions(+), 29 deletions(-) diff --git a/plugins/woocommerce-admin/client/dashboard/dashboard-charts/config.js b/plugins/woocommerce-admin/client/dashboard/dashboard-charts/config.js index 073d5bd747d..74a30900c75 100644 --- a/plugins/woocommerce-admin/client/dashboard/dashboard-charts/config.js +++ b/plugins/woocommerce-admin/client/dashboard/dashboard-charts/config.js @@ -21,19 +21,11 @@ const allCharts = ordersCharts ); // Need to remove duplicate charts, by key, from the configs -const uniqCharts = allCharts.reduce( ( a, b ) => { +export const uniqCharts = allCharts.reduce( ( a, b ) => { if ( a.findIndex( d => d.key === b.key ) < 0 ) { a.push( b ); } return a; }, [] ); -// Default charts. -// TODO: Implement user-based toggling/persistence. -const defaultCharts = [ 'items_sold', 'gross_revenue' ]; - -export const showCharts = uniqCharts.map( d => ( { - ...d, - show: defaultCharts.indexOf( d.key ) >= 0, -} ) ); export const getChartFromKey = key => allCharts.filter( d => d.key === key ); diff --git a/plugins/woocommerce-admin/client/dashboard/dashboard-charts/index.js b/plugins/woocommerce-admin/client/dashboard/dashboard-charts/index.js index f02f385583c..d3573496014 100644 --- a/plugins/woocommerce-admin/client/dashboard/dashboard-charts/index.js +++ b/plugins/woocommerce-admin/client/dashboard/dashboard-charts/index.js @@ -4,10 +4,13 @@ */ import { __ } from '@wordpress/i18n'; import classNames from 'classnames'; -import Gridicon from 'gridicons'; -import { ToggleControl, IconButton, NavigableMenu } from '@wordpress/components'; import { Component, Fragment } from '@wordpress/element'; +import { compose } from '@wordpress/compose'; +import Gridicon from 'gridicons'; +import { isEqual, xor } from 'lodash'; import PropTypes from 'prop-types'; +import { ToggleControl, IconButton, NavigableMenu } from '@wordpress/components'; +import { withDispatch } from '@wordpress/data'; /** * WooCommerce dependencies @@ -18,47 +21,73 @@ import { EllipsisMenu, MenuItem, SectionHeader } from '@woocommerce/components'; * Internal dependencies */ import ChartBlock from './block'; -import { getChartFromKey, showCharts } from './config'; +import { getChartFromKey, uniqCharts } from './config'; +import withSelect from 'wc-api/with-select'; import './style.scss'; class DashboardCharts extends Component { - constructor() { + constructor( props ) { super( ...arguments ); this.state = { - chartType: 'line', // @TODO: Remove this and use from props containing persisted user preferences. - showCharts, + chartType: props.userPrefChartType || 'line', + hiddenChartKeys: props.userPrefCharts || [], + query: props.query, }; this.toggle = this.toggle.bind( this ); } + componentDidUpdate( { + userPrefCharts: prevUserPrefCharts, + userPrefChartType: prevUserPrefChartType, + } ) { + const { userPrefCharts, userPrefChartType } = this.props; + if ( userPrefCharts && ! isEqual( userPrefCharts, prevUserPrefCharts ) ) { + /* eslint-disable react/no-did-update-set-state */ + this.setState( { + hiddenChartKeys: userPrefCharts, + } ); + /* eslint-enable react/no-did-update-set-state */ + } + if ( userPrefChartType && userPrefChartType !== prevUserPrefChartType ) { + /* eslint-disable react/no-did-update-set-state */ + this.setState( { + chartType: userPrefChartType, + } ); + /* eslint-enable react/no-did-update-set-state */ + } + } + toggle( key ) { return () => { - this.setState( state => { - const foundIndex = state.showCharts.findIndex( x => x.key === key ); - state.showCharts[ foundIndex ].show = ! state.showCharts[ foundIndex ].show; - return state; - } ); + const hiddenChartKeys = xor( this.state.hiddenChartKeys, [ key ] ); + this.setState( { hiddenChartKeys } ); + const userDataFields = { + [ 'dashboard_charts' ]: hiddenChartKeys, + }; + this.props.updateCurrentUserData( userDataFields ); }; } handleTypeToggle( type ) { return () => { - this.setState( { - chartType: type, - } ); + this.setState( { chartType: type } ); + const userDataFields = { + [ 'dashboard_chart_type' ]: type, + }; + this.props.updateCurrentUserData( userDataFields ); }; } renderMenu() { return ( - { this.state.showCharts.map( chart => { + { uniqCharts.map( chart => { return ( @@ -70,7 +99,8 @@ class DashboardCharts extends Component { render() { const { path } = this.props; - const query = { ...this.props.query, type: this.state.chartType }; + const { chartType, hiddenChartKeys } = this.state; + const query = { ...this.props.query, type: chartType }; return (
@@ -105,8 +135,8 @@ class DashboardCharts extends Component {
- { this.state.showCharts.map( chart => { - return ! chart.show ? null : ( + { uniqCharts.map( chart => { + return hiddenChartKeys.includes( chart.key ) ? null : (
{ + const { getCurrentUserData } = select( 'wc-api' ); + const userData = getCurrentUserData(); + + return { + userPrefCharts: userData.dashboard_charts, + userPrefChartType: userData.dashboard_chart_type, + }; + } ), + withDispatch( dispatch => { + const { updateCurrentUserData } = dispatch( 'wc-api' ); + + return { + updateCurrentUserData, + }; + } ) +)( DashboardCharts ); diff --git a/plugins/woocommerce-admin/client/wc-api/user/operations.js b/plugins/woocommerce-admin/client/wc-api/user/operations.js index 1c12e9765c0..0a9dd40f99c 100644 --- a/plugins/woocommerce-admin/client/wc-api/user/operations.js +++ b/plugins/woocommerce-admin/client/wc-api/user/operations.js @@ -40,6 +40,8 @@ function updateCurrentUserData( resourceNames, data, fetch ) { 'revenue_report_columns', 'taxes_report_columns', 'variations_report_columns', + 'dashboard_charts', + 'dashboard_chart_type', ]; if ( resourceNames.includes( resourceName ) ) { diff --git a/plugins/woocommerce-admin/lib/admin.php b/plugins/woocommerce-admin/lib/admin.php index b44ac05158f..54defb7daad 100644 --- a/plugins/woocommerce-admin/lib/admin.php +++ b/plugins/woocommerce-admin/lib/admin.php @@ -399,6 +399,8 @@ function wc_admin_get_user_data_fields() { 'revenue_report_columns', 'taxes_report_columns', 'variations_report_columns', + 'dashboard_charts', + 'dashboard_chart_type', ); return apply_filters( 'wc_admin_get_user_data_fields', $user_data_fields );