Stop hidden products from being linked in cart and checkout blocks (https://github.com/woocommerce/woocommerce-blocks/pull/3415)
* Add catalog_visibility to CartItemSchema.php This is used to get whether the product is visible in the catalogue, visible in the shop only, visible in search results only, or visible everywhere. We need to know this so we can pass it to the ProductImage and ProductName components. * Remove links from CartLineItemRow if not visible in catalogue Added catalog_visibility to lineItems prop, and when the product is not visible in the catalogue do not wrap product image in a link. Also pass down the hasLink prop to ProductName. * Add hasLink prop to ProductName When this prop is false we should not output the link around the product name. This is for when the product is hidden from the catalogue but we still want to show its name somewhere. * Add tests and storybook for ProductName * Add catalog_visibility check to OrderSummaryItem When the catalogue visibility of a product is set to hidden or search, then the product name in the checkout sidebar should not be hyperlinked. * Reverse logic for hiding link on product image & disabling link on name Following a point from @budzanowski we do not need the hasLink prop, making use of disabled is probably a better idea. * Remove tabindex from a in ProductName & output span if name is disabled This change removes the need to pass a tabindex to the a in ProductName. This is because a disabled ProductName will now never output an a tag. When the ProductName is disabled a span is output instead, which has no tabindex by default. This change also reverses the logic to decide whether the a or span should be output so as to make the code more readable and flow better. * Update storybook and tests/snapshots for ProductName
This commit is contained in:
parent
f6c8d91b9d
commit
fcfe5ee7dc
|
@ -18,6 +18,7 @@ import Dinero from 'dinero.js';
|
|||
const OrderSummaryItem = ( { cartItem } ) => {
|
||||
const {
|
||||
images,
|
||||
catalog_visibility: catalogVisibility = '',
|
||||
low_stock_remaining: lowStockRemaining = null,
|
||||
show_backorder_badge: showBackorderBadge = false,
|
||||
name,
|
||||
|
@ -37,6 +38,8 @@ const OrderSummaryItem = ( { cartItem } ) => {
|
|||
.multiply( quantity )
|
||||
.convertPrecision( currency.minorUnit )
|
||||
.getAmount();
|
||||
const shouldLinkToProduct =
|
||||
catalogVisibility !== 'hidden' && catalogVisibility !== 'search';
|
||||
|
||||
return (
|
||||
<div className="wc-block-components-order-summary-item">
|
||||
|
@ -55,7 +58,11 @@ const OrderSummaryItem = ( { cartItem } ) => {
|
|||
</div>
|
||||
<div className="wc-block-components-order-summary-item__description">
|
||||
<div className="wc-block-components-order-summary-item__header">
|
||||
<ProductName permalink={ permalink } name={ name } />
|
||||
<ProductName
|
||||
hasLink={ shouldLinkToProduct }
|
||||
permalink={ permalink }
|
||||
name={ name }
|
||||
/>
|
||||
<ProductPrice
|
||||
currency={ currency }
|
||||
price={ linePrice }
|
||||
|
|
|
@ -10,14 +10,12 @@ import { decodeEntities } from '@wordpress/html-entities';
|
|||
import './style.scss';
|
||||
|
||||
const ProductName = ( { name, permalink, disabled = false } ) => {
|
||||
return (
|
||||
// we use tabIndex -1 to prevent the link from being focused, pointer-events
|
||||
// disabled click events, so we get an almost disabled link.
|
||||
<a
|
||||
className="wc-block-components-product-name"
|
||||
href={ permalink }
|
||||
tabIndex={ disabled ? -1 : 0 }
|
||||
>
|
||||
return disabled ? (
|
||||
<span className="wc-block-components-product-name">
|
||||
{ decodeEntities( name ) }
|
||||
</span>
|
||||
) : (
|
||||
<a className="wc-block-components-product-name" href={ permalink }>
|
||||
{ decodeEntities( name ) }
|
||||
</a>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { boolean } from '@storybook/addon-knobs';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ProductName from '../';
|
||||
|
||||
export default {
|
||||
title: 'WooCommerce Blocks/@base-components/cart-checkout/ProductName',
|
||||
component: ProductName,
|
||||
};
|
||||
|
||||
export const Default = () => {
|
||||
const disabled = boolean( 'disabled', false );
|
||||
|
||||
return (
|
||||
<ProductName
|
||||
disabled={ disabled }
|
||||
name={ 'Test product' }
|
||||
permalink={ '/' }
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ProductName should not render a link if disabled is true 1`] = `
|
||||
<span
|
||||
className="wc-block-components-product-name"
|
||||
>
|
||||
Test product
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`ProductName should render a link if disabled is false 1`] = `
|
||||
<a
|
||||
className="wc-block-components-product-name"
|
||||
>
|
||||
Test product
|
||||
</a>
|
||||
`;
|
||||
|
||||
exports[`ProductName should render a link if disabled is not defined 1`] = `
|
||||
<a
|
||||
className="wc-block-components-product-name"
|
||||
>
|
||||
Test product
|
||||
</a>
|
||||
`;
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import TestRenderer from 'react-test-renderer';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ProductName from '..';
|
||||
|
||||
describe( 'ProductName', () => {
|
||||
test( 'should not render a link if disabled is true', () => {
|
||||
const component = TestRenderer.create(
|
||||
<ProductName disabled={ true } name={ 'Test product' } />
|
||||
);
|
||||
|
||||
expect( component.toJSON() ).toMatchSnapshot();
|
||||
} );
|
||||
|
||||
test( 'should render a link if disabled is false', () => {
|
||||
const component = TestRenderer.create(
|
||||
<ProductName disabled={ false } name={ 'Test product' } />
|
||||
);
|
||||
|
||||
expect( component.toJSON() ).toMatchSnapshot();
|
||||
} );
|
||||
|
||||
test( 'should render a link if disabled is not defined', () => {
|
||||
const component = TestRenderer.create(
|
||||
<ProductName name={ 'Test product' } />
|
||||
);
|
||||
|
||||
expect( component.toJSON() ).toMatchSnapshot();
|
||||
} );
|
||||
} );
|
|
@ -43,6 +43,7 @@ const getAmountFromRawPrice = ( priceObject, currency ) => {
|
|||
const CartLineItemRow = ( { lineItem = {} } ) => {
|
||||
const {
|
||||
name = '',
|
||||
catalog_visibility: catalogVisibility = '',
|
||||
short_description: shortDescription = '',
|
||||
description: fullDescription = '',
|
||||
low_stock_remaining: lowStockRemaining = null,
|
||||
|
@ -90,6 +91,8 @@ const CartLineItemRow = ( { lineItem = {} } ) => {
|
|||
} ).multiply( quantity );
|
||||
const saleAmount = regularAmount.subtract( purchaseAmount );
|
||||
const firstImage = images.length ? images[ 0 ] : {};
|
||||
const isProductHiddenFromCatalog =
|
||||
catalogVisibility === 'hidden' || catalogVisibility === 'search';
|
||||
|
||||
return (
|
||||
<tr
|
||||
|
@ -103,15 +106,19 @@ const CartLineItemRow = ( { lineItem = {} } ) => {
|
|||
aria-hidden={ ! firstImage.alt }
|
||||
>
|
||||
{ /* We don't need to make it focusable, because product name has the same link. */ }
|
||||
<a href={ permalink } tabIndex={ -1 }>
|
||||
{ isProductHiddenFromCatalog ? (
|
||||
<ProductImage image={ firstImage } />
|
||||
</a>
|
||||
) : (
|
||||
<a href={ permalink } tabIndex={ -1 }>
|
||||
<ProductImage image={ firstImage } />
|
||||
</a>
|
||||
) }
|
||||
</td>
|
||||
<td className="wc-block-cart-item__product">
|
||||
<ProductName
|
||||
permalink={ permalink }
|
||||
name={ name }
|
||||
disabled={ isPendingDelete }
|
||||
disabled={ isPendingDelete || isProductHiddenFromCatalog }
|
||||
/>
|
||||
{ showBackorderBadge ? (
|
||||
<ProductBackorderBadge />
|
||||
|
|
|
@ -260,6 +260,12 @@ class CartItemSchema extends ProductSchema {
|
|||
]
|
||||
),
|
||||
],
|
||||
'catalog_visibility' => [
|
||||
'description' => __( 'Whether the product is visible in the catalog', 'woo-gutenberg-products-block' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view', 'edit' ],
|
||||
'readonly' => true,
|
||||
],
|
||||
self::EXTENDING_KEY => $this->get_extended_schema( self::IDENTIFIER ),
|
||||
];
|
||||
}
|
||||
|
@ -299,6 +305,7 @@ class CartItemSchema extends ProductSchema {
|
|||
'line_total_tax' => $this->prepare_money_response( $cart_item['line_tax'], wc_get_price_decimals() ),
|
||||
]
|
||||
),
|
||||
'catalog_visibility' => $product->get_catalog_visibility(),
|
||||
self::EXTENDING_KEY => $this->get_extended_data( self::IDENTIFIER, $cart_item ),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -245,6 +245,7 @@ class CartItems extends TestCase {
|
|||
$this->assertArrayHasKey( 'backorders_allowed', $data );
|
||||
$this->assertArrayHasKey( 'show_backorder_badge', $data );
|
||||
$this->assertArrayHasKey( 'short_description', $data );
|
||||
$this->assertArrayHasKey( 'catalog_visibility', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue