2018-12-22 00:24:26 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { __ } from '@wordpress/i18n';
|
|
|
|
import classNames from 'classnames';
|
2020-06-10 16:46:46 +00:00
|
|
|
import { Fragment, useState } from '@wordpress/element';
|
2019-01-08 01:49:11 +00:00
|
|
|
import Gridicon from 'gridicons';
|
2018-12-22 00:24:26 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2020-05-29 02:32:37 +00:00
|
|
|
import { Button, NavigableMenu, SelectControl } from '@wordpress/components';
|
2018-12-22 00:24:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* WooCommerce dependencies
|
|
|
|
*/
|
2020-02-14 02:23:21 +00:00
|
|
|
import {
|
|
|
|
EllipsisMenu,
|
|
|
|
MenuItem,
|
|
|
|
MenuTitle,
|
|
|
|
SectionHeader,
|
|
|
|
} from '@woocommerce/components';
|
2020-07-20 22:17:28 +00:00
|
|
|
import { useUserPreferences } from '@woocommerce/data';
|
2019-11-26 19:39:40 +00:00
|
|
|
import { getAllowedIntervalsForQuery } from 'lib/date';
|
2018-12-22 00:24:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import ChartBlock from './block';
|
2019-06-15 12:12:19 +00:00
|
|
|
import { uniqCharts } from './config';
|
2019-07-01 10:16:12 +00:00
|
|
|
import { recordEvent } from 'lib/tracks';
|
2018-12-22 00:24:26 +00:00
|
|
|
import './style.scss';
|
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
const renderChartToggles = ( { hiddenBlocks, onToggleHiddenBlock } ) => {
|
|
|
|
return uniqCharts.map( ( chart ) => {
|
|
|
|
const key = chart.endpoint + '_' + chart.key;
|
|
|
|
const checked = ! hiddenBlocks.includes( key );
|
2018-12-22 00:24:26 +00:00
|
|
|
return (
|
2020-06-10 16:46:46 +00:00
|
|
|
<MenuItem
|
|
|
|
checked={ checked }
|
|
|
|
isCheckbox
|
|
|
|
isClickable
|
|
|
|
key={ chart.endpoint + '_' + chart.key }
|
|
|
|
onInvoke={ () => {
|
|
|
|
onToggleHiddenBlock( key )();
|
2020-07-20 22:17:28 +00:00
|
|
|
recordEvent( 'dash_charts_chart_toggle', {
|
|
|
|
status: checked ? 'off' : 'on',
|
|
|
|
key,
|
|
|
|
} );
|
2020-06-10 16:46:46 +00:00
|
|
|
} }
|
|
|
|
>
|
|
|
|
{ chart.label }
|
|
|
|
</MenuItem>
|
2018-12-22 00:24:26 +00:00
|
|
|
);
|
2020-06-10 16:46:46 +00:00
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderIntervalSelector = ( { chartInterval, setInterval, query } ) => {
|
|
|
|
const allowedIntervals = getAllowedIntervalsForQuery( query );
|
|
|
|
if ( ! allowedIntervals || allowedIntervals.length < 1 ) {
|
|
|
|
return null;
|
2018-12-22 00:24:26 +00:00
|
|
|
}
|
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
const intervalLabels = {
|
|
|
|
hour: __( 'By hour', 'woocommerce-admin' ),
|
|
|
|
day: __( 'By day', 'woocommerce-admin' ),
|
|
|
|
week: __( 'By week', 'woocommerce-admin' ),
|
|
|
|
month: __( 'By month', 'woocommerce-admin' ),
|
|
|
|
quarter: __( 'By quarter', 'woocommerce-admin' ),
|
|
|
|
year: __( 'By year', 'woocommerce-admin' ),
|
|
|
|
};
|
2019-01-09 00:12:39 +00:00
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
return (
|
|
|
|
<SelectControl
|
|
|
|
className="woocommerce-chart__interval-select"
|
|
|
|
value={ chartInterval }
|
|
|
|
options={ allowedIntervals.map( ( allowedInterval ) => ( {
|
|
|
|
value: allowedInterval,
|
|
|
|
label: intervalLabels[ allowedInterval ],
|
|
|
|
} ) ) }
|
|
|
|
onChange={ setInterval }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
2019-01-09 00:12:39 +00:00
|
|
|
|
2020-07-20 22:17:28 +00:00
|
|
|
const renderChartBlocks = ( { hiddenBlocks, path, query, filters } ) => {
|
2020-06-10 16:46:46 +00:00
|
|
|
// Reduce the API response to only the necessary stat fields
|
|
|
|
// by supplying all charts common to each endpoint.
|
|
|
|
const chartsByEndpoint = uniqCharts.reduce( ( byEndpoint, chart ) => {
|
|
|
|
if ( typeof byEndpoint[ chart.endpoint ] === 'undefined' ) {
|
|
|
|
byEndpoint[ chart.endpoint ] = [];
|
|
|
|
}
|
|
|
|
byEndpoint[ chart.endpoint ].push( chart );
|
|
|
|
|
|
|
|
return byEndpoint;
|
|
|
|
}, {} );
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="woocommerce-dashboard__columns">
|
|
|
|
{ uniqCharts.map( ( chart ) => {
|
|
|
|
return hiddenBlocks.includes(
|
|
|
|
chart.endpoint + '_' + chart.key
|
|
|
|
) ? null : (
|
|
|
|
<ChartBlock
|
|
|
|
charts={ chartsByEndpoint[ chart.endpoint ] }
|
|
|
|
endpoint={ chart.endpoint }
|
|
|
|
key={ chart.endpoint + '_' + chart.key }
|
|
|
|
path={ path }
|
|
|
|
query={ query }
|
|
|
|
selectedChart={ chart }
|
2020-07-20 22:17:28 +00:00
|
|
|
filters={ filters }
|
2020-06-10 16:46:46 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
} ) }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
2019-01-09 00:12:39 +00:00
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
const DashboardCharts = ( props ) => {
|
|
|
|
const {
|
|
|
|
controls: Controls,
|
|
|
|
hiddenBlocks,
|
|
|
|
isFirst,
|
|
|
|
isLast,
|
|
|
|
onMove,
|
|
|
|
onRemove,
|
|
|
|
onTitleBlur,
|
|
|
|
onTitleChange,
|
|
|
|
onToggleHiddenBlock,
|
|
|
|
path,
|
|
|
|
title,
|
|
|
|
titleInput,
|
2020-07-20 22:17:28 +00:00
|
|
|
filters,
|
2020-06-10 16:46:46 +00:00
|
|
|
} = props;
|
|
|
|
const { updateUserPreferences, ...userPrefs } = useUserPreferences();
|
2020-07-20 22:17:28 +00:00
|
|
|
const [ chartType, setChartType ] = useState(
|
|
|
|
userPrefs.dashboard_chart_type || 'line'
|
|
|
|
);
|
|
|
|
const [ chartInterval, setChartInterval ] = useState(
|
|
|
|
userPrefs.dashboard_chart_interval || 'day'
|
|
|
|
);
|
2020-06-10 16:46:46 +00:00
|
|
|
const query = { ...props.query, chartType, interval: chartInterval };
|
|
|
|
|
|
|
|
const handleTypeToggle = ( type ) => {
|
|
|
|
return () => {
|
|
|
|
setChartType( type );
|
2019-01-09 00:12:39 +00:00
|
|
|
const userDataFields = {
|
2020-06-10 16:46:46 +00:00
|
|
|
dashboard_chart_type: type,
|
2019-01-09 00:12:39 +00:00
|
|
|
};
|
2020-06-10 16:46:46 +00:00
|
|
|
updateUserPreferences( userDataFields );
|
|
|
|
recordEvent( 'dash_charts_type_toggle', { chart_type: type } );
|
|
|
|
};
|
2019-01-09 00:12:39 +00:00
|
|
|
};
|
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
const renderMenu = () => (
|
|
|
|
<EllipsisMenu
|
|
|
|
label={ __(
|
|
|
|
'Choose which charts to display',
|
|
|
|
'woocommerce-admin'
|
|
|
|
) }
|
|
|
|
renderContent={ ( { onToggle } ) => (
|
|
|
|
<Fragment>
|
|
|
|
<MenuTitle>
|
|
|
|
{ __( 'Charts', 'woocommerce-admin' ) }
|
|
|
|
</MenuTitle>
|
2020-07-20 22:17:28 +00:00
|
|
|
{ renderChartToggles( {
|
|
|
|
hiddenBlocks,
|
|
|
|
onToggleHiddenBlock,
|
|
|
|
} ) }
|
2020-06-10 16:46:46 +00:00
|
|
|
{ window.wcAdminFeatures[
|
|
|
|
'analytics-dashboard/customizable'
|
|
|
|
] && (
|
|
|
|
<Controls
|
|
|
|
onToggle={ onToggle }
|
|
|
|
onMove={ onMove }
|
|
|
|
onRemove={ onRemove }
|
|
|
|
isFirst={ isFirst }
|
|
|
|
isLast={ isLast }
|
|
|
|
onTitleBlur={ onTitleBlur }
|
|
|
|
onTitleChange={ onTitleChange }
|
|
|
|
titleInput={ titleInput }
|
2020-03-31 15:08:40 +00:00
|
|
|
/>
|
2020-06-10 16:46:46 +00:00
|
|
|
) }
|
|
|
|
</Fragment>
|
|
|
|
) }
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
const setInterval = ( interval ) => {
|
|
|
|
setChartInterval( interval );
|
|
|
|
const userDataFields = {
|
|
|
|
dashboard_chart_interval: interval,
|
|
|
|
};
|
|
|
|
updateUserPreferences( userDataFields );
|
|
|
|
recordEvent( 'dash_charts_interval', { interval } );
|
|
|
|
};
|
2020-03-31 15:08:40 +00:00
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
return (
|
|
|
|
<div className="woocommerce-dashboard__dashboard-charts">
|
|
|
|
<SectionHeader
|
|
|
|
title={ title || __( 'Charts', 'woocommerce-admin' ) }
|
|
|
|
menu={ renderMenu() }
|
|
|
|
className={ 'has-interval-select' }
|
|
|
|
>
|
2020-07-20 22:17:28 +00:00
|
|
|
{ renderIntervalSelector( {
|
|
|
|
chartInterval,
|
|
|
|
setInterval,
|
|
|
|
query,
|
|
|
|
} ) }
|
2020-06-10 16:46:46 +00:00
|
|
|
<NavigableMenu
|
|
|
|
className="woocommerce-chart__types"
|
|
|
|
orientation="horizontal"
|
|
|
|
role="menubar"
|
|
|
|
>
|
|
|
|
<Button
|
|
|
|
className={ classNames(
|
|
|
|
'woocommerce-chart__type-button',
|
|
|
|
{
|
|
|
|
'woocommerce-chart__type-button-selected':
|
|
|
|
! query.chartType ||
|
|
|
|
query.chartType === 'line',
|
|
|
|
}
|
|
|
|
) }
|
2020-07-20 22:17:28 +00:00
|
|
|
title={ __( 'Line chart', 'woocommerce-admin' ) }
|
2020-06-10 16:46:46 +00:00
|
|
|
aria-checked={ query.chartType === 'line' }
|
|
|
|
role="menuitemradio"
|
|
|
|
tabIndex={ query.chartType === 'line' ? 0 : -1 }
|
|
|
|
onClick={ handleTypeToggle( 'line' ) }
|
2019-01-09 00:12:39 +00:00
|
|
|
>
|
2020-06-10 16:46:46 +00:00
|
|
|
<Gridicon icon="line-graph" />
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
className={ classNames(
|
|
|
|
'woocommerce-chart__type-button',
|
|
|
|
{
|
|
|
|
'woocommerce-chart__type-button-selected':
|
|
|
|
query.chartType === 'bar',
|
|
|
|
}
|
|
|
|
) }
|
|
|
|
title={ __( 'Bar chart', 'woocommerce-admin' ) }
|
|
|
|
aria-checked={ query.chartType === 'bar' }
|
|
|
|
role="menuitemradio"
|
|
|
|
tabIndex={ query.chartType === 'bar' ? 0 : -1 }
|
|
|
|
onClick={ handleTypeToggle( 'bar' ) }
|
|
|
|
>
|
|
|
|
<Gridicon icon="stats-alt" />
|
|
|
|
</Button>
|
|
|
|
</NavigableMenu>
|
|
|
|
</SectionHeader>
|
2020-07-20 22:17:28 +00:00
|
|
|
{ renderChartBlocks( { hiddenBlocks, path, query, filters } ) }
|
2020-06-10 16:46:46 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
2018-12-22 00:24:26 +00:00
|
|
|
|
|
|
|
DashboardCharts.propTypes = {
|
|
|
|
path: PropTypes.string.isRequired,
|
|
|
|
query: PropTypes.object.isRequired,
|
|
|
|
};
|
|
|
|
|
2020-06-10 16:46:46 +00:00
|
|
|
export default DashboardCharts;
|