Move `ReportError` to `@woocommerce/components` as `AnalyticsError` (#50108)

Co-authored-by: Eason <eason.su.tw@gmail.com>
This commit is contained in:
Tomek Wytrębowicz 2024-08-21 20:12:13 +02:00 committed by GitHub
parent 536807ca43
commit d31aae633a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 170 additions and 27 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add AnalyticsError component.

View File

@ -0,0 +1,15 @@
# AnalyticsError
Standard error message with reload action used in Analytics pages.
## Usage
```jsx
<AnalyticsError />
```
### Props
Name | Type | Default | Description
--- | --- | --- | ---
`className` | String | `null` | Additional CSS classes

View File

@ -3,16 +3,21 @@
*/
import { __ } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import { EmptyContent } from '@woocommerce/components';
import { createElement } from '@wordpress/element';
/**
* Component to render when there is an error in a report component due to data
* Internal dependencies
*/
import EmptyContent from '../../empty-content';
/**
* Component to render when there is an error in an analytics component due to data
* not being loaded or being invalid.
*
* @param {Object} props React props.
* @param {string} [props.className] Additional class name to style the component.
*/
function ReportError( { className } ) {
function AnalyticsError( { className } ) {
const title = __(
'There was an error getting your stats. Please try again.',
'woocommerce'
@ -32,11 +37,11 @@ function ReportError( { className } ) {
);
}
ReportError.propTypes = {
AnalyticsError.propTypes = {
/**
* Additional class name to style the component.
*/
className: PropTypes.string,
};
export default ReportError;
export default AnalyticsError;

View File

@ -0,0 +1,19 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { Story } from '@storybook/react';
/**
* Internal dependencies
*/
import AnalyticsError from '../';
const Template: Story = ( args ) => <AnalyticsError { ...args } />;
export const Basic = Template.bind( {} );
export default {
title: 'WooCommerce Admin/components/analytics/AnalyticsError',
component: AnalyticsError,
};

View File

@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AnalyticsError should match snapshot 1`] = `
<div>
<div
class="woocommerce-empty-content"
>
<img
alt=""
class="woocommerce-empty-content__illustration"
src="data:image/svg+xml;utf8,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 400 400\\"%3E%3Cpath d=\\"M226.153073,88.3099993 L355.380187,301.446227 C363.970299,315.614028 359.448689,334.062961 345.280888,342.653073 C340.591108,345.496544 335.21158,347 329.727115,347 L71.2728854,347 C54.7043429,347 41.2728854,333.568542 41.2728854,317 C41.2728854,311.515534 42.7763415,306.136007 45.6198127,301.446227 L174.846927,88.3099993 C183.437039,74.1421985 201.885972,69.6205881 216.053773,78.2106999 C220.184157,80.7150022 223.64877,84.1796157 226.153073,88.3099993 Z M184.370159,153 L186.899684,255.024156 L213.459691,255.024156 L215.989216,153 L184.370159,153 Z M200.179688,307.722584 C209.770801,307.722584 217.359375,300.450201 217.359375,291.175278 C217.359375,281.900355 209.770801,274.627972 200.179688,274.627972 C190.588574,274.627972 183,281.900355 183,291.175278 C183,300.450201 190.588574,307.722584 200.179688,307.722584 Z\\" id=\\"Combined-Shape\\" stroke=\\"%23c0c0c0\\" fill=\\"%23c0c0c0\\" fill-rule=\\"nonzero\\"%3E%3C/path%3E%3C/svg%3E"
width="100"
/>
<h2
class="woocommerce-empty-content__title"
>
There was an error getting your stats. Please try again.
</h2>
<div
class="woocommerce-empty-content__actions"
>
<button
class="components-button woocommerce-empty-content__action is-primary"
type="button"
>
Reload
</button>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,62 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
/**
* Internal dependencies
*/
import AnalyticsError from '..';
describe( 'AnalyticsError', () => {
// Mock window.location.reload by using a global variable
const originalLocation = window.location;
beforeAll( () => {
delete window.location;
window.location = { reload: jest.fn() };
} );
afterAll( () => {
window.location = originalLocation;
} );
it( 'displays an error message', () => {
render( <AnalyticsError /> );
expect(
screen.getByText(
'There was an error getting your stats. Please try again.'
)
).toBeInTheDocument();
} );
it( 'shows reload button', () => {
render( <AnalyticsError /> );
expect(
screen.getByRole( 'button', { name: 'Reload' } )
).toBeInTheDocument();
} );
it( 'refreshes the page when Reload Page button is clicked', () => {
const reloadMock = jest.fn();
Object.defineProperty( window.location, 'reload', {
configurable: true,
value: reloadMock,
} );
render( <AnalyticsError /> );
userEvent.click( screen.getByText( 'Reload' ) );
expect( reloadMock ).toHaveBeenCalled();
} );
it( 'should match snapshot', () => {
const { container } = render( <AnalyticsError /> );
expect( container ).toMatchSnapshot();
} );
} );

View File

@ -0,0 +1 @@
export { default as AnalyticsError } from './error';

View File

@ -1,5 +1,6 @@
export { default as AbbreviatedCard } from './abbreviated-card';
export { default as AdvancedFilters } from './advanced-filters';
export * from './analytics';
export { default as AnimationSlider } from './animation-slider';
export { default as Chart } from './chart';
export { default as ChartPlaceholder } from './chart/placeholder';

View File

@ -1,4 +1,3 @@
export { default as ReportChart } from './report-chart';
export { default as ReportError } from './report-error';
export { default as ReportSummary } from './report-summary';
export { default as ReportTable } from './report-table';

View File

@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';
import { Card, CardBody, CardHeader } from '@wordpress/components';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { EmptyTable, TableCard } from '@woocommerce/components';
import { EmptyTable, AnalyticsError, TableCard } from '@woocommerce/components';
import { withSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
import { getPersistedQuery } from '@woocommerce/navigation';
@ -21,7 +21,6 @@ import { Text } from '@woocommerce/experimental';
/**
* Internal dependencies
*/
import ReportError from '../report-error';
import sanitizeHTML from '../../../lib/sanitize-html';
import './style.scss';
@ -88,7 +87,7 @@ export class Leaderboard extends Component {
const classes = 'woocommerce-leaderboard';
if ( isError ) {
return <ReportError className={ classes } />;
return <AnalyticsError className={ classes } />;
}
const rows = this.getFormattedRows();

View File

@ -8,7 +8,7 @@ import { format as formatDate } from '@wordpress/date';
import { withSelect } from '@wordpress/data';
import { get, isEqual } from 'lodash';
import PropTypes from 'prop-types';
import { Chart } from '@woocommerce/components';
import { Chart, AnalyticsError } from '@woocommerce/components';
import {
getReportChartData,
getTooltipValueFormat,
@ -27,7 +27,6 @@ import { CurrencyContext } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import ReportError from '../report-error';
import {
getChartMode,
getSelectedFilter,
@ -197,7 +196,7 @@ export class ReportChart extends Component {
const { isRequesting, primaryData } = this.props;
if ( primaryData.isError ) {
return <ReportError />;
return <AnalyticsError />;
}
const isChartRequesting = isRequesting || primaryData.isRequesting;
@ -214,7 +213,7 @@ export class ReportChart extends Component {
const { isRequesting, primaryData, secondaryData } = this.props;
if ( ! primaryData || primaryData.isError || secondaryData.isError ) {
return <ReportError />;
return <AnalyticsError />;
}
const isChartRequesting =

View File

@ -8,6 +8,7 @@ import { withSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
import { getNewPath } from '@woocommerce/navigation';
import {
AnalyticsError,
SummaryList,
SummaryListPlaceholder,
SummaryNumber,
@ -21,7 +22,6 @@ import { CurrencyContext } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import ReportError from '../report-error';
/**
* Component to render summary numbers in reports.
@ -64,7 +64,7 @@ export class ReportSummary extends Component {
const { isError, isRequesting } = summaryData;
if ( isError ) {
return <ReportError />;
return <AnalyticsError />;
}
if ( isRequesting ) {
@ -138,7 +138,7 @@ ReportSummary.propTypes = {
* The endpoint to use in API calls to populate the Summary Numbers.
* For example, if `taxes` is provided, data will be fetched from the report
* `taxes` endpoint (ie: `/wc-analytics/reports/taxes/stats`). If the provided endpoint
* doesn't exist, an error will be shown to the user with `ReportError`.
* doesn't exist, an error will be shown to the user with `AnalyticsError`.
*/
endpoint: PropTypes.string.isRequired,
/**

View File

@ -124,7 +124,7 @@ describe( 'ReportSummary', () => {
expect( delta ).toBeInTheDocument();
} );
test( 'should display ReportError when isError is true', () => {
test( 'should display AnalyticsError when isError is true', () => {
renderChart( 'number', null, null, true );
expect(

View File

@ -11,7 +11,12 @@ import { get, partial, uniq } from 'lodash';
import { __, sprintf } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import { STORE_KEY as CES_STORE_KEY } from '@woocommerce/customer-effort-score';
import { CompareButton, Search, TableCard } from '@woocommerce/components';
import {
CompareButton,
AnalyticsError,
Search,
TableCard,
} from '@woocommerce/components';
import {
getIdsFromQuery,
getSearchWords,
@ -38,7 +43,6 @@ import { recordEvent } from '@woocommerce/tracks';
* Internal dependencies
*/
import DownloadIcon from './download-icon';
import ReportError from '../report-error';
import { extendTableData } from './utils';
import './style.scss';
@ -89,7 +93,7 @@ const ReportTable = ( props ) => {
const isError = tableData.isError || primaryData.isError;
if ( isError ) {
return <ReportError />;
return <AnalyticsError />;
}
let userPrefColumns = [];
@ -489,7 +493,7 @@ ReportTable.propTypes = {
* For example, if `taxes` is provided, data will be fetched from the report
* `taxes` endpoint (ie: `/wc-analytics/reports/taxes` and `/wc/v4/reports/taxes/stats`).
* If the provided endpoint doesn't exist, an error will be shown to the user
* with `ReportError`.
* with `AnalyticsError`.
*/
endpoint: PropTypes.string,
/**

View File

@ -8,6 +8,7 @@ import PropTypes from 'prop-types';
import { find } from 'lodash';
import { getQuery, getSearchWords } from '@woocommerce/navigation';
import { searchItemsByString, ITEMS_STORE_NAME } from '@woocommerce/data';
import { AnalyticsError } from '@woocommerce/components';
import {
CurrencyContext,
getFilteredCurrencyInstance,
@ -18,7 +19,6 @@ import {
*/
import './style.scss';
import { NoMatch } from '~/layout/NoMatch';
import ReportError from '../components/report-error';
import getReports from './get-reports';
/**
@ -83,7 +83,7 @@ class Report extends Component {
const { isError } = this.props;
if ( isError ) {
return <ReportError />;
return <AnalyticsError />;
}
const reportParam = getReportParam( this.props );

View File

@ -6,6 +6,7 @@ import { Component, Fragment } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import PropTypes from 'prop-types';
import { ITEMS_STORE_NAME } from '@woocommerce/data';
import { AnalyticsError } from '@woocommerce/components';
import { withSelect } from '@wordpress/data';
/**
@ -15,7 +16,6 @@ import { advancedFilters, charts, filters } from './config';
import getSelectedChart from '../../../lib/get-selected-chart';
import ProductsReportTable from './table';
import ReportChart from '../../components/report-chart';
import ReportError from '../../components/report-error';
import ReportSummary from '../../components/report-summary';
import VariationsReportTable from '../variations/table';
import ReportFilters from '../../components/report-filters';
@ -57,7 +57,7 @@ class ProductsReport extends Component {
this.props;
if ( isError ) {
return <ReportError />;
return <AnalyticsError />;
}
const chartQuery = {

View File

@ -4,6 +4,7 @@
import { __ } from '@wordpress/i18n';
import { Fragment } from '@wordpress/element';
import PropTypes from 'prop-types';
import { AnalyticsError } from '@woocommerce/components';
/**
* Internal dependencies
@ -11,7 +12,6 @@ import PropTypes from 'prop-types';
import { advancedFilters, charts, filters } from './config';
import getSelectedChart from '../../../lib/get-selected-chart';
import ReportChart from '../../components/report-chart';
import ReportError from '../../components/report-error';
import ReportSummary from '../../components/report-summary';
import VariationsReportTable from './table';
import ReportFilters from '../../components/report-filters';
@ -35,7 +35,7 @@ const VariationsReport = ( props ) => {
const { path, query, isError, isRequesting } = props;
if ( isError ) {
return <ReportError />;
return <AnalyticsError />;
}
const chartQuery = {

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Move `ReportError` to `@woocommerce/components` as `AnalyticsError`