From 427a229591c765de7f7be6ba45cbe079003a906e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 6 Mar 2020 13:27:54 +0100 Subject: [PATCH] Split Full Cart sidebar totals into several components (https://github.com/woocommerce/woocommerce-blocks/pull/1885) --- .../assets/js/base/components/totals/index.js | 6 + .../components/totals/subtotals-item/index.js | 39 ++++ .../totals/totals-discount-item/index.js | 97 +++++++++ .../totals/totals-fees-item/index.js | 50 +++++ .../totals/totals-footer-item/index.js | 59 ++++++ .../totals/totals-footer-item/style.scss | 15 ++ .../totals/totals-shipping-item/index.js | 66 ++++++ .../totals/totals-taxes-item/index.js | 31 +++ .../cart-checkout/cart/full-cart/index.js | 193 +++--------------- .../cart-checkout/cart/full-cart/style.scss | 15 -- 10 files changed, 396 insertions(+), 175 deletions(-) create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/subtotals-item/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-discount-item/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-fees-item/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/style.scss create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-shipping-item/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/totals/totals-taxes-item/index.js diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/index.js index db27b86a211..5542de8d87a 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/totals/index.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/index.js @@ -1,2 +1,8 @@ +export { default as SubtotalsItem } from './subtotals-item'; export { default as TotalsCouponCodeInput } from './totals-coupon-code-input'; +export { default as TotalsDiscountItem } from './totals-discount-item'; +export { default as TotalsFeesItem } from './totals-fees-item'; +export { default as TotalsFooterItem } from './totals-footer-item'; export { default as TotalsItem } from './totals-item'; +export { default as TotalsShippingItem } from './totals-shipping-item'; +export { default as TotalsTaxesItem } from './totals-taxes-item'; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/subtotals-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/subtotals-item/index.js new file mode 100644 index 00000000000..9ea0def2fdf --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/subtotals-item/index.js @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { DISPLAY_CART_PRICES_INCLUDING_TAX } from '@woocommerce/block-settings'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; + +const SubtotalsItem = ( { currency, values } ) => { + const { total_items: totalItems, total_items_tax: totalItemsTax } = values; + const itemsValue = parseInt( totalItems, 10 ); + const itemsTaxValue = parseInt( totalItemsTax, 10 ); + + return ( + + ); +}; + +SubtotalsItem.propTypes = { + currency: PropTypes.object.isRequired, + values: PropTypes.shape( { + total_items: PropTypes.string, + total_items_tax: PropTypes.string, + } ).isRequired, +}; + +export default SubtotalsItem; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-discount-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-discount-item/index.js new file mode 100644 index 00000000000..6ea6bde6e0b --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-discount-item/index.js @@ -0,0 +1,97 @@ +/** + * External dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { DISPLAY_CART_PRICES_INCLUDING_TAX } from '@woocommerce/block-settings'; +import LoadingMask from '@woocommerce/base-components/loading-mask'; +import Chip from '@woocommerce/base-components/chip'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; + +const TotalsDiscountItem = ( { + cartCoupons = [], + currency, + isRemovingCoupon, + removeCoupon, + values, +} ) => { + const { + total_discount: totalDiscount, + total_discount_tax: totalDiscountTax, + } = values; + const discountValue = parseInt( totalDiscount, 10 ); + + if ( ! discountValue && cartCoupons.length === 0 ) { + return null; + } + + const discountTaxValue = parseInt( totalDiscountTax, 10 ); + + return ( + +
    + { cartCoupons.map( ( cartCoupon ) => ( + { + removeCoupon( cartCoupon.code ); + } } + radius="large" + /> + ) ) } +
