Show compared keys in chart legends even if their values are 0 (https://github.com/woocommerce/woocommerce-admin/pull/1754)

* Show compared keys in chart legends

* Fix JS error if filters is missing

* Add docs
This commit is contained in:
Albert Juhé Lluveras 2019-03-06 21:12:28 +01:00 committed by GitHub
parent 1a395fd11f
commit a7e3cf78a0
5 changed files with 43 additions and 27 deletions

View File

@ -6,6 +6,7 @@ import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { format as formatDate } from '@wordpress/date';
import { get } from 'lodash';
import PropTypes from 'prop-types';
/**
@ -27,7 +28,7 @@ import { Chart } from '@woocommerce/components';
import { getReportChartData, getTooltipValueFormat } from 'wc-api/reports/utils';
import ReportError from 'analytics/components/report-error';
import withSelect from 'wc-api/with-select';
import { getChartMode } from './utils';
import { getChartMode, getSelectedFilter } from './utils';
/**
* Component that renders the chart in reports.
@ -92,6 +93,7 @@ export class ReportChart extends Component {
renderChart( mode, isRequesting, chartData ) {
const {
emptySearchResults,
filterParam,
interactiveLegend,
itemsLabel,
legendPosition,
@ -113,6 +115,7 @@ export class ReportChart extends Component {
data={ chartData }
dateParser={ '%Y-%m-%dT%H:%M:%S' }
emptyMessage={ emptyMessage }
filterParam={ filterParam }
interactiveLegend={ interactiveLegend }
interval={ currentInterval }
isRequesting={ isRequesting }
@ -238,25 +241,30 @@ export default compose(
withSelect( ( select, props ) => {
const { endpoint, filters, isRequesting, limitProperty, query } = props;
const limitBy = limitProperty || endpoint;
const chartMode = props.mode || getChartMode( filters, query ) || 'time-comparison';
const selectedFilter = getSelectedFilter( filters, query );
const filterParam = get( selectedFilter, [ 'settings', 'param' ] );
const chartMode = props.mode || getChartMode( selectedFilter, query ) || 'time-comparison';
const newProps = {
mode: chartMode,
filterParam,
};
if ( isRequesting ) {
return {
mode: chartMode,
};
return newProps;
}
if ( query.search && ! ( query[ limitBy ] && query[ limitBy ].length ) ) {
return {
...newProps,
emptySearchResults: true,
mode: chartMode,
};
}
if ( 'item-comparison' === chartMode ) {
const primaryData = getReportChartData( endpoint, 'primary', query, select, limitBy );
return {
mode: chartMode,
...newProps,
primaryData,
};
}
@ -264,7 +272,7 @@ export default compose(
const primaryData = getReportChartData( endpoint, 'primary', query, select, limitBy );
const secondaryData = getReportChartData( endpoint, 'secondary', query, select, limitBy );
return {
mode: chartMode,
...newProps,
primaryData,
secondaryData,
};

View File

@ -8,7 +8,7 @@ import { shallow } from 'enzyme';
* Internal dependencies
*/
import { ReportChart } from '../';
import { getChartMode } from '../utils';
import { getChartMode, getSelectedFilter } from '../utils';
jest.mock( '@woocommerce/components', () => ( {
...require.requireActual( '@woocommerce/components' ),
@ -63,7 +63,8 @@ describe( 'ReportChart', () => {
},
];
const query = { filter: 'lorem-ipsum', filter2: 'ipsum-lorem' };
const mode = getChartMode( filters, query );
const selectedFilter = getSelectedFilter( filters, query );
const mode = getChartMode( selectedFilter, query );
expect( mode ).toEqual( 'item-comparison' );
} );
} );

View File

@ -13,32 +13,30 @@ import { flattenFilters } from '@woocommerce/navigation';
export const DEFAULT_FILTER = 'all';
export function getSelectedFilter( filters, query, selectedFilterArgs = {} ) {
if ( filters.length === 0 ) {
if ( ! filters || filters.length === 0 ) {
return null;
}
const filterConfig = filters.pop();
const clonedFilters = filters.slice( 0 );
const filterConfig = clonedFilters.pop();
if ( filterConfig.showFilters( query, selectedFilterArgs ) ) {
const allFilters = flattenFilters( filterConfig.filters );
const value = query[ filterConfig.param ] || DEFAULT_FILTER;
const selectedFilter = find( allFilters, { value } );
return find( allFilters, { value } );
}
return getSelectedFilter( clonedFilters, query, selectedFilterArgs );
}
export function getChartMode( selectedFilter, query ) {
if ( selectedFilter && query ) {
const selectedFilterParam = get( selectedFilter, [ 'settings', 'param' ] );
if ( ! selectedFilterParam || Object.keys( query ).includes( selectedFilterParam ) ) {
return selectedFilter;
return get( selectedFilter, [ 'chartMode' ] );
}
}
return getSelectedFilter( filters, query, selectedFilterArgs );
}
export function getChartMode( filters, query, selectedFilterArgs ) {
if ( ! filters ) {
return;
}
const clonedFilters = filters.slice( 0 );
const selectedFilter = getSelectedFilter( clonedFilters, query, selectedFilterArgs );
return get( selectedFilter, [ 'chartMode' ] );
return null;
}

View File

@ -1,5 +1,6 @@
# (unreleased)
- Chart legend component now uses withInstanceId HOC so the ids used in several HTML elements are unique.
- Chart component: new prop `filterParam` used to detect selected items in the current query. If there are, they will be displayed in the chart even if their values are 0.
# 1.6.0
- Chart component: new props `emptyMessage` and `baseValue`. When an empty message is provided, it will be displayed on top of the chart if there are no values different than `baseValue`.

View File

@ -16,7 +16,7 @@ import { withViewportMatch } from '@wordpress/viewport';
/**
* WooCommerce dependencies
*/
import { updateQueryString } from '@woocommerce/navigation';
import { getIdsFromQuery, updateQueryString } from '@woocommerce/navigation';
/**
* Internal dependencies
@ -74,7 +74,9 @@ function getOrderedKeys( props, previousOrderedKeys = [] ) {
if ( 'item-comparison' === props.mode ) {
updatedKeys.sort( ( a, b ) => b.total - a.total );
if ( isEmpty( previousOrderedKeys ) ) {
return updatedKeys.filter( key => key.total > 0 ).map( ( key, index ) => {
const selectedIds = props.filterParam ? getIdsFromQuery( props.query[ props.filterParam ] ) : [];
const filteredKeys = updatedKeys.filter( key => key.total > 0 || selectedIds.includes( parseInt( key.key, 10 ) ) );
return filteredKeys.map( ( key, index ) => {
return {
...key,
visible: index < selectionLimit || key.visible,
@ -443,6 +445,12 @@ Chart.propTypes = {
* nothing will be displayed.
*/
emptyMessage: PropTypes.string,
/**
* Name of the param used to filter items. If specified, it will be used, in combination
* with query, to detect which elements are being used by the current filter and must be
* displayed even if their value is 0.
*/
filterParam: PropTypes.string,
/**
* Label describing the legend items.
*/