/** * External dependencies */ import { __, _n, sprintf } from '@wordpress/i18n'; import { useMemo, useContext } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { decodeEntities } from '@wordpress/html-entities'; import PropTypes from 'prop-types'; import interpolateComponents from '@automattic/interpolate-components'; import { EmptyContent, Flag, H, Link, OrderStatus, Section, } from '@woocommerce/components'; import { getNewPath } from '@woocommerce/navigation'; import { getAdminLink } from '@woocommerce/settings'; import { ORDERS_STORE_NAME, ITEMS_STORE_NAME } from '@woocommerce/data'; import { recordEvent } from '@woocommerce/tracks'; import { CurrencyContext, CurrencyFactory } from '@woocommerce/currency'; /** * Internal dependencies */ import { ActivityCard, ActivityCardPlaceholder, } from '~/activity-panel/activity-card'; import { getAdminSetting } from '~/utils/admin-settings'; import './style.scss'; function recordOrderEvent( eventName ) { recordEvent( `activity_panel_orders_${ eventName }`, {} ); } const renderEmptyCard = () => { return ( <> 🎉 { __( 'You’ve fulfilled all your orders', 'woocommerce' ) } recordOrderEvent( 'orders_manage' ) } className="woocommerce-layout__activity-panel-outbound-link woocommerce-layout__activity-panel-empty" type="wp-admin" > { __( 'Manage all orders', 'woocommerce' ) } ); }; function renderOrders( orders, customers, getFormattedOrderTotal ) { if ( orders.length === 0 ) { return renderEmptyCard(); } const getCustomerString = ( customer ) => { const { name } = customer || {}; if ( ! name ) { return ''; } return `{{customerLink}}${ name }{{/customerLink}}`; }; const orderCardTitle = ( order ) => { const { id: orderId, number: orderNumber, customer_id: customerId, } = order; const customer = customers.find( ( c ) => c.user_id === customerId ) || {}; let customerUrl = null; if ( customer && customer.id ) { customerUrl = window.wcAdminFeatures.analytics ? getNewPath( {}, '/analytics/customers', { filter: 'single_customer', customers: customer.id, } ) : getAdminLink( 'user-edit.php?user_id=' + customer.id ); } return ( <> { interpolateComponents( { mixedString: sprintf( /* translators: 1: order number, 2: customer name */ __( '{{orderLink}}Order #%(orderNumber)s{{/orderLink}} %(customerString)s', 'woocommerce' ), { orderNumber, customerString: getCustomerString( customer ), } ), components: { orderLink: ( recordOrderEvent( 'order_number' ) } type="wp-admin" /> ), destinationFlag: customer && customer.country ? ( ) : null, customerLink: customerUrl ? ( recordOrderEvent( 'customer_name' ) } type="wc-admin" /> ) : ( ), }, } ) } ); }; const cards = []; orders.forEach( ( order ) => { const { date_created_gmt: dateCreatedGmt, line_items: lineItems, id: orderId, } = order; const productsCount = lineItems ? lineItems.length : 0; cards.push( { recordOrderEvent( 'orders_begin_fulfillment' ); if ( ! target.href ) { window.location.href = getAdminLink( `post.php?action=edit&post=${ orderId }` ); } } } subtitle={
{ sprintf( /* translators: %d: number of products */ _n( '%d product', '%d products', productsCount, 'woocommerce' ), productsCount ) } { getFormattedOrderTotal( order.total, order.currency ) }
} >
); } ); return ( <> { cards } recordOrderEvent( 'orders_manage' ) } type="wp-admin" > { __( 'Manage all orders', 'woocommerce' ) } ); } function OrdersPanel( { unreadOrdersCount, orderStatuses } ) { const actionableOrdersQuery = useMemo( () => ( { page: 1, per_page: 5, status: orderStatuses, _fields: [ 'id', 'number', 'currency', 'status', 'total', 'customer', 'line_items', 'customer_id', 'date_created_gmt', ], } ), [ orderStatuses ] ); const currencyContext = useContext( CurrencyContext ); const storeCurrency = currencyContext.getCurrencyConfig(); const { currencySymbols = {} } = getAdminSetting( 'onboarding', {} ); const getFormattedOrderTotal = ( total, orderCurrencyCode ) => { if ( ! orderCurrencyCode ) { return null; } // If the order currency is the same as the store currency, we show the formatted amount. if ( storeCurrency && storeCurrency.code === orderCurrencyCode ) { return currencyContext.formatAmount( total ); } const symbol = currencySymbols[ orderCurrencyCode ]; if ( ! symbol ) { // This should never happen, but if it does, we'll just show the currency code. return `${ orderCurrencyCode }${ total }`; } // If the order currency is different from the store currency, we show the currency code and amount in the order currency. return CurrencyFactory( { ...storeCurrency, symbol: decodeEntities( symbol ), code: orderCurrencyCode, } ).formatAmount( total ); }; const { orders = [], isRequesting, isError, customerItems, } = useSelect( ( select ) => { const { getOrders, hasFinishedResolution, getOrdersError } = select( ORDERS_STORE_NAME ); // eslint-disable-next-line @wordpress/no-unused-vars-before-return const { getItems } = select( ITEMS_STORE_NAME ); if ( ! orderStatuses.length && unreadOrdersCount === 0 ) { return { isRequesting: false }; } /* eslint-disable @wordpress/no-unused-vars-before-return */ const actionableOrders = getOrders( actionableOrdersQuery, null ); const isRequestingActionable = hasFinishedResolution( 'getOrders', [ actionableOrdersQuery, ] ); if ( isRequestingActionable || unreadOrdersCount === null || actionableOrders === null ) { return { isError: Boolean( getOrdersError( actionableOrdersQuery ) ), isRequesting: true, orderStatuses, }; } const customers = getItems( 'customers', { users: actionableOrders .map( ( order ) => order.customer_id ) .filter( ( id ) => id !== 0 ), _fields: [ 'id', 'name', 'country', 'user_id' ], } ); return { orders: actionableOrders, isError: Boolean( getOrdersError( actionableOrders ) ), isRequesting: isRequestingActionable, orderStatuses, customerItems: customers, }; } ); if ( isError ) { if ( ! orderStatuses.length && window.wcAdminFeatures.analytics ) { return ( ); } const title = __( 'There was an error getting your orders. Please try again.', 'woocommerce' ); const actionLabel = __( 'Reload', 'woocommerce' ); const actionCallback = () => { // @todo Add tracking for how often an error is displayed, and the reload action is clicked. window.location.reload(); }; return ( <> ); } const customerList = customerItems ? Array.from( customerItems, ( [ , value ] ) => value ) : []; return ( <>
{ isRequesting ? ( ) : ( renderOrders( orders, customerList, getFormattedOrderTotal ) ) }
); } OrdersPanel.propTypes = { isError: PropTypes.bool, isRequesting: PropTypes.bool, unreadOrdersCount: PropTypes.number, orders: PropTypes.array.isRequired, orderStatuses: PropTypes.array, }; OrdersPanel.defaultProps = { orders: [], isError: false, isRequesting: false, }; export default OrdersPanel;