From 10d7bb92cb00959f79143cf74ead5810b131b169 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Tue, 13 Dec 2022 10:59:07 +0100 Subject: [PATCH 01/14] Display 5 'empty' stars if there's no product rating in All Products --- assets/js/atomic/blocks/product-elements/rating/block.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/block.tsx b/assets/js/atomic/blocks/product-elements/rating/block.tsx index 62a769de8a5..f67ea26aa4f 100644 --- a/assets/js/atomic/blocks/product-elements/rating/block.tsx +++ b/assets/js/atomic/blocks/product-elements/rating/block.tsx @@ -61,10 +61,6 @@ export const Block = ( props: Props ): JSX.Element | null => { const typographyProps = useTypographyProps( props ); const spacingProps = useSpacingProps( props ); - if ( ! rating ) { - return null; - } - const starStyle = { width: ( rating / 5 ) * 100 + '%', }; From ae620d0d0d65112cafa0e55f98d19c618a036965 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Tue, 13 Dec 2022 12:08:58 +0100 Subject: [PATCH 02/14] Display 5 'empty' stars if there's no product rating in Productsa and Legacy PHP template --- .../blocks/product-elements/rating/block.tsx | 17 ++++++++++++----- src/BlockTypes/ProductRating.php | 8 +++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/block.tsx b/assets/js/atomic/blocks/product-elements/rating/block.tsx index f67ea26aa4f..9703497d354 100644 --- a/assets/js/atomic/blocks/product-elements/rating/block.tsx +++ b/assets/js/atomic/blocks/product-elements/rating/block.tsx @@ -43,6 +43,17 @@ const getRatingCount = ( product: ProductResponseItem ) => { return Number.isFinite( count ) && count > 0 ? count : 0; }; +const getRatingText = ( rating: number ) => { + if ( rating === 0 ) { + return __( 'No rating available', 'woo-gutenberg-products-block' ); + } + return sprintf( + /* translators: %f is referring to the average rating value */ + __( 'Rated %f out of 5', 'woo-gutenberg-products-block' ), + rating + ); +}; + /** * Product Rating Block Component. * @@ -65,11 +76,7 @@ export const Block = ( props: Props ): JSX.Element | null => { width: ( rating / 5 ) * 100 + '%', }; - const ratingText = sprintf( - /* translators: %f is referring to the average rating value */ - __( 'Rated %f out of 5', 'woo-gutenberg-products-block' ), - rating - ); + const ratingText = getRatingText( rating ); const reviews = getRatingCount( product ); const ratingHTML = { diff --git a/src/BlockTypes/ProductRating.php b/src/BlockTypes/ProductRating.php index 149c26930a5..9af2c54a821 100644 --- a/src/BlockTypes/ProductRating.php +++ b/src/BlockTypes/ProductRating.php @@ -76,11 +76,9 @@ protected function get_block_type_uses_context() { * @return string */ public function filter_rating_html( $html, $rating, $count ) { - if ( 0 < $rating ) { - /* translators: %s: rating */ - $label = sprintf( __( 'Rated %s out of 5', 'woo-gutenberg-products-block' ), $rating ); - $html = ''; - } + /* translators: %s: rating */ + $label = 0 < $rating ? sprintf( __( 'Rated %s out of 5', 'woo-gutenberg-products-block' ), $rating ) : sprintf( __( 'No rating available', 'woo-gutenberg-products-block' ) ); + $html = ''; return $html; } From 51d5fa505528411d5734cf630be689ff95d4088e Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 11:36:43 +0100 Subject: [PATCH 03/14] Display Add Review link in the All Products if there's no product rating --- .../blocks/product-elements/rating/block.tsx | 60 ++++++++++++------- .../blocks/product-elements/rating/style.scss | 8 +++ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/block.tsx b/assets/js/atomic/blocks/product-elements/rating/block.tsx index 9703497d354..7506b6f1a2e 100644 --- a/assets/js/atomic/blocks/product-elements/rating/block.tsx +++ b/assets/js/atomic/blocks/product-elements/rating/block.tsx @@ -25,6 +25,10 @@ type Props = { className?: string; }; +type AddReviewProps = { + href?: string; +}; + const getAverageRating = ( product: Omit< ProductResponseItem, 'average_rating' > & { average_rating: string; @@ -35,6 +39,11 @@ const getAverageRating = ( return Number.isFinite( rating ) && rating > 0 ? rating : 0; }; +const getReviewsHref = ( product: ProductResponseItem ) => { + const { permalink } = product; + return `${ permalink }#reviews`; +}; + const getRatingCount = ( product: ProductResponseItem ) => { const count = isNumber( product.review_count ) ? product.review_count @@ -43,15 +52,11 @@ const getRatingCount = ( product: ProductResponseItem ) => { return Number.isFinite( count ) && count > 0 ? count : 0; }; -const getRatingText = ( rating: number ) => { - if ( rating === 0 ) { - return __( 'No rating available', 'woo-gutenberg-products-block' ); - } - return sprintf( - /* translators: %f is referring to the average rating value */ - __( 'Rated %f out of 5', 'woo-gutenberg-products-block' ), - rating - ); +const AddReview = ( props: AddReviewProps ): JSX.Element | null => { + const { href } = props; + const label = __( 'Add review', 'woo-gutenberg-products-block' ); + + return href ? { label } : null; }; /** @@ -76,7 +81,11 @@ export const Block = ( props: Props ): JSX.Element | null => { width: ( rating / 5 ) * 100 + '%', }; - const ratingText = getRatingText( rating ); + const ratingText = sprintf( + /* translators: %f is referring to the average rating value */ + __( 'Rated %f out of 5', 'woo-gutenberg-products-block' ), + rating + ); const reviews = getRatingCount( product ); const ratingHTML = { @@ -93,6 +102,23 @@ export const Block = ( props: Props ): JSX.Element | null => { ), }; + const href = getReviewsHref( product ); + + const content = reviews ? ( +
+ +
+ ) : ( + + ); + return (
{ ...spacingProps.style, } } > -
- -
+ { content }
); }; diff --git a/assets/js/atomic/blocks/product-elements/rating/style.scss b/assets/js/atomic/blocks/product-elements/rating/style.scss index 9452669113d..82085d3622b 100644 --- a/assets/js/atomic/blocks/product-elements/rating/style.scss +++ b/assets/js/atomic/blocks/product-elements/rating/style.scss @@ -46,8 +46,16 @@ } } } + .wc-block-single-product { .wc-block-components-product-rating__stars { margin: 0; } } + +.is-loading { + .wc-block-components-product-rating { + @include placeholder(); + width: 7em; + } +} From b43774709373162d50d6aa59d1447a464e493f69 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 12:18:59 +0100 Subject: [PATCH 04/14] Center the placeholder and Add Review link in the Products Editor --- .../js/atomic/blocks/product-elements/rating/style.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/assets/js/atomic/blocks/product-elements/rating/style.scss b/assets/js/atomic/blocks/product-elements/rating/style.scss index 82085d3622b..0909239ce76 100644 --- a/assets/js/atomic/blocks/product-elements/rating/style.scss +++ b/assets/js/atomic/blocks/product-elements/rating/style.scss @@ -45,6 +45,12 @@ white-space: nowrap; } } + + &__link { + display: inline-block; + width: 100%; + text-align: center; + } } .wc-block-single-product { @@ -57,5 +63,7 @@ .wc-block-components-product-rating { @include placeholder(); width: 7em; + margin-left: auto; + margin-right: auto; } } From 6b1a4acac778d0a0b4ad9a88bd8819a5174e3923 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 12:19:44 +0100 Subject: [PATCH 05/14] Refactor product-elements/rating block --- .../blocks/product-elements/rating/block.tsx | 98 +++++++++++-------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/block.tsx b/assets/js/atomic/blocks/product-elements/rating/block.tsx index 7506b6f1a2e..02d7ec714ee 100644 --- a/assets/js/atomic/blocks/product-elements/rating/block.tsx +++ b/assets/js/atomic/blocks/product-elements/rating/block.tsx @@ -25,6 +25,12 @@ type Props = { className?: string; }; +type RatingProps = { + reviews: number; + rating: number; + parentClassName?: string; +}; + type AddReviewProps = { href?: string; }; @@ -52,30 +58,8 @@ const getRatingCount = ( product: ProductResponseItem ) => { return Number.isFinite( count ) && count > 0 ? count : 0; }; -const AddReview = ( props: AddReviewProps ): JSX.Element | null => { - const { href } = props; - const label = __( 'Add review', 'woo-gutenberg-products-block' ); - - return href ? { label } : null; -}; - -/** - * Product Rating Block Component. - * - * @param {Object} props Incoming props. - * @param {string} [props.className] CSS Class name for the component. - * @param {string} [props.textAlign] Text alignment. - * - * @return {*} The component. - */ -export const Block = ( props: Props ): JSX.Element | null => { - const { textAlign } = props; - const { parentClassName } = useInnerBlockLayoutContext(); - const { product } = useProductDataContext(); - const rating = getAverageRating( product ); - const colorProps = useColorProps( props ); - const typographyProps = useTypographyProps( props ); - const spacingProps = useSpacingProps( props ); +const Rating = ( props: RatingProps ): JSX.Element => { + const { rating, reviews, parentClassName } = props; const starStyle = { width: ( rating / 5 ) * 100 + '%', @@ -87,7 +71,6 @@ export const Block = ( props: Props ): JSX.Element | null => { rating ); - const reviews = getRatingCount( product ); const ratingHTML = { __html: sprintf( /* translators: %1$s is referring to the average rating value, %2$s is referring to the number of ratings */ @@ -101,10 +84,7 @@ export const Block = ( props: Props ): JSX.Element | null => { sprintf( '%d', reviews ) ), }; - - const href = getReviewsHref( product ); - - const content = reviews ? ( + return (
{ >
+ ); +}; + +const AddReview = ( props: AddReviewProps ): JSX.Element | null => { + const { href } = props; + const label = __( 'Add review', 'woo-gutenberg-products-block' ); + + return href ? ( + + { label } + + ) : null; +}; + +/** + * Product Rating Block Component. + * + * @param {Object} props Incoming props. + * @param {string} [props.className] CSS Class name for the component. + * @param {string} [props.textAlign] Text alignment. + * + * @return {*} The component. + */ +export const Block = ( props: Props ): JSX.Element | null => { + const { textAlign } = props; + const { parentClassName } = useInnerBlockLayoutContext(); + const { product } = useProductDataContext(); + const rating = getAverageRating( product ); + const colorProps = useColorProps( props ); + const typographyProps = useTypographyProps( props ); + const spacingProps = useSpacingProps( props ); + const reviews = getRatingCount( product ); + const href = getReviewsHref( product ); + + const className = classnames( + colorProps.className, + 'wc-block-components-product-rating', + { + [ `${ parentClassName }__product-rating` ]: parentClassName, + [ `has-text-align-${ textAlign }` ]: textAlign, + } + ); + + const content = reviews ? ( + ) : ( ); return (
Date: Thu, 15 Dec 2022 14:50:11 +0100 Subject: [PATCH 06/14] Display Add Review link in the Products if there's no product rating --- src/BlockTypes/ProductRating.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/BlockTypes/ProductRating.php b/src/BlockTypes/ProductRating.php index 9af2c54a821..b387c1cf5bb 100644 --- a/src/BlockTypes/ProductRating.php +++ b/src/BlockTypes/ProductRating.php @@ -76,9 +76,11 @@ protected function get_block_type_uses_context() { * @return string */ public function filter_rating_html( $html, $rating, $count ) { - /* translators: %s: rating */ - $label = 0 < $rating ? sprintf( __( 'Rated %s out of 5', 'woo-gutenberg-products-block' ), $rating ) : sprintf( __( 'No rating available', 'woo-gutenberg-products-block' ) ); - $html = ''; + if ( 0 < $rating ) { + /* translators: %s: rating */ + $label = sprintf( __( 'Rated %s out of 5', 'woo-gutenberg-products-block' ), $rating ); + $html = ''; + } return $html; } @@ -111,6 +113,13 @@ protected function render( $attributes, $content, $block ) { $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array( 'font_size', 'margin', 'text_color' ) ); $text_align_styles_and_classes = StyleAttributesUtils::get_text_align_class_and_style( $attributes ); + $average_rating = $product->get_average_rating(); + $reviews_link = $product->get_permalink() . '#reviews'; + $link_label = __( 'Add review', 'woo-gutenberg-products-block' ); + $link_html = '' . esc_attr( $link_label ) . ''; + + $content = $rating_count ? wc_get_rating_html( $average_rating ) : $link_html; + return sprintf( '
%4$s @@ -118,7 +127,7 @@ protected function render( $attributes, $content, $block ) { esc_attr( $text_align_styles_and_classes['class'] ?? '' ), esc_attr( $styles_and_classes['classes'] ), esc_attr( $styles_and_classes['styles'] ?? '' ), - wc_get_rating_html( $product->get_average_rating() ) + $content ); } } From 86f4752a0b21e71efd94cb6c72571efc604e3e28 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 15:19:21 +0100 Subject: [PATCH 07/14] Bring back missing variable --- src/BlockTypes/ProductRating.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BlockTypes/ProductRating.php b/src/BlockTypes/ProductRating.php index b387c1cf5bb..cd1ef6ac2ab 100644 --- a/src/BlockTypes/ProductRating.php +++ b/src/BlockTypes/ProductRating.php @@ -114,6 +114,7 @@ protected function render( $attributes, $content, $block ) { $text_align_styles_and_classes = StyleAttributesUtils::get_text_align_class_and_style( $attributes ); $average_rating = $product->get_average_rating(); + $rating_count = $product->get_rating_count(); $reviews_link = $product->get_permalink() . '#reviews'; $link_label = __( 'Add review', 'woo-gutenberg-products-block' ); $link_html = '' . esc_attr( $link_label ) . ''; From faaeaacc2da8ce4551682a30ec93f3e53bfa8447 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 15:19:39 +0100 Subject: [PATCH 08/14] Remove unused variable --- src/BlockTypes/AbstractProductGrid.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BlockTypes/AbstractProductGrid.php b/src/BlockTypes/AbstractProductGrid.php index caa51c0713b..2f6034532c4 100644 --- a/src/BlockTypes/AbstractProductGrid.php +++ b/src/BlockTypes/AbstractProductGrid.php @@ -572,7 +572,6 @@ protected function get_rating_html( $product ) { return ''; } $rating_count = $product->get_rating_count(); - $review_count = $product->get_review_count(); $average = $product->get_average_rating(); if ( $rating_count > 0 ) { From 76d68fd9af68a907fc445ed56d4c3bd088e7388b Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 15:20:06 +0100 Subject: [PATCH 09/14] Apply the font-size mixin to the Add Review link --- assets/js/atomic/blocks/product-elements/rating/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/js/atomic/blocks/product-elements/rating/style.scss b/assets/js/atomic/blocks/product-elements/rating/style.scss index 0909239ce76..473452a7a5e 100644 --- a/assets/js/atomic/blocks/product-elements/rating/style.scss +++ b/assets/js/atomic/blocks/product-elements/rating/style.scss @@ -50,6 +50,7 @@ display: inline-block; width: 100%; text-align: center; + @include font-size(small); } } From d7369d4b6ff5e594a02ffe2c250663a4787b907b Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 15 Dec 2022 17:11:40 +0100 Subject: [PATCH 10/14] Make Add review link NOT clickable in editor --- assets/js/atomic/blocks/product-elements/rating/edit.tsx | 1 + assets/js/atomic/blocks/product-elements/rating/editor.scss | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 assets/js/atomic/blocks/product-elements/rating/editor.scss diff --git a/assets/js/atomic/blocks/product-elements/rating/edit.tsx b/assets/js/atomic/blocks/product-elements/rating/edit.tsx index 19dd529c19f..d2c8e56270d 100644 --- a/assets/js/atomic/blocks/product-elements/rating/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/rating/edit.tsx @@ -18,6 +18,7 @@ import Block from './block'; import withProductSelector from '../shared/with-product-selector'; import { BLOCK_TITLE, BLOCK_ICON } from './constants'; import { Attributes } from './types'; +import './editor.scss'; const Edit = ( { attributes, diff --git a/assets/js/atomic/blocks/product-elements/rating/editor.scss b/assets/js/atomic/blocks/product-elements/rating/editor.scss new file mode 100644 index 00000000000..1b7514bcf0a --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/rating/editor.scss @@ -0,0 +1,3 @@ +.wc-block-components-product-rating__link { + pointer-events: none; +} From dbf22c398da4ec6341979b1eedf1d53f2a7d9c19 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Fri, 16 Dec 2022 11:57:36 +0100 Subject: [PATCH 11/14] Escape URL used in the Add Review link --- src/BlockTypes/ProductRating.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BlockTypes/ProductRating.php b/src/BlockTypes/ProductRating.php index cd1ef6ac2ab..adb682db742 100644 --- a/src/BlockTypes/ProductRating.php +++ b/src/BlockTypes/ProductRating.php @@ -117,7 +117,7 @@ protected function render( $attributes, $content, $block ) { $rating_count = $product->get_rating_count(); $reviews_link = $product->get_permalink() . '#reviews'; $link_label = __( 'Add review', 'woo-gutenberg-products-block' ); - $link_html = '' . esc_attr( $link_label ) . ''; + $link_html = '' . esc_attr( $link_label ) . ''; $content = $rating_count ? wc_get_rating_html( $average_rating ) : $link_html; From dca9a01f51e2123d11428aa063fb92f66c204c59 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Fri, 16 Dec 2022 15:42:04 +0100 Subject: [PATCH 12/14] Improve styles of Rating component so they support alignment in product grids --- .../atomic/blocks/product-elements/rating/style.scss | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/style.scss b/assets/js/atomic/blocks/product-elements/rating/style.scss index 473452a7a5e..cfd46836b33 100644 --- a/assets/js/atomic/blocks/product-elements/rating/style.scss +++ b/assets/js/atomic/blocks/product-elements/rating/style.scss @@ -4,6 +4,7 @@ margin-bottom: $gap-small; &__stars { + display: inline-block; overflow: hidden; position: relative; width: 5.3em; @@ -49,7 +50,7 @@ &__link { display: inline-block; width: 100%; - text-align: center; + text-align: inherit; @include font-size(small); } } @@ -68,3 +69,10 @@ margin-right: auto; } } + +// Fix applied specifically to Classic Template +.woocommerce-loop-product__link { + .wc-block-components-product-rating__stars { + display: block; + } +} From cc77dd80f39654fcbbdc84656bb119446c9f5718 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Mon, 19 Dec 2022 16:16:56 +0100 Subject: [PATCH 13/14] Limit the placeholder of Rating just to the All Products and Products block That could be done globally, however there's a bug that makes Filter by Rating keeping is-loading class which keeps the placeholder visible there all the time --- .../blocks/product-elements/rating/style.scss | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/rating/style.scss b/assets/js/atomic/blocks/product-elements/rating/style.scss index cfd46836b33..a94e66f86a1 100644 --- a/assets/js/atomic/blocks/product-elements/rating/style.scss +++ b/assets/js/atomic/blocks/product-elements/rating/style.scss @@ -61,12 +61,15 @@ } } -.is-loading { - .wc-block-components-product-rating { - @include placeholder(); - width: 7em; - margin-left: auto; - margin-right: auto; +.wc-block-all-products, +.wp-block-query { + .is-loading { + .wc-block-components-product-rating { + @include placeholder(); + width: 7em; + margin-left: auto; + margin-right: auto; + } } } From 6f8b2fbb21f41283627c26e30689416303166fcd Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Tue, 27 Dec 2022 15:33:37 +0100 Subject: [PATCH 14/14] Move the logic to render link from render function to the filter --- src/BlockTypes/ProductRating.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/BlockTypes/ProductRating.php b/src/BlockTypes/ProductRating.php index adb682db742..ac419567815 100644 --- a/src/BlockTypes/ProductRating.php +++ b/src/BlockTypes/ProductRating.php @@ -76,11 +76,16 @@ protected function get_block_type_uses_context() { * @return string */ public function filter_rating_html( $html, $rating, $count ) { - if ( 0 < $rating ) { + $product_permalink = get_permalink(); + if ( 0 < $rating || false === $product_permalink ) { /* translators: %s: rating */ $label = sprintf( __( 'Rated %s out of 5', 'woo-gutenberg-products-block' ), $rating ); $html = ''; + } else { + $product_review_url = esc_url( $product_permalink . '#reviews' ); + $html = '' . __( 'Add review', 'woo-gutenberg-products-block' ) . ''; } + return $html; } @@ -113,14 +118,6 @@ protected function render( $attributes, $content, $block ) { $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array( 'font_size', 'margin', 'text_color' ) ); $text_align_styles_and_classes = StyleAttributesUtils::get_text_align_class_and_style( $attributes ); - $average_rating = $product->get_average_rating(); - $rating_count = $product->get_rating_count(); - $reviews_link = $product->get_permalink() . '#reviews'; - $link_label = __( 'Add review', 'woo-gutenberg-products-block' ); - $link_html = '' . esc_attr( $link_label ) . ''; - - $content = $rating_count ? wc_get_rating_html( $average_rating ) : $link_html; - return sprintf( '
%4$s @@ -128,7 +125,7 @@ protected function render( $attributes, $content, $block ) { esc_attr( $text_align_styles_and_classes['class'] ?? '' ), esc_attr( $styles_and_classes['classes'] ), esc_attr( $styles_and_classes['styles'] ?? '' ), - $content + wc_get_rating_html( $product->get_average_rating() ) ); } }