import { ReportFilters, TableCard } from '@woocommerce/components'; import { isoDateFormat } from '@woocommerce/date'; import { Button, __experimentalSpacer as Spacer, Notice, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { useState } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; import { downloadCSVFile, generateCSVDataFromTable, generateCSVFileName, type Rows, } from '@woocommerce/csv-export'; import { LabelReportProps } from './types'; import { DownloadIcon } from 'components/icons'; import { AnalyticsStore } from 'data/analytics'; import { camelCase } from 'lodash'; import { camelCaseKeys, createReportQueryPath, getAnalyticsConfig, } from 'utils'; import { ReportResponse } from 'types'; import { mapRowToTableData } from './utils'; import { tableHeaders } from './contants'; export const Labels = ( { query, path, currency }: LabelReportProps ) => { const [ pagination, setPagination ] = useState( { perPage: 25, // Minimum value for PER_PAGE_OPTIONS in Pagination component paged: 1, } ); const [ preparingExport, setPreparingExport ] = useState( false ); const [ errors, setErrors ] = useState< string[] >( [] ); const tableData: { rows: Rows; summary: { key: string; label: string; value: number | string | JSX.Element; }[]; } = { rows: [], summary: [], }; const data = useSelect( ( select ) => { setErrors( [] ); return select( AnalyticsStore ).getLabelsReport( { ...query, perPage: pagination.perPage.toString(), offset: `${ ( pagination.paged - 1 ) * pagination.perPage }`, } ); }, // eslint-disable-next-line react-hooks/exhaustive-deps -- query, path, pagination are dependencies [ query, path, pagination ] ); if ( data?.rows && data.meta ) { tableData.rows = data.rows.map( mapRowToTableData( currency ) ); tableData.summary = [ { key: 'total_count', label: __( 'Labels purchased in this period', 'woocommerce-shipping' ), value: data.meta.totalCount, }, { key: 'total_cost', label: __( 'Total label cost in this period', 'woocommerce-shipping' ), value: currency?.render( data.meta.totalCost ), }, { key: 'total_refunds', label: __( 'Refund in this period', 'woocommerce-shipping' ), value: data.meta.totalRefunds, }, ]; } const isLoading = data === undefined; const onQueryChange = ( key: 'page_size' | 'paged' | 'sort' | string ) => ( value: string ) => { if ( key === 'page_size' || key === 'paged' ) { setPagination( { ...pagination, [ camelCase( key ) ]: parseInt( value, 10 ), } ); } }; const onClickDownload = async () => { let { rows } = tableData; setErrors( [] ); if ( data?.meta.totalCount && data.meta.totalCount > pagination.perPage ) { setPreparingExport( true ); try { const result = await apiFetch< ReportResponse >( { path: createReportQueryPath( { ...query, perPage: '-1', offset: '0', } ), method: 'GET', } ); rows = result.rows .map( camelCaseKeys ) .map( mapRowToTableData( currency ) ); } catch { setErrors( [ ...errors, __( 'Failed to fetch data for export.', 'woocommerce-shipping' ), ] ); return; } finally { setPreparingExport( false ); } } try { const params = { ...query }; // shallow copy downloadCSVFile( generateCSVFileName( __( 'Shipping Labels', 'woocommerce-shipping' ), params as Record< string, string > ), generateCSVDataFromTable( tableHeaders, rows ) ); } catch { setErrors( [ ...errors, __( 'Failed to request download of CSV file.', 'woocommerce-shipping' ), ] ); } }; return ( <> { sprintf( // translators: %d is the cache expiration in minutes __( 'To improve performance, the data shown here may be up to %d minutes old.', 'woocommerce-shipping' ), getAnalyticsConfig().cacheExpirationInSeconds / 60 ) } { errors.length > 0 && ( <> { errors.map( ( error, index ) => (

{ error }

) ) }
) } { __( 'Download', 'woocommerce-shipping' ) } , ] } onQueryChange={ onQueryChange } /> ); };