+ + ) + } + label={ __( 'Discount', 'woo-gutenberg-products-block' ) } + value={ + ( DISPLAY_CART_PRICES_INCLUDING_TAX + ? discountValue + discountTaxValue + : discountValue ) * -1 + } + /> + ); +}; + +TotalsDiscountItem.propTypes = { + cartCoupons: PropTypes.arrayOf( + PropTypes.shape( { + code: PropTypes.string.isRequired, + } ) + ), + currency: PropTypes.object.isRequired, + isRemovingCoupon: PropTypes.bool.isRequired, + removeCoupon: PropTypes.func.isRequired, + values: PropTypes.shape( { + total_discount: PropTypes.string, + total_discount_tax: PropTypes.string, + } ).isRequired, +}; + +export default TotalsDiscountItem; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-fees-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-fees-item/index.js new file mode 100644 index 00000000000..6e181ef7cad --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-fees-item/index.js @@ -0,0 +1,50 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + DISPLAY_CART_PRICES_INCLUDING_TAX, + SHIPPING_ENABLED, +} from '@woocommerce/block-settings'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; + +const TotalsFeesItem = ( { currency, values } ) => { + if ( ! SHIPPING_ENABLED ) { + return null; + } + const { total_fees: totalFees, total_fees_tax: totalFeesTax } = values; + const feesValue = parseInt( totalFees, 10 ); + + if ( ! feesValue ) { + return null; + } + + const feesTaxValue = parseInt( totalFeesTax, 10 ); + + return ( + + ); +}; + +TotalsFeesItem.propTypes = { + currency: PropTypes.object.isRequired, + values: PropTypes.shape( { + total_fees: PropTypes.string, + total_fees_tax: PropTypes.string, + } ).isRequired, +}; + +export default TotalsFeesItem; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/index.js new file mode 100644 index 00000000000..cb2258476af --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/index.js @@ -0,0 +1,59 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { DISPLAY_CART_PRICES_INCLUDING_TAX } from '@woocommerce/block-settings'; +import { __experimentalCreateInterpolateElement } from 'wordpress-element'; +import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; +import './style.scss'; + +const TotalsFooterItem = ( { currency, values } ) => { + const { total_price: totalPrice, total_tax: totalTax } = values; + + return ( + + { __experimentalCreateInterpolateElement( + __( + 'Including in taxes', + 'woo-gutenberg-products-block' + ), + { + TaxAmount: ( + + ), + } + ) } +

+ ) + } + /> + ); +}; + +TotalsFooterItem.propTypes = { + currency: PropTypes.object.isRequired, + values: PropTypes.shape( { + total_price: PropTypes.string, + total_tax: PropTypes.string, + } ).isRequired, +}; + +export default TotalsFooterItem; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/style.scss new file mode 100644 index 00000000000..e968cc7e022 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-footer-item/style.scss @@ -0,0 +1,15 @@ +.wc-block-totals-footer-item { + .wc-block-totals-table-item__value, + .wc-block-totals-table-item__label { + color: #000; + font-size: 1.25em; + } + + .wc-block-totals-table-item__label { + font-weight: normal; + } + + .wc-block-totals-footer-item-tax { + margin-bottom: 0; + } +} diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-shipping-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-shipping-item/index.js new file mode 100644 index 00000000000..bc1a588da6c --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-shipping-item/index.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + DISPLAY_CART_PRICES_INCLUDING_TAX, + SHIPPING_ENABLED, +} from '@woocommerce/block-settings'; +import ShippingCalculator from '@woocommerce/base-components/shipping-calculator'; +import ShippingLocation from '@woocommerce/base-components/shipping-location'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; + +const TotalsShippingItem = ( { + currency, + shippingAddress, + updateShippingAddress, + values, +} ) => { + if ( ! SHIPPING_ENABLED ) { + return null; + } + const { + total_shipping: totalShipping, + total_shipping_tax: totalShippingTax, + } = values; + const shippingValue = parseInt( totalShipping, 10 ); + const shippingTaxValue = parseInt( totalShippingTax, 10 ); + + return ( + + + + + } + label={ __( 'Shipping', 'woo-gutenberg-products-block' ) } + value={ + DISPLAY_CART_PRICES_INCLUDING_TAX + ? shippingValue + shippingTaxValue + : shippingValue + } + /> + ); +}; + +TotalsShippingItem.propTypes = { + currency: PropTypes.object.isRequired, + shippingAddress: PropTypes.object, + updateShippingAddress: PropTypes.func, + values: PropTypes.shape( { + total_shipping: PropTypes.string, + total_shipping_tax: PropTypes.string, + } ).isRequired, +}; + +export default TotalsShippingItem; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-taxes-item/index.js b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-taxes-item/index.js new file mode 100644 index 00000000000..481a5e07c80 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/totals/totals-taxes-item/index.js @@ -0,0 +1,31 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import TotalsItem from '../totals-item'; + +const TotalsTaxesItem = ( { currency, values } ) => { + const { total_tax: totalTax } = values; + + return ( + + ); +}; + +TotalsTaxesItem.propTypes = { + currency: PropTypes.object.isRequired, + values: PropTypes.shape( { + total_tax: PropTypes.string, + } ).isRequired, +}; + +export default TotalsTaxesItem; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/index.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/index.js index da59d01039d..0c6a578c5bd 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/index.js +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/index.js @@ -3,17 +3,18 @@ * External dependencies */ import PropTypes from 'prop-types'; -import { sprintf, __ } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { useState, useEffect } from '@wordpress/element'; import { + SubtotalsItem, + TotalsFeesItem, TotalsCouponCodeInput, - TotalsItem, + TotalsDiscountItem, + TotalsFooterItem, + TotalsShippingItem, + TotalsTaxesItem, } from '@woocommerce/base-components/totals'; import ShippingRatesControl from '@woocommerce/base-components/shipping-rates-control'; -import ShippingCalculator from '@woocommerce/base-components/shipping-calculator'; -import ShippingLocation from '@woocommerce/base-components/shipping-location'; -import LoadingMask from '@woocommerce/base-components/loading-mask'; -import Chip from '@woocommerce/base-components/chip'; import { COUPONS_ENABLED, SHIPPING_ENABLED, @@ -25,7 +26,6 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone import { decodeEntities } from '@wordpress/html-entities'; import { useStoreCartCoupons, useShippingRates } from '@woocommerce/base-hooks'; import classnames from 'classnames'; -import { __experimentalCreateInterpolateElement } from 'wordpress-element'; /** * Internal dependencies @@ -131,109 +131,7 @@ const Cart = ( { return setShowShippingCosts( false ); }, [ isShippingCalculatorEnabled, isShippingCostHidden, shippingAddress ] ); - /** - * Given an API response with cart totals, generates an array of rows to display in the Cart block. - * - * @return {Object[]} Values to display in the cart block. - */ - const getTotalRowsConfig = () => { - const totalItems = parseInt( cartTotals.total_items, 10 ); - const totalItemsTax = parseInt( cartTotals.total_items_tax, 10 ); - const totalRowsConfig = [ - { - label: __( 'Subtotal', 'woo-gutenberg-products-block' ), - value: DISPLAY_CART_PRICES_INCLUDING_TAX - ? totalItems + totalItemsTax - : totalItems, - }, - ]; - const totalFees = parseInt( cartTotals.total_fees, 10 ); - if ( totalFees > 0 ) { - const totalFeesTax = parseInt( cartTotals.total_fees_tax, 10 ); - totalRowsConfig.push( { - label: __( 'Fees', 'woo-gutenberg-products-block' ), - value: DISPLAY_CART_PRICES_INCLUDING_TAX - ? totalFees + totalFeesTax - : totalFees, - } ); - } - const totalDiscount = parseInt( cartTotals.total_discount, 10 ); - if ( totalDiscount > 0 || cartCoupons.length !== 0 ) { - const totalDiscountTax = parseInt( - cartTotals.total_discount_tax, - 10 - ); - // @todo The remove coupon button is a placeholder - replace with new - // chip component. - totalRowsConfig.push( { - label: __( 'Discount', 'woo-gutenberg-products-block' ), - value: - ( DISPLAY_CART_PRICES_INCLUDING_TAX - ? totalDiscount + totalDiscountTax - : totalDiscount ) * -1, - description: cartCoupons.length !== 0 && ( - -
    - { cartCoupons.map( ( cartCoupon ) => ( - { - removeCoupon( cartCoupon.code ); - } } - radius="large" - /> - ) ) } -
-
- ), - } ); - } - - if ( SHIPPING_ENABLED && isShippingCalculatorEnabled ) { - const totalShipping = parseInt( cartTotals.total_shipping, 10 ); - const totalShippingTax = parseInt( - cartTotals.total_shipping_tax, - 10 - ); - totalRowsConfig.push( { - label: __( 'Shipping', 'woo-gutenberg-products-block' ), - value: DISPLAY_CART_PRICES_INCLUDING_TAX - ? totalShipping + totalShippingTax - : totalShipping, - description: ( - <> - - - - ), - } ); - } - return totalRowsConfig; - }; - const totalsCurrency = getCurrencyFromPriceResponse( cartTotals ); - const totalRowsConfig = getTotalRowsConfig(); const cartClassName = classnames( 'wc-block-cart', { 'wc-block-cart--is-loading': isLoading, @@ -257,16 +155,28 @@ const Cart = ( { 'woo-gutenberg-products-block' ) } - { totalRowsConfig.map( - ( { label, value, description } ) => ( - - ) + + + + { isShippingCalculatorEnabled && ( + ) } { showShippingCosts && (
@@ -286,14 +196,9 @@ const Cart = ( {
) } { ! DISPLAY_CART_PRICES_INCLUDING_TAX && ( - ) } { COUPONS_ENABLED && ( @@ -302,41 +207,9 @@ const Cart = ( { isLoading={ isApplyingCoupon } /> ) } - - { __experimentalCreateInterpolateElement( - __( - 'Including in taxes', - 'woo-gutenberg-products-block' - ), - { - TaxAmount: ( - - ), - } - ) } -

- ) - } + values={ cartTotals } /> diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/style.scss index f78a30fdd1c..f0c3c3dbe69 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/style.scss +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart/full-cart/style.scss @@ -45,21 +45,6 @@ opacity: 0.8; } } - .wc-block-cart__totals-footer { - .wc-block-totals-table-item__value, - .wc-block-totals-table-item__label { - color: #000; - font-size: 1.25em; - } - - .wc-block-totals-table-item__label { - font-weight: normal; - } - - .wc-block-cart__totals-footer-tax { - margin-bottom: 0; - } - } // Added extra class and label for specificity. fieldset.wc-block-cart__shipping-options-fieldset { background-color: transparent;