From 9584744d8b2a8e75009110367528767e91ded990 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:32:53 +0200 Subject: [PATCH 001/111] Move default Product Collection template to constants --- .../js/blocks/product-collection/constants.ts | 60 +++++++++++++++++ assets/js/blocks/product-collection/edit.tsx | 65 +------------------ 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/assets/js/blocks/product-collection/constants.ts b/assets/js/blocks/product-collection/constants.ts index 78455691dbc..18c2fbe4949 100644 --- a/assets/js/blocks/product-collection/constants.ts +++ b/assets/js/blocks/product-collection/constants.ts @@ -3,6 +3,7 @@ */ import { getSetting } from '@woocommerce/settings'; import { objectOmit } from '@woocommerce/utils'; +import { type InnerBlockTemplate } from '@wordpress/blocks'; /** * Internal dependencies @@ -14,6 +15,8 @@ import { ProductCollectionQuery, ProductCollectionDisplayLayout, } from './types'; +import { ImageSizing } from '../../atomic/blocks/product-elements/image/types'; +import { VARIATION_NAME as PRODUCT_TITLE_ID } from './variations/elements/product-title'; export const STOCK_STATUS_OPTIONS = getSetting< Record< string, string > >( 'stockStatusOptions', @@ -87,3 +90,60 @@ export const DEFAULT_FILTERS: Partial< ProductCollectionQuery > = { taxQuery: DEFAULT_QUERY.taxQuery, woocommerceHandPickedProducts: [], }; + +export const INNER_BLOCKS_TEMPLATE: InnerBlockTemplate[] = [ + [ + 'woocommerce/product-template', + {}, + [ + [ + 'woocommerce/product-image', + { + imageSizing: ImageSizing.THUMBNAIL, + }, + ], + [ + 'core/post-title', + { + textAlign: 'center', + level: 3, + fontSize: 'medium', + style: { + spacing: { + margin: { + bottom: '0.75rem', + top: '0', + }, + }, + }, + isLink: true, + __woocommerceNamespace: PRODUCT_TITLE_ID, + }, + ], + [ + 'woocommerce/product-price', + { + textAlign: 'center', + fontSize: 'small', + }, + ], + [ + 'woocommerce/product-button', + { + textAlign: 'center', + fontSize: 'small', + }, + ], + ], + ], + [ + 'core/query-pagination', + { + layout: { + type: 'flex', + justifyContent: 'center', + }, + }, + ], + [ 'core/query-no-results' ], +]; diff --git a/assets/js/blocks/product-collection/edit.tsx b/assets/js/blocks/product-collection/edit.tsx index dfc53b1e662..5f7aec5fc3a 100644 --- a/assets/js/blocks/product-collection/edit.tsx +++ b/assets/js/blocks/product-collection/edit.tsx @@ -2,81 +2,22 @@ * External dependencies */ import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; -import { BlockEditProps, InnerBlockTemplate } from '@wordpress/blocks'; +import { BlockEditProps } from '@wordpress/blocks'; import { useInstanceId } from '@wordpress/compose'; import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import { ImageSizing } from '../../atomic/blocks/product-elements/image/types'; import type { ProductCollectionAttributes, ProductCollectionQuery, } from './types'; -import { VARIATION_NAME as PRODUCT_TITLE_ID } from './variations/elements/product-title'; import InspectorControls from './inspector-controls'; -import { DEFAULT_ATTRIBUTES } from './constants'; -import './editor.scss'; +import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from './constants'; import { getDefaultValueOfInheritQueryFromTemplate } from './utils'; import ToolbarControls from './toolbar-controls'; - -export const INNER_BLOCKS_TEMPLATE: InnerBlockTemplate[] = [ - [ - 'woocommerce/product-template', - {}, - [ - [ - 'woocommerce/product-image', - { - imageSizing: ImageSizing.THUMBNAIL, - }, - ], - [ - 'core/post-title', - { - textAlign: 'center', - level: 3, - fontSize: 'medium', - style: { - spacing: { - margin: { - bottom: '0.75rem', - top: '0', - }, - }, - }, - isLink: true, - __woocommerceNamespace: PRODUCT_TITLE_ID, - }, - ], - [ - 'woocommerce/product-price', - { - textAlign: 'center', - fontSize: 'small', - }, - ], - [ - 'woocommerce/product-button', - { - textAlign: 'center', - fontSize: 'small', - }, - ], - ], - ], - [ - 'core/query-pagination', - { - layout: { - type: 'flex', - justifyContent: 'center', - }, - }, - ], - [ 'core/query-no-results' ], -]; +import './editor.scss'; const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { const { attributes, setAttributes } = props; From 815cbc02fc7c42dea002839d1d1a56d0480ba364 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:19:48 +0200 Subject: [PATCH 002/111] Move Product Collection editor related code to edit directory and display the placeholer --- .../ProductCollectionContent.tsx} | 19 ++++--- .../edit/ProductCollectionPlaceholder.tsx | 49 +++++++++++++++++++ .../product-collection/{ => edit}/editor.scss | 0 .../blocks/product-collection/edit/index.tsx | 32 ++++++++++++ .../inspector-controls/attributes-control.tsx | 2 +- .../inspector-controls/author-control.tsx | 2 +- .../inspector-controls/columns-control.tsx | 4 +- .../hand-picked-products-control.tsx | 2 +- .../{ => edit}/inspector-controls/index.tsx | 8 +-- .../inherit-query-control.tsx | 6 +-- .../inspector-controls/keyword-control.tsx | 2 +- .../inspector-controls/on-sale-control.tsx | 2 +- .../inspector-controls/order-by-control.tsx | 4 +- .../stock-status-control.tsx | 4 +- .../taxonomy-controls/index.tsx | 2 +- .../taxonomy-controls/taxonomy-item.tsx | 0 .../inspector-controls/upgrade-notice.tsx | 0 .../display-layout-toolbar.tsx | 2 +- .../display-settings-toolbar.tsx | 2 +- .../{ => edit}/toolbar-controls/index.tsx | 4 +- .../pattern-chooser-toolbar.tsx | 0 .../pattern-selection-modal.tsx | 2 +- 22 files changed, 116 insertions(+), 32 deletions(-) rename assets/js/blocks/product-collection/{edit.tsx => edit/ProductCollectionContent.tsx} (81%) create mode 100644 assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx rename assets/js/blocks/product-collection/{ => edit}/editor.scss (100%) create mode 100644 assets/js/blocks/product-collection/edit/index.tsx rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/attributes-control.tsx (97%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/author-control.tsx (98%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/columns-control.tsx (91%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/hand-picked-products-control.tsx (98%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/index.tsx (96%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/inherit-query-control.tsx (93%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/keyword-control.tsx (96%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/on-sale-control.tsx (95%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/order-by-control.tsx (96%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/stock-status-control.tsx (97%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/taxonomy-controls/index.tsx (97%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/taxonomy-controls/taxonomy-item.tsx (100%) rename assets/js/blocks/product-collection/{ => edit}/inspector-controls/upgrade-notice.tsx (100%) rename assets/js/blocks/product-collection/{ => edit}/toolbar-controls/display-layout-toolbar.tsx (97%) rename assets/js/blocks/product-collection/{ => edit}/toolbar-controls/display-settings-toolbar.tsx (98%) rename assets/js/blocks/product-collection/{ => edit}/toolbar-controls/index.tsx (93%) rename assets/js/blocks/product-collection/{ => edit}/toolbar-controls/pattern-chooser-toolbar.tsx (100%) rename assets/js/blocks/product-collection/{ => edit}/toolbar-controls/pattern-selection-modal.tsx (97%) diff --git a/assets/js/blocks/product-collection/edit.tsx b/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx similarity index 81% rename from assets/js/blocks/product-collection/edit.tsx rename to assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx index 5f7aec5fc3a..29d3ad1eeb9 100644 --- a/assets/js/blocks/product-collection/edit.tsx +++ b/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx @@ -12,14 +12,15 @@ import { useEffect } from '@wordpress/element'; import type { ProductCollectionAttributes, ProductCollectionQuery, -} from './types'; +} from '../types'; +import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from '../constants'; +import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; import InspectorControls from './inspector-controls'; -import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from './constants'; -import { getDefaultValueOfInheritQueryFromTemplate } from './utils'; import ToolbarControls from './toolbar-controls'; -import './editor.scss'; -const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { +const ProductCollectionContent = ( + props: BlockEditProps< ProductCollectionAttributes > +) => { const { attributes, setAttributes } = props; const { queryId } = attributes; @@ -28,7 +29,7 @@ const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { template: INNER_BLOCKS_TEMPLATE, } ); - const instanceId = useInstanceId( Edit ); + const instanceId = useInstanceId( ProductCollectionContent ); // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. @@ -61,7 +62,9 @@ const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { * We don't wanna render anything until default attributes are set. * Default attributes are set in the useEffect above. */ - if ( typeof attributes?.query?.inherit !== 'boolean' ) return null; + if ( typeof attributes?.query?.inherit !== 'boolean' ) { + return null; + } return (
@@ -72,4 +75,4 @@ const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { ); }; -export default Edit; +export default ProductCollectionContent; diff --git a/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx b/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx new file mode 100644 index 00000000000..f215847f8fe --- /dev/null +++ b/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx @@ -0,0 +1,49 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useBlockProps } from '@wordpress/block-editor'; +import { Placeholder, Button } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import Icon from '../icon'; + +const QueryPlaceholder = () => { + const blockProps = useBlockProps(); + const tempEventHandler = () => { + /** Temp handler */ + }; + + return ( +
+ + + + +
+ ); +}; + +export default QueryPlaceholder; diff --git a/assets/js/blocks/product-collection/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss similarity index 100% rename from assets/js/blocks/product-collection/editor.scss rename to assets/js/blocks/product-collection/edit/editor.scss diff --git a/assets/js/blocks/product-collection/edit/index.tsx b/assets/js/blocks/product-collection/edit/index.tsx new file mode 100644 index 00000000000..aad12cc540f --- /dev/null +++ b/assets/js/blocks/product-collection/edit/index.tsx @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { BlockEditProps } from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import type { ProductCollectionAttributes } from '../types'; +import ProductCollectionPlaceholder from './ProductCollectionPlaceholder'; +import ProductCollectionContent from './ProductCollectionContent'; +import './editor.scss'; + +const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { + const { clientId } = props; + + const hasInnerBlocks = useSelect( + ( select ) => + !! select( blockEditorStore ).getBlocks( clientId ).length, + [ clientId ] + ); + + if ( ! hasInnerBlocks ) { + return ; + } + + return ; +}; + +export default Edit; diff --git a/assets/js/blocks/product-collection/inspector-controls/attributes-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/attributes-control.tsx similarity index 97% rename from assets/js/blocks/product-collection/inspector-controls/attributes-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/attributes-control.tsx index f8f08f7aa76..a401aaeb484 100644 --- a/assets/js/blocks/product-collection/inspector-controls/attributes-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/attributes-control.tsx @@ -15,7 +15,7 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; +import { QueryControlProps } from '../../types'; const EDIT_ATTRIBUTES_URL = `${ ADMIN_URL }edit.php?post_type=product&page=product_attributes`; diff --git a/assets/js/blocks/product-collection/inspector-controls/author-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/author-control.tsx similarity index 98% rename from assets/js/blocks/product-collection/inspector-controls/author-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/author-control.tsx index 8fedd27376c..8d9002286e9 100644 --- a/assets/js/blocks/product-collection/inspector-controls/author-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/author-control.tsx @@ -13,7 +13,7 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; +import { QueryControlProps } from '../../types'; interface Author { id: string; diff --git a/assets/js/blocks/product-collection/inspector-controls/columns-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/columns-control.tsx similarity index 91% rename from assets/js/blocks/product-collection/inspector-controls/columns-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/columns-control.tsx index 87e99ddbf79..d824557e6f5 100644 --- a/assets/js/blocks/product-collection/inspector-controls/columns-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/columns-control.tsx @@ -12,8 +12,8 @@ import { /** * Internal dependencies */ -import { DisplayLayoutControlProps } from '../types'; -import { getDefaultDisplayLayout } from '../constants'; +import { DisplayLayoutControlProps } from '../../types'; +import { getDefaultDisplayLayout } from '../../constants'; const ColumnsControl = ( props: DisplayLayoutControlProps ) => { const { type, columns } = props.displayLayout; diff --git a/assets/js/blocks/product-collection/inspector-controls/hand-picked-products-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/hand-picked-products-control.tsx similarity index 98% rename from assets/js/blocks/product-collection/inspector-controls/hand-picked-products-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/hand-picked-products-control.tsx index f95e9ee7653..e8dc6aea27b 100644 --- a/assets/js/blocks/product-collection/inspector-controls/hand-picked-products-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/hand-picked-products-control.tsx @@ -15,7 +15,7 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; +import { QueryControlProps } from '../../types'; /** * Returns: diff --git a/assets/js/blocks/product-collection/inspector-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx similarity index 96% rename from assets/js/blocks/product-collection/inspector-controls/index.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/index.tsx index 78ee38a4059..a6d05e6d966 100644 --- a/assets/js/blocks/product-collection/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx @@ -24,10 +24,10 @@ import { /** * Internal dependencies */ -import metadata from '../block.json'; -import { ProductCollectionAttributes } from '../types'; -import { setQueryAttribute } from '../utils'; -import { DEFAULT_FILTERS, getDefaultSettings } from '../constants'; +import metadata from '../../block.json'; +import { ProductCollectionAttributes } from '../../types'; +import { setQueryAttribute } from '../../utils'; +import { DEFAULT_FILTERS, getDefaultSettings } from '../../constants'; import UpgradeNotice from './upgrade-notice'; import ColumnsControl from './columns-control'; import InheritQueryControl from './inherit-query-control'; diff --git a/assets/js/blocks/product-collection/inspector-controls/inherit-query-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/inherit-query-control.tsx similarity index 93% rename from assets/js/blocks/product-collection/inspector-controls/inherit-query-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/inherit-query-control.tsx index 5091dc185b9..c163abc9ba5 100644 --- a/assets/js/blocks/product-collection/inspector-controls/inherit-query-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/inherit-query-control.tsx @@ -16,9 +16,9 @@ import { /** * Internal dependencies */ -import { ProductCollectionQuery } from '../types'; -import { DEFAULT_QUERY } from '../constants'; -import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; +import { ProductCollectionQuery } from '../../types'; +import { DEFAULT_QUERY } from '../../constants'; +import { getDefaultValueOfInheritQueryFromTemplate } from '../../utils'; const label = __( 'Inherit query from template', diff --git a/assets/js/blocks/product-collection/inspector-controls/keyword-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/keyword-control.tsx similarity index 96% rename from assets/js/blocks/product-collection/inspector-controls/keyword-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/keyword-control.tsx index f1ceccdfe88..7709bd8c042 100644 --- a/assets/js/blocks/product-collection/inspector-controls/keyword-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/keyword-control.tsx @@ -14,7 +14,7 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; +import { QueryControlProps } from '../../types'; const KeywordControl = ( props: QueryControlProps ) => { const { query, setQueryAttribute } = props; diff --git a/assets/js/blocks/product-collection/inspector-controls/on-sale-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/on-sale-control.tsx similarity index 95% rename from assets/js/blocks/product-collection/inspector-controls/on-sale-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/on-sale-control.tsx index d12bf2e00cd..16d4cb2506b 100644 --- a/assets/js/blocks/product-collection/inspector-controls/on-sale-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/on-sale-control.tsx @@ -12,7 +12,7 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; +import { QueryControlProps } from '../../types'; const OnSaleControl = ( props: QueryControlProps ) => { const { query, setQueryAttribute } = props; diff --git a/assets/js/blocks/product-collection/inspector-controls/order-by-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/order-by-control.tsx similarity index 96% rename from assets/js/blocks/product-collection/inspector-controls/order-by-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/order-by-control.tsx index 2c57ecbf9e0..23fa538e0d5 100644 --- a/assets/js/blocks/product-collection/inspector-controls/order-by-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/order-by-control.tsx @@ -16,8 +16,8 @@ import { TProductCollectionOrder, TProductCollectionOrderBy, QueryControlProps, -} from '../types'; -import { getDefaultQuery } from '../constants'; +} from '../../types'; +import { getDefaultQuery } from '../../constants'; const orderOptions = [ { diff --git a/assets/js/blocks/product-collection/inspector-controls/stock-status-control.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/stock-status-control.tsx similarity index 97% rename from assets/js/blocks/product-collection/inspector-controls/stock-status-control.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/stock-status-control.tsx index a1ee7dce2b2..615708047cc 100644 --- a/assets/js/blocks/product-collection/inspector-controls/stock-status-control.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/stock-status-control.tsx @@ -13,8 +13,8 @@ import { /** * Internal dependencies */ -import { QueryControlProps } from '../types'; -import { STOCK_STATUS_OPTIONS, getDefaultStockStatuses } from '../constants'; +import { QueryControlProps } from '../../types'; +import { STOCK_STATUS_OPTIONS, getDefaultStockStatuses } from '../../constants'; /** * Gets the id of a specific stock status from its text label diff --git a/assets/js/blocks/product-collection/inspector-controls/taxonomy-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/taxonomy-controls/index.tsx similarity index 97% rename from assets/js/blocks/product-collection/inspector-controls/taxonomy-controls/index.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/taxonomy-controls/index.tsx index 454b59e97bb..0754a9ca181 100644 --- a/assets/js/blocks/product-collection/inspector-controls/taxonomy-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/taxonomy-controls/index.tsx @@ -15,7 +15,7 @@ import { * Internal dependencies */ import TaxonomyItem from './taxonomy-item'; -import { ProductCollectionQuery } from '../../types'; +import { ProductCollectionQuery } from '../../../types'; interface TaxonomyControlProps { query: ProductCollectionQuery; diff --git a/assets/js/blocks/product-collection/inspector-controls/taxonomy-controls/taxonomy-item.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/taxonomy-controls/taxonomy-item.tsx similarity index 100% rename from assets/js/blocks/product-collection/inspector-controls/taxonomy-controls/taxonomy-item.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/taxonomy-controls/taxonomy-item.tsx diff --git a/assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/upgrade-notice.tsx similarity index 100% rename from assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx rename to assets/js/blocks/product-collection/edit/inspector-controls/upgrade-notice.tsx diff --git a/assets/js/blocks/product-collection/toolbar-controls/display-layout-toolbar.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/display-layout-toolbar.tsx similarity index 97% rename from assets/js/blocks/product-collection/toolbar-controls/display-layout-toolbar.tsx rename to assets/js/blocks/product-collection/edit/toolbar-controls/display-layout-toolbar.tsx index 8732ff03c65..f94b6dc4693 100644 --- a/assets/js/blocks/product-collection/toolbar-controls/display-layout-toolbar.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/display-layout-toolbar.tsx @@ -11,7 +11,7 @@ import { list, grid } from '@wordpress/icons'; import { DisplayLayoutToolbarProps, ProductCollectionDisplayLayout, -} from '../types'; +} from '../../types'; const DisplayLayoutToolbar = ( props: DisplayLayoutToolbarProps ) => { const { type, columns } = props.displayLayout; diff --git a/assets/js/blocks/product-collection/toolbar-controls/display-settings-toolbar.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/display-settings-toolbar.tsx similarity index 98% rename from assets/js/blocks/product-collection/toolbar-controls/display-settings-toolbar.tsx rename to assets/js/blocks/product-collection/edit/toolbar-controls/display-settings-toolbar.tsx index e9c554efede..fbd3402edc0 100644 --- a/assets/js/blocks/product-collection/toolbar-controls/display-settings-toolbar.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/display-settings-toolbar.tsx @@ -16,7 +16,7 @@ import { /** * Internal dependencies */ -import { ProductCollectionQuery } from '../types'; +import { ProductCollectionQuery } from '../../types'; interface DisplaySettingsToolbarProps { query: ProductCollectionQuery; diff --git a/assets/js/blocks/product-collection/toolbar-controls/index.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx similarity index 93% rename from assets/js/blocks/product-collection/toolbar-controls/index.tsx rename to assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx index bb0ab643dc6..0d87fb53ec5 100644 --- a/assets/js/blocks/product-collection/toolbar-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx @@ -8,8 +8,8 @@ import { BlockControls } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { setQueryAttribute } from '../utils'; -import { ProductCollectionAttributes } from '../types'; +import { setQueryAttribute } from '../../utils'; +import { ProductCollectionAttributes } from '../../types'; import DisplaySettingsToolbar from './display-settings-toolbar'; import DisplayLayoutToolbar from './display-layout-toolbar'; import PatternChooserToolbar from './pattern-chooser-toolbar'; diff --git a/assets/js/blocks/product-collection/toolbar-controls/pattern-chooser-toolbar.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-chooser-toolbar.tsx similarity index 100% rename from assets/js/blocks/product-collection/toolbar-controls/pattern-chooser-toolbar.tsx rename to assets/js/blocks/product-collection/edit/toolbar-controls/pattern-chooser-toolbar.tsx diff --git a/assets/js/blocks/product-collection/toolbar-controls/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx similarity index 97% rename from assets/js/blocks/product-collection/toolbar-controls/pattern-selection-modal.tsx rename to assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx index 2601e7f2fb1..043af3a7a15 100644 --- a/assets/js/blocks/product-collection/toolbar-controls/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx @@ -13,7 +13,7 @@ import { type BlockInstance, cloneBlock } from '@wordpress/blocks'; /** * Internal dependencies */ -import { ProductCollectionQuery } from '../types'; +import { ProductCollectionQuery } from '../../types'; const blockName = 'woocommerce/product-collection'; From fe7f5dc3fe2ddda10387e75045857438207ae83a Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:53:20 +0200 Subject: [PATCH 003/111] Use Pattern Selection Modal for both: initial state and later --- .../edit/ProductCollectionContent.tsx | 6 ++-- .../edit/ProductCollectionPlaceholder.tsx | 9 +++-- .../blocks/product-collection/edit/index.tsx | 33 ++++++++++++++++--- .../edit/toolbar-controls/index.tsx | 28 +++------------- assets/js/blocks/product-collection/types.ts | 8 ++++- 5 files changed, 49 insertions(+), 35 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx b/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx index 29d3ad1eeb9..55ae013d51f 100644 --- a/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx +++ b/assets/js/blocks/product-collection/edit/ProductCollectionContent.tsx @@ -2,7 +2,6 @@ * External dependencies */ import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; -import { BlockEditProps } from '@wordpress/blocks'; import { useInstanceId } from '@wordpress/compose'; import { useEffect } from '@wordpress/element'; @@ -12,15 +11,14 @@ import { useEffect } from '@wordpress/element'; import type { ProductCollectionAttributes, ProductCollectionQuery, + QueryEditComponentProps, } from '../types'; import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from '../constants'; import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; import InspectorControls from './inspector-controls'; import ToolbarControls from './toolbar-controls'; -const ProductCollectionContent = ( - props: BlockEditProps< ProductCollectionAttributes > -) => { +const ProductCollectionContent = ( props: QueryEditComponentProps ) => { const { attributes, setAttributes } = props; const { queryId } = attributes; diff --git a/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx b/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx index f215847f8fe..d3614215d58 100644 --- a/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx +++ b/assets/js/blocks/product-collection/edit/ProductCollectionPlaceholder.tsx @@ -9,8 +9,10 @@ import { Placeholder, Button } from '@wordpress/components'; * Internal dependencies */ import Icon from '../icon'; +import type { QueryEditComponentProps } from '../types'; -const QueryPlaceholder = () => { +const QueryPlaceholder = ( props: QueryEditComponentProps ) => { + const { openPatternSelectionModalOpen } = props; const blockProps = useBlockProps(); const tempEventHandler = () => { /** Temp handler */ @@ -29,7 +31,10 @@ const QueryPlaceholder = () => { 'woo-gutenberg-products-block' ) } > - From e5a0313485128ec9ec7b98909f0ff7222021b676 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:43:54 +0200 Subject: [PATCH 005/111] Use default query when choosing pattern for first time --- .../pattern-selection-modal.tsx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx index 043af3a7a15..3d2596c5f67 100644 --- a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx @@ -9,17 +9,36 @@ import { __experimentalBlockPatternsList as BlockPatternsList, } from '@wordpress/block-editor'; import { type BlockInstance, cloneBlock } from '@wordpress/blocks'; +import { isEmpty } from '@woocommerce/types'; /** * Internal dependencies */ import { ProductCollectionQuery } from '../../types'; +import { DEFAULT_QUERY } from '../../constants'; const blockName = 'woocommerce/product-collection'; +const buildQuery = ( + blockQuery: ProductCollectionQuery | undefined, + patternQuery: ProductCollectionQuery +) => { + // If blockQuery is empty, it means it's the initial pattern/collection choice + // and we should use DEFAULT_QUERY as a base for query. + const baseQuery = isEmpty( blockQuery ) ? DEFAULT_QUERY : blockQuery; + const { perPage, offset, pages } = patternQuery; + + return { + ...baseQuery, + perPage, + offset, + pages, + }; +}; + const DisplayLayoutControl = ( props: { clientId: string; - query: ProductCollectionQuery; + query?: ProductCollectionQuery; closePatternSelectionModal: () => void; } ) => { const { clientId, query } = props; @@ -28,13 +47,7 @@ const DisplayLayoutControl = ( props: { const transformBlock = ( block: BlockInstance ): BlockInstance => { const newInnerBlocks = block.innerBlocks.map( transformBlock ); if ( block.name === blockName ) { - const { perPage, offset, pages } = block.attributes.query; - const newQuery = { - ...query, - perPage, - offset, - pages, - }; + const newQuery = buildQuery( query, block.attributes.query ); return cloneBlock( block, { query: newQuery }, newInnerBlocks ); } return cloneBlock( block, {}, newInnerBlocks ); From fbeb50843b61b2caade7913dc874e631758cfca6 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:04:08 +0200 Subject: [PATCH 006/111] Handle the initial inherit attribute value --- .../edit/toolbar-controls/pattern-selection-modal.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx index 3d2596c5f67..e7e36bd4bf1 100644 --- a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx @@ -16,6 +16,7 @@ import { isEmpty } from '@woocommerce/types'; */ import { ProductCollectionQuery } from '../../types'; import { DEFAULT_QUERY } from '../../constants'; +import { getDefaultValueOfInheritQueryFromTemplate } from '../../utils'; const blockName = 'woocommerce/product-collection'; @@ -25,7 +26,12 @@ const buildQuery = ( ) => { // If blockQuery is empty, it means it's the initial pattern/collection choice // and we should use DEFAULT_QUERY as a base for query. - const baseQuery = isEmpty( blockQuery ) ? DEFAULT_QUERY : blockQuery; + const baseQuery = isEmpty( blockQuery ) + ? { + ...DEFAULT_QUERY, + inherit: getDefaultValueOfInheritQueryFromTemplate(), + } + : blockQuery; const { perPage, offset, pages } = patternQuery; return { From 5decf65bc9eb4132f70d156bcec9596a9248b5ae Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:49:51 +0200 Subject: [PATCH 007/111] Provide initial example collection --- .../js/blocks/product-collection/block.json | 3 + .../product-collection/collections/index.ts | 19 ++++ .../collections/new-arrivals.tsx | 90 +++++++++++++++++++ assets/js/blocks/product-collection/index.tsx | 2 + assets/js/blocks/product-collection/types.ts | 2 +- 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 assets/js/blocks/product-collection/collections/index.ts create mode 100644 assets/js/blocks/product-collection/collections/new-arrivals.tsx diff --git a/assets/js/blocks/product-collection/block.json b/assets/js/blocks/product-collection/block.json index 12bbea73722..5023420b314 100644 --- a/assets/js/blocks/product-collection/block.json +++ b/assets/js/blocks/product-collection/block.json @@ -24,6 +24,9 @@ "convertedFromProducts": { "type": "boolean", "default": false + }, + "collection": { + "type": "string" } }, "providesContext": { diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts new file mode 100644 index 00000000000..85175041855 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -0,0 +1,19 @@ +/** + * External dependencies + */ +import { type BlockVariation, registerBlockVariation } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import newArrivals from './new-arrivals'; + +const collections: BlockVariation[] = [ newArrivals ]; + +const registerCollections = () => { + collections.forEach( ( collection ) => { + registerBlockVariation( 'woocommerce/product-collection', collection ); + } ); +}; + +export default registerCollections; diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx new file mode 100644 index 00000000000..f7bb5b8f110 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -0,0 +1,90 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { ImageSizing } from '../../../atomic/blocks/product-elements/image/types'; +import { VARIATION_NAME as PRODUCT_TITLE_ID } from '../variations/elements/product-title'; +import { DEFAULT_ATTRIBUTES } from '../constants'; + +const collection = { + name: 'product-collection__new-arrivals', + title: 'New Arrivals', + icon: , + description: 'Display a grid of your newest products.', +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 5, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + orderBy: 'date', + order: 'desc', + perPage: 10, + pages: 1, + }, + collection: 'woocommerce-blocks/product-collection/new-arrivals', +}; + +const innerBlocks: InnerBlockTemplate[] = [ + [ + 'woocommerce/product-template', + {}, + [ + [ + 'woocommerce/product-image', + { + imageSizing: ImageSizing.THUMBNAIL, + }, + ], + [ + 'core/post-title', + { + textAlign: 'center', + level: 3, + fontSize: 'medium', + style: { + spacing: { + margin: { + bottom: '0.75rem', + top: '0', + }, + }, + }, + isLink: true, + __woocommerceNamespace: PRODUCT_TITLE_ID, + }, + ], + [ + 'woocommerce/product-price', + { + textAlign: 'center', + fontSize: 'small', + }, + ], + [ + 'woocommerce/product-button', + { + textAlign: 'center', + fontSize: 'small', + width: 75, + }, + ], + ], + ], +]; + +export default { + ...collection, + attributes, + innerBlocks, +}; diff --git a/assets/js/blocks/product-collection/index.tsx b/assets/js/blocks/product-collection/index.tsx index 62b9df69dcd..61d7919ec53 100644 --- a/assets/js/blocks/product-collection/index.tsx +++ b/assets/js/blocks/product-collection/index.tsx @@ -12,6 +12,7 @@ import save from './save'; import icon from './icon'; import registerProductSummaryVariation from './variations/elements/product-summary'; import registerProductTitleVariation from './variations/elements/product-title'; +import registerCollections from './collections'; registerBlockType( metadata, { icon, @@ -20,3 +21,4 @@ registerBlockType( metadata, { } ); registerProductSummaryVariation(); registerProductTitleVariation(); +registerCollections(); diff --git a/assets/js/blocks/product-collection/types.ts b/assets/js/blocks/product-collection/types.ts index e2954f3b61d..b64b2b28db9 100644 --- a/assets/js/blocks/product-collection/types.ts +++ b/assets/js/blocks/product-collection/types.ts @@ -1,7 +1,7 @@ /** * External dependencies */ -import { type BlockEditProps } from '@wordpress/blocks'; +import type { BlockEditProps } from '@wordpress/blocks'; import { type AttributeMetadata } from '@woocommerce/types'; export interface ProductCollectionAttributes { From 104bf1f5ea3362998fdb4ef429687753d4b63865 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:04:11 +0200 Subject: [PATCH 008/111] Add isActive function to collections registration --- assets/js/blocks/product-collection/collections/index.ts | 8 +++++++- assets/js/blocks/product-collection/types.ts | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts index 85175041855..81c25a31974 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -12,7 +12,13 @@ const collections: BlockVariation[] = [ newArrivals ]; const registerCollections = () => { collections.forEach( ( collection ) => { - registerBlockVariation( 'woocommerce/product-collection', collection ); + const isActive = ( blockAttrs ) => + blockAttrs.collection === 'product-collection/new-arrivals'; + + registerBlockVariation( 'woocommerce/product-collection', { + isActive, + ...collection, + } ); } ); }; diff --git a/assets/js/blocks/product-collection/types.ts b/assets/js/blocks/product-collection/types.ts index b64b2b28db9..24759184d1d 100644 --- a/assets/js/blocks/product-collection/types.ts +++ b/assets/js/blocks/product-collection/types.ts @@ -16,6 +16,7 @@ export interface ProductCollectionAttributes { displayLayout: ProductCollectionDisplayLayout; tagName: string; convertedFromProducts: boolean; + collection?: string; } export interface ProductCollectionDisplayLayout { From 8fb526fba7387a6b3b185bdcf56537b577de78f4 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:58:42 +0200 Subject: [PATCH 009/111] Treat collections as patterns and display them in inserter --- .../product-collection/collections/index.ts | 2 +- .../collections/new-arrivals.tsx | 2 +- .../pattern-selection-modal.tsx | 63 +++++++++++++++++-- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts index 81c25a31974..8404856ded6 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -13,7 +13,7 @@ const collections: BlockVariation[] = [ newArrivals ]; const registerCollections = () => { collections.forEach( ( collection ) => { const isActive = ( blockAttrs ) => - blockAttrs.collection === 'product-collection/new-arrivals'; + blockAttrs.collection === collection.name; registerBlockVariation( 'woocommerce/product-collection', { isActive, diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index f7bb5b8f110..6949de3a7c9 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -12,7 +12,7 @@ import { VARIATION_NAME as PRODUCT_TITLE_ID } from '../variations/elements/produ import { DEFAULT_ATTRIBUTES } from '../constants'; const collection = { - name: 'product-collection__new-arrivals', + name: 'woocommerce-blocks/product-collection/new-arrivals', title: 'New Arrivals', icon: , description: 'Display a grid of your newest products.', diff --git a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx index e7e36bd4bf1..0b6cbc6e2f6 100644 --- a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx @@ -8,7 +8,14 @@ import { store as blockEditorStore, __experimentalBlockPatternsList as BlockPatternsList, } from '@wordpress/block-editor'; -import { type BlockInstance, cloneBlock } from '@wordpress/blocks'; +import { + type BlockInstance, + store as blocksStore, + cloneBlock, + createBlock, + createBlocksFromInnerBlocksTemplate, + BlockVariation, +} from '@wordpress/blocks'; import { isEmpty } from '@woocommerce/types'; /** @@ -42,6 +49,24 @@ const buildQuery = ( }; }; +const mapCollectionToPattern = ( collection: BlockVariation ) => { + const { name, title, attributes, innerBlocks } = collection; + return { + name, + title, + blockTypes: [ 'woocommerce/product-collection' ], + categories: [ 'woo-commerce' ], + collection: true, + blocks: [ + createBlock( + 'woocommerce/product-collection', + attributes, + createBlocksFromInnerBlocksTemplate( innerBlocks ) + ), + ], + }; +}; + const DisplayLayoutControl = ( props: { clientId: string; query?: ProductCollectionQuery; @@ -50,8 +75,8 @@ const DisplayLayoutControl = ( props: { const { clientId, query } = props; const { replaceBlock, selectBlock } = useDispatch( blockEditorStore ); - const transformBlock = ( block: BlockInstance ): BlockInstance => { - const newInnerBlocks = block.innerBlocks.map( transformBlock ); + const applyQueryToPattern = ( block: BlockInstance ): BlockInstance => { + const newInnerBlocks = block.innerBlocks.map( applyQueryToPattern ); if ( block.name === blockName ) { const newQuery = buildQuery( query, block.attributes.query ); return cloneBlock( block, { query: newQuery }, newInnerBlocks ); @@ -59,6 +84,7 @@ const DisplayLayoutControl = ( props: { return cloneBlock( block, {}, newInnerBlocks ); }; + // Get the Product Collection patterns const blockPatterns = useSelect( ( select ) => { const { getBlockRootClientId, getPatternsByBlockTypes } = @@ -69,8 +95,27 @@ const DisplayLayoutControl = ( props: { [ blockName, clientId ] ); + // Get the Product Collection collections + const blockCollections = useSelect( ( select ) => { + const { getBlockVariations } = select( blocksStore ); + return getBlockVariations( 'woocommerce/product-collection' ); + }, [] ); + + const collectionsAsPatterns = blockCollections.map( + mapCollectionToPattern + ); + const onClickPattern = ( pattern, blocks: BlockInstance[] ) => { - const newBlocks = blocks.map( transformBlock ); + const { collection } = pattern; + + // Collection overrides the current block completely + // so there's no need to apply current query to pattern + if ( collection ) { + replaceBlock( clientId, blocks ); + return; + } + + const newBlocks = blocks.map( applyQueryToPattern ); replaceBlock( clientId, newBlocks ); selectBlock( newBlocks[ 0 ].clientId ); @@ -85,8 +130,14 @@ const DisplayLayoutControl = ( props: { >
From b6636949149a151487623f34a3fc7f20fe2c9515 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:08:53 +0200 Subject: [PATCH 010/111] Add README.md --- .../product-collection/collections/README.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 assets/js/blocks/product-collection/collections/README.md diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md new file mode 100644 index 00000000000..3610b834f89 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/README.md @@ -0,0 +1,26 @@ +# Product Collection - Collections + +Collections are a variations of Product Collection block with the predefined attributes which includes: + +- UI aspect - you can define layout, number of columns etc. +- Query - specify the filters and sorting of the products +- Inner blocks structure - define the Product Template structure + +## Interface + +Collections are in fact Variations and they are registred via Variation API. Hence they should follow the BlockVariation type, providing at least: + +```javascript +{ + name: 'woocommerce-blocks/product-collection/new-arrivals', + title: 'New Arrivals', + icon: , + description: 'Display a grid of your newest products.', + attributes: ProductCollectionAttributes, + innerBlocks: InnerBlockTemplate[] +} +``` + +Please be aware you can specify `isActive` function, but if not, the default one will compare the variation's `name` with `attributes.collection` value. + +As an example please follow `./new-arrivals.tsx`. From 8fa4dd6a0884354fe61663b716d3a1ed53346476 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:23:29 +0200 Subject: [PATCH 011/111] Add logic to include default Product Collection block --- .../edit/product-collection-placeholder.tsx | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index e1e08d77ac7..5b7793f7e43 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -2,20 +2,48 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useBlockProps } from '@wordpress/block-editor'; +import { + store as blockEditorStore, + useBlockProps, +} from '@wordpress/block-editor'; +import { + createBlock, + createBlocksFromInnerBlocksTemplate, +} from '@wordpress/blocks'; import { Placeholder, Button } from '@wordpress/components'; +import { useDispatch } from '@wordpress/data'; /** * Internal dependencies */ import Icon from '../icon'; import type { QueryEditComponentProps } from '../types'; +import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from '../constants'; +import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; + +const getDefaultProductCollection = () => + createBlock( + 'woocommerce/product-collection', + { + ...DEFAULT_ATTRIBUTES, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: getDefaultValueOfInheritQueryFromTemplate(), + }, + }, + createBlocksFromInnerBlocksTemplate( INNER_BLOCKS_TEMPLATE ) + ); const QueryPlaceholder = ( props: QueryEditComponentProps ) => { - const { openPatternSelectionModalOpen } = props; + const { clientId, openPatternSelectionModalOpen } = props; const blockProps = useBlockProps(); - const tempEventHandler = () => { - /** Temp handler */ + + const { replaceBlock } = useDispatch( blockEditorStore ); + // @todo: This is temporary action that will be changed into + // "Add custom collection" + const addDefaultProductCollection = () => { + const defaultProductCollection = getDefaultProductCollection(); + replaceBlock( clientId, defaultProductCollection ); }; return ( @@ -40,9 +68,12 @@ const QueryPlaceholder = ( props: QueryEditComponentProps ) => { 'woo-gutenberg-products-block' ) } - From feddf81e52981c2fcb2812a1ab8711cd1882f15d Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:26:45 +0200 Subject: [PATCH 012/111] Improve the README.md --- .../js/blocks/product-collection/collections/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index 3610b834f89..6a6fc4d6f53 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -10,12 +10,12 @@ Collections are a variations of Product Collection block with the predefined att Collections are in fact Variations and they are registred via Variation API. Hence they should follow the BlockVariation type, providing at least: -```javascript +```typescript { - name: 'woocommerce-blocks/product-collection/new-arrivals', - title: 'New Arrivals', - icon: , - description: 'Display a grid of your newest products.', + name: string; + title: string, + icon: Icon, + description: string, attributes: ProductCollectionAttributes, innerBlocks: InnerBlockTemplate[] } From 2d1b558cc6f610e66f6ad472c2d860ffcacc60ad Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:30:47 +0200 Subject: [PATCH 013/111] Improve the README.md --- assets/js/blocks/product-collection/collections/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index 6a6fc4d6f53..7e28623337f 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -24,3 +24,7 @@ Collections are in fact Variations and they are registred via Variation API. Hen Please be aware you can specify `isActive` function, but if not, the default one will compare the variation's `name` with `attributes.collection` value. As an example please follow `./new-arrivals.tsx`. + +## Registering Collection + +To register collection import it in `./index.ts` file and add to the `collections` array. From 6cec5e040df9e317d261103683cdca6a9ad93730 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:47:24 +0200 Subject: [PATCH 014/111] Preserve the collection attribute --- .../js/blocks/product-collection/edit/index.tsx | 2 +- .../toolbar-controls/pattern-selection-modal.tsx | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/index.tsx b/assets/js/blocks/product-collection/edit/index.tsx index fc6af12d116..41a21513e67 100644 --- a/assets/js/blocks/product-collection/edit/index.tsx +++ b/assets/js/blocks/product-collection/edit/index.tsx @@ -41,7 +41,7 @@ const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { { isPatternSelectionModalOpen && ( setIsPatternSelectionModalOpen( false ) } diff --git a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx index 0b6cbc6e2f6..f4b94ba9047 100644 --- a/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/pattern-selection-modal.tsx @@ -21,7 +21,10 @@ import { isEmpty } from '@woocommerce/types'; /** * Internal dependencies */ -import { ProductCollectionQuery } from '../../types'; +import type { + ProductCollectionQuery, + ProductCollectionAttributes, +} from '../../types'; import { DEFAULT_QUERY } from '../../constants'; import { getDefaultValueOfInheritQueryFromTemplate } from '../../utils'; @@ -69,17 +72,22 @@ const mapCollectionToPattern = ( collection: BlockVariation ) => { const DisplayLayoutControl = ( props: { clientId: string; - query?: ProductCollectionQuery; + attributes: ProductCollectionAttributes; closePatternSelectionModal: () => void; } ) => { - const { clientId, query } = props; + const { clientId, attributes } = props; + const { query } = attributes; const { replaceBlock, selectBlock } = useDispatch( blockEditorStore ); const applyQueryToPattern = ( block: BlockInstance ): BlockInstance => { const newInnerBlocks = block.innerBlocks.map( applyQueryToPattern ); if ( block.name === blockName ) { const newQuery = buildQuery( query, block.attributes.query ); - return cloneBlock( block, { query: newQuery }, newInnerBlocks ); + return cloneBlock( + block, + { query: newQuery, collection: attributes.collection }, + newInnerBlocks + ); } return cloneBlock( block, {}, newInnerBlocks ); }; From 1ac3c57d08e7125f16c94dbf90a0c4faab8e99cd Mon Sep 17 00:00:00 2001 From: Manish Menaria Date: Tue, 19 Sep 2023 12:42:08 +0530 Subject: [PATCH 015/111] Fix typo and update placeholder instruction in product-collection 1. Corrected a typographical error in the `README.md` file, changing "registred" to "registered". 2. Updated the instruction text presented in the `product-collection-placeholder.tsx` file to offer clearer guidance for users. --- assets/js/blocks/product-collection/collections/README.md | 2 +- .../product-collection/edit/product-collection-placeholder.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index 7e28623337f..7e9069a92ff 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -8,7 +8,7 @@ Collections are a variations of Product Collection block with the predefined att ## Interface -Collections are in fact Variations and they are registred via Variation API. Hence they should follow the BlockVariation type, providing at least: +Collections are in fact Variations and they are registered via Variation API. Hence they should follow the BlockVariation type, providing at least: ```typescript { diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 5b7793f7e43..84c1f572469 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -55,7 +55,7 @@ const QueryPlaceholder = ( props: QueryEditComponentProps ) => { 'woo-gutenberg-products-block' ) } instructions={ __( - 'Choose a pattern for the query loop or start blank.', + 'Choose from pre-existing collections or add default one.', 'woo-gutenberg-products-block' ) } > From 76a88a5607eb3a2b6f465c4af6bfe69cc102d951 Mon Sep 17 00:00:00 2001 From: Manish Menaria Date: Tue, 19 Sep 2023 16:20:18 +0530 Subject: [PATCH 016/111] Refactor Product Collection block and update New Arrivals collection - Updated the New Arrivals collection's default attributes to refine the block's appearance and content structure: - Reduced the default number of columns from 5 to 3 - Set the default number of items per page to 9 - Adjusted the collection attribute to reference the collection name dynamically - Replaced the hardcoded inner blocks template with a more dynamic structure, introducing a welcoming message and centralized product template usage - Refactored constants.ts to create distinct inner block templates for product, pagination, and no-results scenarios, enhancing reusability across different collections and improving code readability with descriptive comments Note: The changes aim to streamline the New Arrivals collection setup and facilitate maintainability through a more dynamic and structured approach to inner block templates. --- .../product-collection/collections/index.ts | 14 ++- .../collections/new-arrivals.tsx | 63 +++-------- .../js/blocks/product-collection/constants.ts | 106 ++++++++++-------- 3 files changed, 84 insertions(+), 99 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts index 8404856ded6..8b763e6d7d9 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -1,7 +1,11 @@ /** * External dependencies */ -import { type BlockVariation, registerBlockVariation } from '@wordpress/blocks'; +import { + type BlockVariation, + registerBlockVariation, + BlockAttributes, +} from '@wordpress/blocks'; /** * Internal dependencies @@ -12,8 +16,12 @@ const collections: BlockVariation[] = [ newArrivals ]; const registerCollections = () => { collections.forEach( ( collection ) => { - const isActive = ( blockAttrs ) => - blockAttrs.collection === collection.name; + const isActive = ( + blockAttrs: BlockAttributes, + variationAttributes: BlockAttributes + ) => { + return blockAttrs.collection === variationAttributes.collection; + }; registerBlockVariation( 'woocommerce/product-collection', { isActive, diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index 6949de3a7c9..0ae4b9d83f2 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -7,9 +7,10 @@ import { Icon } from '@wordpress/components'; /** * Internal dependencies */ -import { ImageSizing } from '../../../atomic/blocks/product-elements/image/types'; -import { VARIATION_NAME as PRODUCT_TITLE_ID } from '../variations/elements/product-title'; -import { DEFAULT_ATTRIBUTES } from '../constants'; +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; const collection = { name: 'woocommerce-blocks/product-collection/new-arrivals', @@ -22,65 +23,29 @@ const attributes = { ...DEFAULT_ATTRIBUTES, displayLayout: { type: 'flex', - columns: 5, + columns: 3, }, query: { ...DEFAULT_ATTRIBUTES.query, inherit: false, orderBy: 'date', order: 'desc', - perPage: 10, + perPage: 9, pages: 1, }, - collection: 'woocommerce-blocks/product-collection/new-arrivals', + collection: collection.name, }; const innerBlocks: InnerBlockTemplate[] = [ + [ 'core/heading', { textAlign: 'center', content: 'New Arrivals' } ], [ - 'woocommerce/product-template', - {}, - [ - [ - 'woocommerce/product-image', - { - imageSizing: ImageSizing.THUMBNAIL, - }, - ], - [ - 'core/post-title', - { - textAlign: 'center', - level: 3, - fontSize: 'medium', - style: { - spacing: { - margin: { - bottom: '0.75rem', - top: '0', - }, - }, - }, - isLink: true, - __woocommerceNamespace: PRODUCT_TITLE_ID, - }, - ], - [ - 'woocommerce/product-price', - { - textAlign: 'center', - fontSize: 'small', - }, - ], - [ - 'woocommerce/product-button', - { - textAlign: 'center', - fontSize: 'small', - width: 75, - }, - ], - ], + 'core/paragraph', + { + align: 'center', + content: 'Here are the latest products in our store', + }, ], + INNER_BLOCKS_PRODUCT_TEMPLATE, ]; export default { diff --git a/assets/js/blocks/product-collection/constants.ts b/assets/js/blocks/product-collection/constants.ts index 18c2fbe4949..3339a88d0ab 100644 --- a/assets/js/blocks/product-collection/constants.ts +++ b/assets/js/blocks/product-collection/constants.ts @@ -91,59 +91,71 @@ export const DEFAULT_FILTERS: Partial< ProductCollectionQuery > = { woocommerceHandPickedProducts: [], }; -export const INNER_BLOCKS_TEMPLATE: InnerBlockTemplate[] = [ +/** + * Default inner block templates for the product collection block. + * Exported for use in different collections, e.g., 'New Arrivals' collection. + */ +export const INNER_BLOCKS_PRODUCT_TEMPLATE: InnerBlockTemplate = [ + 'woocommerce/product-template', + {}, [ - 'woocommerce/product-template', - {}, [ - [ - 'woocommerce/product-image', - { - imageSizing: ImageSizing.THUMBNAIL, - }, - ], - [ - 'core/post-title', - { - textAlign: 'center', - level: 3, - fontSize: 'medium', - style: { - spacing: { - margin: { - bottom: '0.75rem', - top: '0', - }, + 'woocommerce/product-image', + { + imageSizing: ImageSizing.THUMBNAIL, + }, + ], + [ + 'core/post-title', + { + textAlign: 'center', + level: 3, + fontSize: 'medium', + style: { + spacing: { + margin: { + bottom: '0.75rem', + top: '0', }, }, - isLink: true, - __woocommerceNamespace: PRODUCT_TITLE_ID, }, - ], - [ - 'woocommerce/product-price', - { - textAlign: 'center', - fontSize: 'small', - }, - ], - [ - 'woocommerce/product-button', - { - textAlign: 'center', - fontSize: 'small', - }, - ], + isLink: true, + __woocommerceNamespace: PRODUCT_TITLE_ID, + }, ], - ], - [ - 'core/query-pagination', - { - layout: { - type: 'flex', - justifyContent: 'center', + [ + 'woocommerce/product-price', + { + textAlign: 'center', + fontSize: 'small', }, - }, + ], + [ + 'woocommerce/product-button', + { + textAlign: 'center', + fontSize: 'small', + }, + ], ], - [ 'core/query-no-results' ], +]; + +export const INNER_BLOCKS_PAGINATION_TEMPLATE: InnerBlockTemplate = [ + 'core/query-pagination', + { + layout: { + type: 'flex', + justifyContent: 'center', + }, + }, +]; + +export const INNER_BLOCKS_NO_RESULTS_TEMPLATE: InnerBlockTemplate = [ + 'core/query-no-results', +]; + +export const INNER_BLOCKS_TEMPLATE: InnerBlockTemplate[] = [ + INNER_BLOCKS_PRODUCT_TEMPLATE, + INNER_BLOCKS_PAGINATION_TEMPLATE, + INNER_BLOCKS_NO_RESULTS_TEMPLATE, ]; From 6ee03ae4d3df9acd9c5ff413d71457814bba3921 Mon Sep 17 00:00:00 2001 From: Manish Menaria Date: Tue, 19 Sep 2023 16:24:55 +0530 Subject: [PATCH 017/111] Refactor: Rename QueryEditComponentProps to ProductCollectionEditComponentProps and update props usage - Renamed the `QueryEditComponentProps` type to `ProductCollectionEditComponentProps` to better match the Product Collection block context. Updated all occurrences in various files to maintain consistency. - Changed `openPatternSelectionModalOpen` prop to `openPatternSelectionModal` to correct the typo and make the naming more intuitive. Updated its usage in different files accordingly. --- assets/js/blocks/product-collection/edit/index.tsx | 2 +- .../edit/product-collection-content.tsx | 6 ++++-- .../edit/product-collection-placeholder.tsx | 9 ++++++--- .../edit/toolbar-controls/index.tsx | 12 +++++++++--- assets/js/blocks/product-collection/types.ts | 4 ++-- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/index.tsx b/assets/js/blocks/product-collection/edit/index.tsx index 41a21513e67..5afe0cda9c7 100644 --- a/assets/js/blocks/product-collection/edit/index.tsx +++ b/assets/js/blocks/product-collection/edit/index.tsx @@ -34,7 +34,7 @@ const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { <> + openPatternSelectionModal={ () => setIsPatternSelectionModalOpen( true ) } /> diff --git a/assets/js/blocks/product-collection/edit/product-collection-content.tsx b/assets/js/blocks/product-collection/edit/product-collection-content.tsx index 55ae013d51f..8eace5c6783 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-content.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-content.tsx @@ -11,14 +11,16 @@ import { useEffect } from '@wordpress/element'; import type { ProductCollectionAttributes, ProductCollectionQuery, - QueryEditComponentProps, + ProductCollectionEditComponentProps, } from '../types'; import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from '../constants'; import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; import InspectorControls from './inspector-controls'; import ToolbarControls from './toolbar-controls'; -const ProductCollectionContent = ( props: QueryEditComponentProps ) => { +const ProductCollectionContent = ( + props: ProductCollectionEditComponentProps +) => { const { attributes, setAttributes } = props; const { queryId } = attributes; diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 84c1f572469..708e400706a 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -17,7 +17,7 @@ import { useDispatch } from '@wordpress/data'; * Internal dependencies */ import Icon from '../icon'; -import type { QueryEditComponentProps } from '../types'; +import type { ProductCollectionEditComponentProps } from '../types'; import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_TEMPLATE } from '../constants'; import { getDefaultValueOfInheritQueryFromTemplate } from '../utils'; @@ -34,8 +34,11 @@ const getDefaultProductCollection = () => createBlocksFromInnerBlocksTemplate( INNER_BLOCKS_TEMPLATE ) ); -const QueryPlaceholder = ( props: QueryEditComponentProps ) => { - const { clientId, openPatternSelectionModalOpen } = props; +const QueryPlaceholder = ( props: ProductCollectionEditComponentProps ) => { + const { + clientId, + openPatternSelectionModal: openPatternSelectionModalOpen, + } = props; const blockProps = useBlockProps(); const { replaceBlock } = useDispatch( blockEditorStore ); diff --git a/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx b/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx index f649a050025..85087f0b61c 100644 --- a/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/toolbar-controls/index.tsx @@ -11,10 +11,16 @@ import { setQueryAttribute } from '../../utils'; import DisplaySettingsToolbar from './display-settings-toolbar'; import DisplayLayoutToolbar from './display-layout-toolbar'; import PatternChooserToolbar from './pattern-chooser-toolbar'; -import type { QueryEditComponentProps } from '../../types'; +import type { ProductCollectionEditComponentProps } from '../../types'; -export default function ToolbarControls( props: QueryEditComponentProps ) { - const { attributes, setAttributes, openPatternSelectionModalOpen } = props; +export default function ToolbarControls( + props: ProductCollectionEditComponentProps +) { + const { + attributes, + setAttributes, + openPatternSelectionModal: openPatternSelectionModalOpen, + } = props; const { query, displayLayout } = attributes; const setQueryAttributeBind = useMemo( diff --git a/assets/js/blocks/product-collection/types.ts b/assets/js/blocks/product-collection/types.ts index 24759184d1d..a4b11449f13 100644 --- a/assets/js/blocks/product-collection/types.ts +++ b/assets/js/blocks/product-collection/types.ts @@ -58,9 +58,9 @@ export interface ProductCollectionQuery { woocommerceHandPickedProducts?: string[]; } -export type QueryEditComponentProps = +export type ProductCollectionEditComponentProps = BlockEditProps< ProductCollectionAttributes > & { - openPatternSelectionModalOpen: () => void; + openPatternSelectionModal: () => void; }; export type TProductCollectionOrder = 'asc' | 'desc'; From 815e6e6bbc91f9c300a40fea621465bbee37cd9b Mon Sep 17 00:00:00 2001 From: Manish Menaria Date: Tue, 19 Sep 2023 16:42:42 +0530 Subject: [PATCH 018/111] Minor improvements --- .../edit/product-collection-placeholder.tsx | 10 ++-------- .../product-collection/edit/toolbar-controls/index.tsx | 8 ++------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 708e400706a..bd759a2f545 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -35,10 +35,7 @@ const getDefaultProductCollection = () => ); const QueryPlaceholder = ( props: ProductCollectionEditComponentProps ) => { - const { - clientId, - openPatternSelectionModal: openPatternSelectionModalOpen, - } = props; + const { clientId, openPatternSelectionModal } = props; const blockProps = useBlockProps(); const { replaceBlock } = useDispatch( blockEditorStore ); @@ -62,10 +59,7 @@ const QueryPlaceholder = ( props: ProductCollectionEditComponentProps ) => { 'woo-gutenberg-products-block' ) } > - From af4c3fdc5f4a9cb19f3527bddb6b66a4d08daec8 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:09:38 +0200 Subject: [PATCH 024/111] Remove unnecessary todo --- .../product-collection/edit/product-collection-placeholder.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 38625265a5a..e8988ebdf78 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -45,8 +45,6 @@ const ProductCollectionPlaceholder = ( // @ts-expect-error Missing types in Gutenberg const { replaceBlock } = useDispatch( blockEditorStore ); - // TODO: This is temporary action that will be changed into - // "Add custom collection" const addDefaultProductCollection = () => { const defaultProductCollection = getDefaultProductCollection(); replaceBlock( clientId, defaultProductCollection ); From 8bce89e05448c870f0ab8ed588f6fd77eaa40dea Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:33:29 +0200 Subject: [PATCH 025/111] Add subtitle to Pattern Chooser modal --- .../product-collection/edit/pattern-selection-modal.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx index a4bda38bdf6..f501e38540a 100644 --- a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx @@ -162,6 +162,12 @@ const PatternSelectionModal = ( props: { isFullScreen >
+

+ { __( + "Pick what products are shown. Don't worry, you can switch and tweak this collection any time.", + 'woo-gutenberg-products-block' + ) } +

Date: Fri, 6 Oct 2023 09:53:19 +0200 Subject: [PATCH 026/111] Add styles to Pattern Chooser modal --- assets/js/blocks/product-collection/edit/editor.scss | 7 +++++++ .../product-collection/edit/pattern-selection-modal.tsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 796c7a23fc9..47dce62fbfd 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -23,4 +23,11 @@ column-count: 1; } } + + .block-editor-block-preview__container { + height: 200px; + align-items: flex-start; + border: 1px solid $input-border-gray; + border-radius: 4px; + } } diff --git a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx index f501e38540a..b9b85114533 100644 --- a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx @@ -162,7 +162,7 @@ const PatternSelectionModal = ( props: { isFullScreen >
-

+

{ __( "Pick what products are shown. Don't worry, you can switch and tweak this collection any time.", 'woo-gutenberg-products-block' From 174515ae727cda3257ff33b07beafc83dbccae61 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 10:11:28 +0200 Subject: [PATCH 027/111] Increase the gap between Product Collection selection modal subtitle anmd content --- assets/js/blocks/product-collection/edit/editor.scss | 4 ++++ .../product-collection/edit/pattern-selection-modal.tsx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 47dce62fbfd..9a014abde7d 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -31,3 +31,7 @@ border-radius: 4px; } } + +.wc-blocks-product-collection__selection-modal-subtitle { + margin-bottom: $gap-large; +} diff --git a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx index b9b85114533..246116429ce 100644 --- a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx @@ -162,7 +162,7 @@ const PatternSelectionModal = ( props: { isFullScreen >

-

+

{ __( "Pick what products are shown. Don't worry, you can switch and tweak this collection any time.", 'woo-gutenberg-products-block' From 0b57b89902b7aed65195a8db4e4ad9508285edb6 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 11:12:53 +0200 Subject: [PATCH 028/111] Add the padding top between Product Collection selection modal previews to give it more space --- assets/js/blocks/product-collection/edit/editor.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 9a014abde7d..9f0cb62f1f4 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -29,6 +29,7 @@ align-items: flex-start; border: 1px solid $input-border-gray; border-radius: 4px; + padding-top: $gap; } } From 6aa517585136fd0c84fe40b3de1bf7637969b456 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:00:57 +0200 Subject: [PATCH 029/111] Adjust Product Collection tests to the new flow --- .../tests/product-collection/product-collection.page.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 01eac81f276..83326fde691 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -68,11 +68,18 @@ class ProductCollectionPage { this.editorUtils = editorUtils; } + async chooseDefaultCollection() { + await this.page + .getByRole( 'button', { name: 'Use default collection' } ) + .click(); + } + async createNewPostAndInsertBlock() { await this.admin.createNewPost( { legacyCanvas: true } ); await this.editor.insertBlock( { name: this.BLOCK_NAME, } ); + await this.chooseDefaultCollection(); await this.refreshLocators( 'editor' ); } @@ -97,6 +104,8 @@ class ProductCollectionPage { 'woocommerce/product-collection' ); + await this.chooseDefaultCollection(); + await this.editor.saveSiteEditorEntities(); } From 1b8bb2f135923ff03739794778b8b5d586aacca4 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:25:35 +0200 Subject: [PATCH 030/111] Adjust Product Collection tests to the new flow --- tests/e2e/tests/product-collection/product-collection.page.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 83326fde691..c4dfc245c1c 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -130,6 +130,7 @@ class ProductCollectionPage { await this.editor.canvas.click( 'body' ); await this.editor.insertBlock( block ); + await this.chooseDefaultCollection(); await this.editor.openDocumentSettingsSidebar(); await this.editor.saveSiteEditorEntities(); } From ddae428fe97d5448af0493f9fdd00cfd71e0e261 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:34:13 +0200 Subject: [PATCH 031/111] Avoid collection items in pattern chooser break between columns --- assets/js/blocks/product-collection/edit/editor.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 9f0cb62f1f4..5e43d89b79a 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -31,6 +31,10 @@ border-radius: 4px; padding-top: $gap; } + + .block-editor-block-patterns-list__list-item { + break-inside: avoid-column; + } } .wc-blocks-product-collection__selection-modal-subtitle { From 264e82e82ef02c73fc0d9c35603e6ec81ce5f6fd Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Tue, 17 Oct 2023 21:34:04 +0200 Subject: [PATCH 032/111] Hide New Arrivals collection from inserter and add keywords --- .../js/blocks/product-collection/collections/new-arrivals.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index b52f13c872e..4dd4ce5ca71 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -17,6 +17,8 @@ const collection = { title: 'New Arrivals', icon: , description: 'Display a grid of your newest products.', + keywords: [ 'newest products' ], + scope: [], }; const attributes = { From 5d54dcbcf7fc95dc5148328ce805d572d1f63969 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:07:05 +0200 Subject: [PATCH 033/111] Rename with containing Pattern Selection Modal as it changes its purpose to Collection Selection Moda;l --- ...ttern-selection-modal.tsx => collection-selection-modal.tsx} | 0 assets/js/blocks/product-collection/edit/index.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename assets/js/blocks/product-collection/edit/{pattern-selection-modal.tsx => collection-selection-modal.tsx} (100%) diff --git a/assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx similarity index 100% rename from assets/js/blocks/product-collection/edit/pattern-selection-modal.tsx rename to assets/js/blocks/product-collection/edit/collection-selection-modal.tsx diff --git a/assets/js/blocks/product-collection/edit/index.tsx b/assets/js/blocks/product-collection/edit/index.tsx index a7edf05d69e..3c7b46ac530 100644 --- a/assets/js/blocks/product-collection/edit/index.tsx +++ b/assets/js/blocks/product-collection/edit/index.tsx @@ -12,7 +12,7 @@ import { useSelect } from '@wordpress/data'; import type { ProductCollectionAttributes } from '../types'; import ProductCollectionPlaceholder from './product-collection-placeholder'; import ProductCollectionContent from './product-collection-content'; -import PatternSelectionModal from './pattern-selection-modal'; +import PatternSelectionModal from './collection-selection-modal'; import './editor.scss'; const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { From 8fc1a976b383217a0429e2cc5a3b5079001a837c Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:50:20 +0200 Subject: [PATCH 034/111] Separate collections and patterns --- .../edit/collection-selection-modal.tsx | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 246116429ce..7b210ec23f2 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -2,18 +2,15 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import { Modal } from '@wordpress/components'; +import { Modal, Button } from '@wordpress/components'; import { isEmpty } from '@woocommerce/types'; import { type BlockInstance, // @ts-expect-error Type definitions for this function are missing in Guteberg store as blocksStore, cloneBlock, - createBlock, - // @ts-expect-error Type definitions for this function are missing in Guteberg - createBlocksFromInnerBlocksTemplate, - BlockVariation, } from '@wordpress/blocks'; /** * External dependencies @@ -61,22 +58,14 @@ const buildFinalQueryFromBlockAndPatternQuery = ( { }; }; -const mapCollectionToPattern = ( collection: BlockVariation ) => { - const { name, title, attributes, innerBlocks } = collection; - return { - name, - title, - blockTypes: [ blockJson.name ], - categories: [ 'WooCommerce' ], - collection: true, - blocks: [ - createBlock( - blockJson.name, - attributes, - createBlocksFromInnerBlocksTemplate( innerBlocks ) - ), - ], - }; +const CollectionButton = ( { active, title, icon, description, onClick } ) => { + const variant = active ? 'primary' : 'secondary'; + + return ( + + ); }; const PatternSelectionModal = ( props: { @@ -131,16 +120,11 @@ const PatternSelectionModal = ( props: { return getBlockVariations( blockJson.name ); }, [] ); - const collectionsAsPatterns = blockCollections.map( - mapCollectionToPattern - ); - - const onClickPattern = ( pattern, blocks: BlockInstance[] ) => { - const { collection } = pattern; - + const applyCollection = () => { + const blocks = []; // Collection overrides the current block completely // so there's no need to apply current query to pattern - if ( collection ) { + if ( chosenCollection ) { replaceBlock( clientId, blocks ); return; } @@ -149,6 +133,13 @@ const PatternSelectionModal = ( props: { replaceBlock( clientId, newBlocks ); }; + const defaultCollection = blockCollections.length + ? blockCollections[ 0 ].name + : ''; + + const [ chosenCollection, selectCollection ] = + useState( defaultCollection ); + return ( - ( + selectCollection( name ) } + /> + ) + ) } + { /* + /> */ } +

+ + +
); From 87b7f14b77b1f3531dd7cca84e3d669be3f697f0 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:51:38 +0200 Subject: [PATCH 035/111] Simplify New Arrivals structure to just Product Collection block Remove surrounding elements from New Arrivals Collection: heading and paragraph --- .../product-collection/collections/new-arrivals.tsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index 4dd4ce5ca71..4a276265b22 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -38,18 +38,7 @@ const attributes = { collection: collection.name, }; -const innerBlocks: InnerBlockTemplate[] = [ - [ 'core/heading', { textAlign: 'center', content: 'New Arrivals' } ], - [ - 'core/paragraph', - { - align: 'center', - content: 'Here are the latest products in our store', - style: { spacing: { margin: { bottom: 'var:preset|spacing|30' } } }, - }, - ], - INNER_BLOCKS_PRODUCT_TEMPLATE, -]; +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; export default { ...collection, From a9b2312bc900ee1409bf98f4a08de0105a3e1763 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:00:22 +0200 Subject: [PATCH 036/111] Add second variation for easier dfevelopment --- .../product-collection/collections/index.ts | 5 +- .../collections/top-sellers.tsx | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 assets/js/blocks/product-collection/collections/top-sellers.tsx diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts index b4c5c27d858..3d77f0b029f 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -10,10 +10,11 @@ import { /** * Internal dependencies */ -import newArrivals from './new-arrivals'; import blockJson from '../block.json'; +import newArrivals from './new-arrivals'; +import topSellers from './top-sellers'; -const collections: BlockVariation[] = [ newArrivals ]; +const collections: BlockVariation[] = [ newArrivals, topSellers ]; const registerCollections = () => { collections.forEach( ( collection ) => { diff --git a/assets/js/blocks/product-collection/collections/top-sellers.tsx b/assets/js/blocks/product-collection/collections/top-sellers.tsx new file mode 100644 index 00000000000..961fd3587a1 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/top-sellers.tsx @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon, trendingUp } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; + +const collection = { + name: 'woocommerce-blocks/product-collection/top-sellers', + title: 'Top Sellers', + icon: , + description: 'Display a grid of the best selling products.', + keywords: [ 'best selling' ], + scope: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 3, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + orderBy: 'popularity', + order: 'desc', + perPage: 9, + pages: 1, + }, + collection: collection.name, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From 18956d4361c486ee2174eedc2061dd2aa77309a7 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:53:30 +0200 Subject: [PATCH 037/111] Add mechanism of choosing particular collection --- .../edit/collection-selection-modal.tsx | 46 +++++++++------ .../product-collection/edit/editor.scss | 59 +++++++++++-------- 2 files changed, 63 insertions(+), 42 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 7b210ec23f2..69cab9978ff 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -11,6 +11,9 @@ import { // @ts-expect-error Type definitions for this function are missing in Guteberg store as blocksStore, cloneBlock, + createBlock, + // @ts-expect-error Type definitions for this function are missing in Guteberg + createBlocksFromInnerBlocksTemplate, } from '@wordpress/blocks'; /** * External dependencies @@ -120,26 +123,33 @@ const PatternSelectionModal = ( props: { return getBlockVariations( blockJson.name ); }, [] ); + const defaultCollection = blockCollections.length + ? blockCollections[ 0 ].name + : ''; + + const [ chosenCollectionName, selectCollectionName ] = + useState( defaultCollection ); + const applyCollection = () => { - const blocks = []; + const chosenCollection = blockCollections.find( + ( { name } ) => name === chosenCollectionName + ); + // Collection overrides the current block completely // so there's no need to apply current query to pattern if ( chosenCollection ) { - replaceBlock( clientId, blocks ); - return; - } + const newBlock = createBlock( + blockJson.name, + chosenCollection.attributes, + createBlocksFromInnerBlocksTemplate( + chosenCollection.innerBlocks + ) + ); - const newBlocks = blocks.map( updateQueryAttributeOfPattern ); - replaceBlock( clientId, newBlocks ); + replaceBlock( clientId, newBlock ); + } }; - const defaultCollection = blockCollections.length - ? blockCollections[ 0 ].name - : ''; - - const [ chosenCollection, selectCollection ] = - useState( defaultCollection ); - return ( -
-

+

+

{ __( "Pick what products are shown. Don't worry, you can switch and tweak this collection any time.", 'woo-gutenberg-products-block' @@ -162,12 +172,12 @@ const PatternSelectionModal = ( props: { { blockCollections.map( ( { name, title, icon, description } ) => ( selectCollection( name ) } + onClick={ () => selectCollectionName( name ) } /> ) ) } @@ -176,7 +186,7 @@ const PatternSelectionModal = ( props: { shownPatterns={ blockPatterns } onClickPattern={ onClickPattern } /> */ } -

+
); @@ -118,6 +116,8 @@ const PatternSelectionModal = ( props: { [ blockJson.name, clientId ] ); + // const [ chosenPatternName, selectPatternName ] = useState( '' ); + // Get Collections const blockCollections = useSelect( ( select ) => { // @ts-expect-error Type definitions are missing @@ -126,6 +126,7 @@ const PatternSelectionModal = ( props: { return getBlockVariations( blockJson.name ); }, [] ); + // Prepare Collections const defaultCollection = blockCollections.length ? blockCollections[ 0 ].name : ''; @@ -172,23 +173,41 @@ const PatternSelectionModal = ( props: { 'woo-gutenberg-products-block' ) }

- { blockCollections.map( - ( { name, title, icon, description } ) => ( - selectCollectionName( name ) } - /> - ) - ) } - { /* */ } +
+ { blockCollections.map( + ( { name, title, icon, description } ) => ( + selectCollectionName( name ) } + /> + ) + ) } +
+
+

+ { __( + 'Choose a pattern.', + 'woo-gutenberg-products-block' + ) } +

+

+ { __( + 'Patterns are a great starting point that you can customise later.', + 'woo-gutenberg-products-block' + ) } +

+ + selectPatternName( name ) + } + /> +
); }; @@ -63,7 +76,7 @@ const defaultQuery = { name: 'woocommerce-blocks/product-collection/default-query', title: 'Default Query', icon: , - description: 'Use the current query context set by template', + description: 'Use the current query context set by template.', innerBlocks: [ INNER_BLOCKS_PRODUCT_TEMPLATE ], attributes: { ...DEFAULT_ATTRIBUTES, @@ -109,6 +122,7 @@ const PatternSelectionModal = ( props: { return getBlockVariations( blockJson.name ); }, [] ), defaultQuery, + defaultQuery, ]; // Prepare Collections diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 04546fa9c79..55604869e21 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -35,6 +35,30 @@ .block-editor-block-patterns-list__list-item { break-inside: avoid-column; } + + .wc-blocks-product-collection__collection-button { + display: flex; + align-items: flex-start; + height: auto; + + .wc-blocks-product-collection__collection-button-icon { + margin: 1em 0; + } + + .wc-blocks-product-collection__collection-button-text { + padding: 0 $gap-small; + text-align: left; + } + + .wc-blocks-product-collection__collection-button-title { + @include font-size(large); + line-height: 1; + } + + .wc-blocks-product-collection__collection-button-description { + white-space: wrap; + } + } } .wc-blocks-product-collection__selection-modal-subtitle { @@ -42,7 +66,12 @@ } .wc-blocks-product-collection__collections-section { - min-height: 200px; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-auto-rows: 1fr; + gap: $gap-small; + margin: $gap-small auto; + max-width: 1000px; } .wc-blocks-product-collection__patterns-section { From 9e58e9aaa8d8d9c1d15c19ea3fcdf69d6ccab683 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 11:50:27 +0100 Subject: [PATCH 043/111] Change margins of Collection button section --- assets/js/blocks/product-collection/edit/editor.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 55604869e21..c9c4810915c 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -70,7 +70,7 @@ grid-template-columns: 1fr 1fr 1fr; grid-auto-rows: 1fr; gap: $gap-small; - margin: $gap-small auto; + margin: $gap-large auto $gap-largest; max-width: 1000px; } From 71e185b15830d214cb5bc948cc76ebd59f34b398 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 11:59:49 +0100 Subject: [PATCH 044/111] Add Best Sellers collection --- .../collections/best-sellers.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 assets/js/blocks/product-collection/collections/best-sellers.tsx diff --git a/assets/js/blocks/product-collection/collections/best-sellers.tsx b/assets/js/blocks/product-collection/collections/best-sellers.tsx new file mode 100644 index 00000000000..e878ec124dc --- /dev/null +++ b/assets/js/blocks/product-collection/collections/best-sellers.tsx @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon, starEmpty } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; + +const collection = { + name: 'woocommerce-blocks/product-collection/best-sellers', + title: 'Best Sellers', + icon: , + description: 'Display a grid of the best selling products.', + keywords: [ 'best selling' ], + scope: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 3, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + orderBy: 'popularity', + order: 'desc', + perPage: 9, + pages: 1, + }, + collection: collection.name, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From 2009efd6d70743763fc1d2f2c74e194fa308e4ee Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 11:59:59 +0100 Subject: [PATCH 045/111] Add Featured collection --- .../collections/featured.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 assets/js/blocks/product-collection/collections/featured.tsx diff --git a/assets/js/blocks/product-collection/collections/featured.tsx b/assets/js/blocks/product-collection/collections/featured.tsx new file mode 100644 index 00000000000..6f829cbb31f --- /dev/null +++ b/assets/js/blocks/product-collection/collections/featured.tsx @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon, starFilled } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; + +const collection = { + name: 'woocommerce-blocks/product-collection/featured', + title: 'Featured', + icon: , + description: 'Products that have been marked as featured.', + keywords: [ 'best selling' ], + scope: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 3, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + featured: true, + perPage: 9, + pages: 1, + }, + collection: collection.name, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From ad52a498b2dbc56a916d34dca8176c4fb9feb193 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:00:08 +0100 Subject: [PATCH 046/111] Add On Sale collection --- .../collections/on-sale.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 assets/js/blocks/product-collection/collections/on-sale.tsx diff --git a/assets/js/blocks/product-collection/collections/on-sale.tsx b/assets/js/blocks/product-collection/collections/on-sale.tsx new file mode 100644 index 00000000000..ef7bb4c0a73 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/on-sale.tsx @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon, percent } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; + +const collection = { + name: 'woocommerce-blocks/product-collection/on-sale', + title: 'On Sale', + icon: , + description: 'Products currently marked on sale.', + keywords: [], + scope: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 3, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + woocommerceOnSale: true, + perPage: 9, + pages: 1, + }, + collection: collection.name, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From 10360a124dbfd675724d7fa6098030281f54f554 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:00:23 +0100 Subject: [PATCH 047/111] Remove Top Sellers collection --- .../collections/top-sellers.tsx | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/js/blocks/product-collection/collections/top-sellers.tsx diff --git a/assets/js/blocks/product-collection/collections/top-sellers.tsx b/assets/js/blocks/product-collection/collections/top-sellers.tsx deleted file mode 100644 index 6582adcd495..00000000000 --- a/assets/js/blocks/product-collection/collections/top-sellers.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/** - * External dependencies - */ -import { InnerBlockTemplate } from '@wordpress/blocks'; -import { Icon, starEmpty } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import { - DEFAULT_ATTRIBUTES, - INNER_BLOCKS_PRODUCT_TEMPLATE, -} from '../constants'; - -const collection = { - name: 'woocommerce-blocks/product-collection/top-sellers', - title: 'Top Sellers', - icon: , - description: 'Display a grid of the best selling products.', - keywords: [ 'best selling' ], - scope: [], -}; - -const attributes = { - ...DEFAULT_ATTRIBUTES, - displayLayout: { - type: 'flex', - columns: 3, - }, - query: { - ...DEFAULT_ATTRIBUTES.query, - inherit: false, - orderBy: 'popularity', - order: 'desc', - perPage: 9, - pages: 1, - }, - collection: collection.name, -}; - -const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; - -export default { - ...collection, - attributes, - innerBlocks, -}; From f2e27fe1433a85c735a266df8ec9737db3bf62e7 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:00:53 +0100 Subject: [PATCH 048/111] Add Top Rated collection --- .../collections/top-rated.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 assets/js/blocks/product-collection/collections/top-rated.tsx diff --git a/assets/js/blocks/product-collection/collections/top-rated.tsx b/assets/js/blocks/product-collection/collections/top-rated.tsx new file mode 100644 index 00000000000..1f26729516b --- /dev/null +++ b/assets/js/blocks/product-collection/collections/top-rated.tsx @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { Icon, starEmpty } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; + +const collection = { + name: 'woocommerce-blocks/product-collection/top-rated', + title: 'Top Rated', + icon: , + description: 'Products gaining popularity based on recent activity.', + keywords: [], + scope: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + displayLayout: { + type: 'flex', + columns: 3, + }, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: false, + orderBy: 'rating', + order: 'desc', + perPage: 9, + pages: 1, + }, + collection: collection.name, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From 07f824db5cb859b9f1866e911cb1b85bcdd1899b Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:01:25 +0100 Subject: [PATCH 049/111] Remove fake default query collection --- .../product-collection/edit/collection-selection-modal.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 23fafd4795b..988aaf05c15 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -122,7 +122,6 @@ const PatternSelectionModal = ( props: { return getBlockVariations( blockJson.name ); }, [] ), defaultQuery, - defaultQuery, ]; // Prepare Collections From 8dee843015fe9af9df15f6f126a3cce21141ae40 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:01:41 +0100 Subject: [PATCH 050/111] Register all the new collections --- .../blocks/product-collection/collections/index.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.ts index 3d77f0b029f..c940ce46bba 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.ts @@ -12,9 +12,18 @@ import { */ import blockJson from '../block.json'; import newArrivals from './new-arrivals'; -import topSellers from './top-sellers'; +import topRated from './top-rated'; +import bestSellers from './best-sellers'; +import onSale from './on-sale'; +import featured from './featured'; -const collections: BlockVariation[] = [ newArrivals, topSellers ]; +const collections: BlockVariation[] = [ + newArrivals, + topRated, + bestSellers, + onSale, + featured, +]; const registerCollections = () => { collections.forEach( ( collection ) => { From b633f9694c33e494fb252075ae4da836588e4eb8 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:20:22 +0100 Subject: [PATCH 051/111] Fix incorrect import --- .../product-collection/edit/product-collection-placeholder.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 91aeddc6431..eb34ac941ae 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -13,7 +13,7 @@ import { useDispatch } from '@wordpress/data'; * Internal dependencies */ import type { ProductCollectionEditComponentProps } from '../types'; -import { getDefaultProductCollection } from '../utils'; +import { getDefaultProductCollection } from '../constants'; import Icon from '../icon'; const ProductCollectionPlaceholder = ( From 3248853b60e17c43bf3d00f2f7f3af24a79c74fc Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:22:39 +0100 Subject: [PATCH 052/111] Add logic to choose highlighted collection --- .../edit/collection-selection-modal.tsx | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 988aaf05c15..661e59ee159 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -87,12 +87,30 @@ const defaultQuery = { }, }; +const getDefaultChosenCollection = ( + attributes: ProductCollectionAttributes, + // @ts-expect-error Type definitions are missing + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts + blockCollections +) => { + // If `attributes.query` is truthy, that means Product Collection was already + // configured. So it's either a collection or we need to return defaultQuery + // collection name; + if ( attributes.query ) { + return attributes.collection || defaultQuery.name; + } + + // Otherwise it should be the first available choice. We control collections + // so there always should be at least one available. + return blockCollections.length ? blockCollections[ 0 ].name : ''; +}; + const PatternSelectionModal = ( props: { clientId: string; attributes: ProductCollectionAttributes; closePatternSelectionModal: () => void; } ) => { - const { clientId } = props; + const { clientId, attributes } = props; // @ts-expect-error Type definitions for this function are missing // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/actions.d.ts const { replaceBlock } = useDispatch( blockEditorStore ); @@ -125,12 +143,14 @@ const PatternSelectionModal = ( props: { ]; // Prepare Collections - const defaultCollection = blockCollections.length - ? blockCollections[ 0 ].name - : ''; + const defaultChosenCollection = getDefaultChosenCollection( + attributes, + blockCollections + ); - const [ chosenCollectionName, selectCollectionName ] = - useState( defaultCollection ); + const [ chosenCollectionName, selectCollectionName ] = useState( + defaultChosenCollection + ); const applyCollection = () => { const chosenCollection = blockCollections.find( From d37c041d2e73998c2de29f14d4bdfe0cb911c873 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:38:38 +0100 Subject: [PATCH 053/111] Improve Collection buttons styling --- .../collections/best-sellers.tsx | 4 ++-- .../blocks/product-collection/edit/editor.scss | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/best-sellers.tsx b/assets/js/blocks/product-collection/collections/best-sellers.tsx index e878ec124dc..867527411b4 100644 --- a/assets/js/blocks/product-collection/collections/best-sellers.tsx +++ b/assets/js/blocks/product-collection/collections/best-sellers.tsx @@ -2,7 +2,7 @@ * External dependencies */ import { InnerBlockTemplate } from '@wordpress/blocks'; -import { Icon, starEmpty } from '@wordpress/icons'; +import { Icon, chartBar } from '@wordpress/icons'; /** * Internal dependencies @@ -15,7 +15,7 @@ import { const collection = { name: 'woocommerce-blocks/product-collection/best-sellers', title: 'Best Sellers', - icon: , + icon: , description: 'Display a grid of the best selling products.', keywords: [ 'best selling' ], scope: [], diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index c9c4810915c..50981932dc1 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -37,9 +37,27 @@ } .wc-blocks-product-collection__collection-button { + color: inherit; display: flex; align-items: flex-start; height: auto; + border: 1px solid $input-border-gray; + border-radius: $universal-border-radius; + box-sizing: border-box; + box-shadow: none; + padding: $gap-smallest $gap-small; + + &.is-primary { + border: 2px solid var(--wp-admin-theme-color-darker-10, #3858e9); + background-color: #fff; + color: inherit; + margin: -1px; + + &:hover { + background-color: #fff; + color: inherit; + } + } .wc-blocks-product-collection__collection-button-icon { margin: 1em 0; From 8d6abb6fb7836dc80f479ad83c837fcc6a2884e2 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:47:40 +0100 Subject: [PATCH 054/111] Improve Pattern Chooser styling --- .../edit/collection-selection-modal.tsx | 1 + .../product-collection/edit/editor.scss | 22 +++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 661e59ee159..2b7963ebdd0 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -220,6 +220,7 @@ const PatternSelectionModal = ( props: { ) }

diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 50981932dc1..d75c9f9a7b5 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -12,16 +12,12 @@ .wc-blocks-product-collection__selection-modal { .block-editor-block-patterns-list { - column-count: 3; - column-gap: $grid-unit-30; - - @include breakpoint("<1280px") { - column-count: 2; - } - - @include breakpoint("<782px") { - column-count: 1; - } + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-auto-rows: 1fr; + gap: $gap-small; + margin: $gap-large auto $gap-largest; + max-width: 1200px; } .block-editor-block-preview__container { @@ -49,13 +45,13 @@ &.is-primary { border: 2px solid var(--wp-admin-theme-color-darker-10, #3858e9); + color: var(--wp-admin-theme-color-darker-10); background-color: #fff; - color: inherit; margin: -1px; &:hover { background-color: #fff; - color: inherit; + color: var(--wp-admin-theme-color-darker-10); } } @@ -93,9 +89,7 @@ } .wc-blocks-product-collection__patterns-section { - min-height: 200px; background-color: $gray-100; - // @todo: Fix the hardcoded -32px value. margin: 0 -32px; padding: 32px; } From 2faeccd483fff987a38952f692f18e0d59f11ab3 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:10:03 +0100 Subject: [PATCH 055/111] Add styles to Modal buttons --- .../product-collection/edit/collection-selection-modal.tsx | 2 +- assets/js/blocks/product-collection/edit/editor.scss | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 2b7963ebdd0..60b60974212 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -175,7 +175,7 @@ const PatternSelectionModal = ( props: { return ( Date: Thu, 9 Nov 2023 16:49:30 +0100 Subject: [PATCH 056/111] Merge Collections and Patterns --- .../edit/collection-selection-modal.tsx | 58 ++++++++++++++++--- .../product-collection/edit/editor.scss | 4 -- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 60b60974212..f079b8ed890 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -82,7 +82,6 @@ const defaultQuery = { ...DEFAULT_ATTRIBUTES, query: { ...DEFAULT_ATTRIBUTES.query, - inherit: getDefaultValueOfInheritQueryFromTemplate(), // TODO: This has to be resolved when applying the collection, so the context is known. }, }, }; @@ -105,6 +104,16 @@ const getDefaultChosenCollection = ( return blockCollections.length ? blockCollections[ 0 ].name : ''; }; +const findProductCollectionBlock = ( blocks ) => { + return blocks.find( ( block ) => { + const isProductCollection = + block.name === 'woocommerce/product-collection'; + return isProductCollection + ? block + : findProductCollectionBlock( block.innerBlocks ); + } ); +}; + const PatternSelectionModal = ( props: { clientId: string; attributes: ProductCollectionAttributes; @@ -156,20 +165,55 @@ const PatternSelectionModal = ( props: { const chosenCollection = blockCollections.find( ( { name }: { name: string } ) => name === chosenCollectionName ); - const chosenPattern = blockPatterns.find( ( { name }: { name: string } ) => name === chosenPatternName ); + if ( + chosenCollection.name === + 'woocommerce-blocks/product-collection/default-query' + ) { + chosenCollection.attributes.query.inherit = + getDefaultValueOfInheritQueryFromTemplate(); + } + + if ( ! chosenPattern ) { + const newBlock = createBlock( + blockJson.name, + chosenCollection.attributes, + createBlocksFromInnerBlocksTemplate( + chosenCollection.innerBlocks + ) + ); + + replaceBlock( clientId, newBlock ); + return; + } + + const { innerBlocks, attributes: patternAttributes } = + findProductCollectionBlock( chosenPattern.blocks ); + const { + displayLayout, + query: { perPage, pages, offset }, + } = patternAttributes; + + const mergedAttributes = { + ...chosenCollection.attributes, + displayLayout, + query: { + ...chosenCollection.attributes.query, + perPage, + pages, + offset, + }, + }; + const newBlock = createBlock( blockJson.name, - chosenCollection.attributes, - createBlocksFromInnerBlocksTemplate( chosenCollection.innerBlocks ) + mergedAttributes, + createBlocksFromInnerBlocksTemplate( innerBlocks ) ); - // TODO: Need to apply pattern attributes and inner blocks structure - // to the new Collection from a chosenPattern. - replaceBlock( clientId, newBlock ); }; diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index a3be309523e..ce8c8ca80f5 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -28,10 +28,6 @@ padding-top: $gap; } - .block-editor-block-patterns-list__list-item { - break-inside: avoid-column; - } - .wc-blocks-product-collection__collection-button { color: inherit; display: flex; From b64502f6c9d9818c1a7908037374ababd906ec40 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:21:28 +0100 Subject: [PATCH 057/111] Remove Pattern Chooser - visual part --- .../edit/collection-selection-modal.tsx | 29 +------------------ .../product-collection/edit/editor.scss | 23 --------------- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index f079b8ed890..ba374041fe6 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -16,12 +16,7 @@ import { /** * External dependencies */ -import { - store as blockEditorStore, - // @ts-expect-error Using experimental features - // eslint-disable-next-line @wordpress/no-unsafe-wp-apis - __experimentalBlockPatternsList as BlockPatternsList, -} from '@wordpress/block-editor'; +import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies @@ -250,28 +245,6 @@ const PatternSelectionModal = ( props: { ) ) }
-
-

- { __( - 'Choose a pattern', - 'woo-gutenberg-products-block' - ) } -

-

- { __( - 'Patterns are a great starting point that you can customise later.', - 'woo-gutenberg-products-block' - ) } -

- - selectPatternName( name ) - } - /> -
@@ -53,10 +53,7 @@ const ProductCollectionPlaceholder = ( variant="tertiary" onClick={ addDefaultProductCollection } > - { __( - 'Use default collection', - 'woo-gutenberg-products-block' - ) } + { __( 'Create custom', 'woo-gutenberg-products-block' ) }
diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 4766ffdc4ee..8fc3b654c15 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -90,11 +90,11 @@ class ProductCollectionPage { async chooseCollectionInPost( collection?: Collections ) { if ( ! collection ) { await this.admin.page - .getByRole( 'button', { name: 'Use default collection' } ) + .getByRole( 'button', { name: 'Create custom' } ) .click(); } else { await this.admin.page - .getByRole( 'button', { name: 'Choose Collection' } ) + .getByRole( 'button', { name: 'Choose collection' } ) .click(); await this.admin.page.waitForSelector( @@ -116,12 +116,12 @@ class ProductCollectionPage { if ( ! collection ) { await this.admin.page .frameLocator( 'iframe[name="editor-canvas"]' ) - .getByRole( 'button', { name: 'Use default collection' } ) + .getByRole( 'button', { name: 'Create custom' } ) .click(); } else { await this.admin.page .frameLocator( 'iframe[name="editor-canvas"]' ) - .getByRole( 'button', { name: 'Choose Collection' } ) + .getByRole( 'button', { name: 'Choose collection' } ) .click(); await this.admin.page.waitForSelector( From 78dacf220a73570cbacffa9b8eb33d1a122007a0 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:03:09 +0100 Subject: [PATCH 090/111] Move defaultQuery to collections directory so the name property can be reused --- .../collections/{index.ts => index.tsx} | 9 +++++++++ .../edit/collection-selection-modal.tsx | 10 +--------- .../edit/inspector-controls/index.tsx | 6 +++++- 3 files changed, 15 insertions(+), 10 deletions(-) rename assets/js/blocks/product-collection/collections/{index.ts => index.tsx} (74%) diff --git a/assets/js/blocks/product-collection/collections/index.ts b/assets/js/blocks/product-collection/collections/index.tsx similarity index 74% rename from assets/js/blocks/product-collection/collections/index.ts rename to assets/js/blocks/product-collection/collections/index.tsx index e9e782f52ce..b8e0c8dc8bc 100644 --- a/assets/js/blocks/product-collection/collections/index.ts +++ b/assets/js/blocks/product-collection/collections/index.tsx @@ -6,6 +6,7 @@ import { registerBlockVariation, BlockAttributes, } from '@wordpress/blocks'; +import { Icon, loop } from '@wordpress/icons'; /** * Internal dependencies @@ -17,6 +18,14 @@ import bestSellers from './best-sellers'; import onSale from './on-sale'; import featured from './featured'; +export const defaultQuery = { + name: 'woocommerce-blocks/product-collection/default-query', + title: 'All Products', + icon: , + description: + 'Display all products. Results may be limited by the current template context.', +}; + const collections: BlockVariation[] = [ featured, topRated, diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index 2dc77ef9e91..f07ba249e86 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -5,7 +5,6 @@ import { __ } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { Modal, Button } from '@wordpress/components'; -import { Icon, loop } from '@wordpress/icons'; import { // @ts-expect-error Type definitions for this function are missing in Guteberg store as blocksStore, @@ -24,6 +23,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import type { ProductCollectionAttributes } from '../types'; import { getDefaultProductCollection } from '../constants'; import blockJson from '../block.json'; +import { defaultQuery } from '../collections'; type CollectionButtonProps = { active: boolean; @@ -63,14 +63,6 @@ const CollectionButton = ( { ); }; -const defaultQuery = { - name: 'woocommerce-blocks/product-collection/default-query', - title: 'All Products', - icon: , - description: - 'Display all products in your catalog. Results may change to match the current template, page, or search term.', -}; - const getDefaultChosenCollection = ( attributes: ProductCollectionAttributes, // @ts-expect-error Type definitions are missing diff --git a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx index b99025b64c6..56a724b2c35 100644 --- a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx @@ -28,6 +28,7 @@ import metadata from '../../block.json'; import { ProductCollectionAttributes } from '../../types'; import { setQueryAttribute } from '../../utils'; import { DEFAULT_FILTERS, getDefaultSettings } from '../../constants'; +import { defaultQuery } from '../../collections'; import UpgradeNotice from './upgrade-notice'; import ColumnsControl from './columns-control'; import InheritQueryControl from './inherit-query-control'; @@ -47,7 +48,10 @@ const ProductCollectionInspectorControls = ( ) => { const { query, collection } = props.attributes; const inherit = query?.inherit; - const displayInheritQueryControls = isEmpty( collection ); + // To be changed - inherit control will be hidden completely once Custom + // collection is introduced + const displayInheritQueryControls = + isEmpty( collection ) || collection === defaultQuery.name; const displayQueryControls = inherit === false; const setQueryAttributeBind = useMemo( From 89064e5c736de3b2cfd80b5af312fd0388fd171d Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:32:47 +0100 Subject: [PATCH 091/111] Initial implementation of hiding filters per collection --- .../product-collection/collections/index.tsx | 17 +++++-- .../edit/collection-selection-modal.tsx | 6 +-- .../edit/inspector-controls/index.tsx | 46 +++++++++++++++++-- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/index.tsx b/assets/js/blocks/product-collection/collections/index.tsx index b8e0c8dc8bc..39814dfefc0 100644 --- a/assets/js/blocks/product-collection/collections/index.tsx +++ b/assets/js/blocks/product-collection/collections/index.tsx @@ -18,7 +18,7 @@ import bestSellers from './best-sellers'; import onSale from './on-sale'; import featured from './featured'; -export const defaultQuery = { +const defaultQuery = { name: 'woocommerce-blocks/product-collection/default-query', title: 'All Products', icon: , @@ -26,7 +26,16 @@ export const defaultQuery = { 'Display all products. Results may be limited by the current template context.', }; -const collections: BlockVariation[] = [ +export const collections = { + newArrivals, + topRated, + bestSellers, + onSale, + featured, + defaultQuery, +}; + +const collectionsArray: BlockVariation[] = [ featured, topRated, onSale, @@ -34,8 +43,8 @@ const collections: BlockVariation[] = [ newArrivals, ]; -const registerCollections = () => { - collections.forEach( ( collection ) => { +export const registerCollections = () => { + collectionsArray.forEach( ( collection ) => { const isActive = ( blockAttrs: BlockAttributes, variationAttributes: BlockAttributes diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index f07ba249e86..f2721eb0c4d 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -23,7 +23,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import type { ProductCollectionAttributes } from '../types'; import { getDefaultProductCollection } from '../constants'; import blockJson from '../block.json'; -import { defaultQuery } from '../collections'; +import { collections } from '../collections'; type CollectionButtonProps = { active: boolean; @@ -73,7 +73,7 @@ const getDefaultChosenCollection = ( // configured. So it's either a collection or we need to return defaultQuery // collection name; if ( attributes.query ) { - return attributes.collection || defaultQuery.name; + return attributes.collection || collections.defaultQuery.name; } // Otherwise it should be the first available choice. We control collections @@ -93,7 +93,7 @@ const PatternSelectionModal = ( props: { // Get Collections const blockCollections = [ - defaultQuery, + collections.defaultQuery, ...useSelect( ( select ) => { // @ts-expect-error Type definitions are missing // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts diff --git a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx index 56a724b2c35..c2c6844ba8e 100644 --- a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx @@ -28,7 +28,7 @@ import metadata from '../../block.json'; import { ProductCollectionAttributes } from '../../types'; import { setQueryAttribute } from '../../utils'; import { DEFAULT_FILTERS, getDefaultSettings } from '../../constants'; -import { defaultQuery } from '../../collections'; +import { collections } from '../../collections'; import UpgradeNotice from './upgrade-notice'; import ColumnsControl from './columns-control'; import InheritQueryControl from './inherit-query-control'; @@ -43,6 +43,35 @@ import LayoutOptionsControl from './layout-options-control'; import FeaturedProductsControl from './featured-products-control'; import CreatedControl from './created-control'; +const shouldDisplayOrderBy = ( collection?: string ) => { + if ( ! collection ) { + return true; + } + + const collectionsToHideOrderBy = [ + collections.bestSellers.name, + collections.newArrivals.name, + collections.topRated.name, + ]; + return ! collectionsToHideOrderBy.includes( collection ); +}; + +const shouldDisplayFeatured = ( collection?: string ) => { + if ( ! collection ) { + return true; + } + + return collection !== collections.featured.name; +}; + +const shouldDisplayOnSale = ( collection?: string ) => { + if ( ! collection ) { + return true; + } + + return collection !== collections.onSale.name; +}; + const ProductCollectionInspectorControls = ( props: BlockEditProps< ProductCollectionAttributes > ) => { @@ -51,8 +80,11 @@ const ProductCollectionInspectorControls = ( // To be changed - inherit control will be hidden completely once Custom // collection is introduced const displayInheritQueryControls = - isEmpty( collection ) || collection === defaultQuery.name; + isEmpty( collection ) || collection === collections.defaultQuery.name; const displayQueryControls = inherit === false; + const displayOrderBy = shouldDisplayOrderBy( collection ); + const displayFeatured = shouldDisplayFeatured( collection ); + const displayOnSale = shouldDisplayOnSale( collection ); const setQueryAttributeBind = useMemo( () => setQueryAttribute.bind( null, props ), @@ -85,7 +117,7 @@ const ProductCollectionInspectorControls = ( { displayInheritQueryControls ? ( ) : null } - { displayQueryControls ? ( + { displayQueryControls && displayOrderBy ? ( ) : null } @@ -101,13 +133,17 @@ const ProductCollectionInspectorControls = ( } } className="wc-block-editor-product-collection-inspector-toolspanel__filters" > - + { displayOnSale ? ( + + ) : null } - + { displayFeatured ? ( + + ) : null } ) : null } From 945924ac33d98aeb6c9d96249f638672f5d980fe Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:21:39 +0100 Subject: [PATCH 092/111] Declare hidden filters on the collection level --- .../collections/best-sellers.tsx | 1 + .../collections/featured.tsx | 1 + .../product-collection/collections/index.tsx | 14 ++++++ .../collections/new-arrivals.tsx | 1 + .../collections/on-sale.tsx | 1 + .../collections/top-rated.tsx | 1 + .../edit/inspector-controls/index.tsx | 44 ++++--------------- 7 files changed, 27 insertions(+), 36 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/best-sellers.tsx b/assets/js/blocks/product-collection/collections/best-sellers.tsx index c7ec002462a..2790a6e9b53 100644 --- a/assets/js/blocks/product-collection/collections/best-sellers.tsx +++ b/assets/js/blocks/product-collection/collections/best-sellers.tsx @@ -23,6 +23,7 @@ const collection = { ), keywords: [ 'best selling' ], scope: [], + unchangeableFilters: [ 'order', 'orderBy' ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/featured.tsx b/assets/js/blocks/product-collection/collections/featured.tsx index 55dbb6af19c..c0bc226fe95 100644 --- a/assets/js/blocks/product-collection/collections/featured.tsx +++ b/assets/js/blocks/product-collection/collections/featured.tsx @@ -27,6 +27,7 @@ const collection = { ), keywords: [], scope: [], + unchangeableFilters: [ 'featured' ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/index.tsx b/assets/js/blocks/product-collection/collections/index.tsx index 39814dfefc0..a45cba5860a 100644 --- a/assets/js/blocks/product-collection/collections/index.tsx +++ b/assets/js/blocks/product-collection/collections/index.tsx @@ -59,4 +59,18 @@ export const registerCollections = () => { } ); }; +export const getCollectionByName = ( collectionName ) => { + return collectionsArray.find( ( { name } ) => name === collectionName ); +}; + +export const getUnchangeableFilters = ( collectionName ) => { + const collection = getCollectionByName( collectionName ); + + if ( ! collection ) { + return []; + } + + return collection.unchangeableFilters; +}; + export default registerCollections; diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index 0bac18cc28f..943b1c587d9 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -27,6 +27,7 @@ const collection = { ), keywords: [ 'newest products' ], scope: [], + unchangeableFilters: [ 'order', 'orderBy' ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/on-sale.tsx b/assets/js/blocks/product-collection/collections/on-sale.tsx index d3ec70f5752..7b75f34a5f9 100644 --- a/assets/js/blocks/product-collection/collections/on-sale.tsx +++ b/assets/js/blocks/product-collection/collections/on-sale.tsx @@ -27,6 +27,7 @@ const collection = { ), keywords: [], scope: [], + unchangeableFilters: [ 'onSale' ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/top-rated.tsx b/assets/js/blocks/product-collection/collections/top-rated.tsx index 1d2a695801a..2a9de1d1605 100644 --- a/assets/js/blocks/product-collection/collections/top-rated.tsx +++ b/assets/js/blocks/product-collection/collections/top-rated.tsx @@ -27,6 +27,7 @@ const collection = { ), keywords: [], scope: [], + unchangeableFilters: [ 'order', 'orderBy' ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx index c2c6844ba8e..f20915c206e 100644 --- a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx @@ -28,7 +28,7 @@ import metadata from '../../block.json'; import { ProductCollectionAttributes } from '../../types'; import { setQueryAttribute } from '../../utils'; import { DEFAULT_FILTERS, getDefaultSettings } from '../../constants'; -import { collections } from '../../collections'; +import { collections, getUnchangeableFilters } from '../../collections'; import UpgradeNotice from './upgrade-notice'; import ColumnsControl from './columns-control'; import InheritQueryControl from './inherit-query-control'; @@ -43,35 +43,6 @@ import LayoutOptionsControl from './layout-options-control'; import FeaturedProductsControl from './featured-products-control'; import CreatedControl from './created-control'; -const shouldDisplayOrderBy = ( collection?: string ) => { - if ( ! collection ) { - return true; - } - - const collectionsToHideOrderBy = [ - collections.bestSellers.name, - collections.newArrivals.name, - collections.topRated.name, - ]; - return ! collectionsToHideOrderBy.includes( collection ); -}; - -const shouldDisplayFeatured = ( collection?: string ) => { - if ( ! collection ) { - return true; - } - - return collection !== collections.featured.name; -}; - -const shouldDisplayOnSale = ( collection?: string ) => { - if ( ! collection ) { - return true; - } - - return collection !== collections.onSale.name; -}; - const ProductCollectionInspectorControls = ( props: BlockEditProps< ProductCollectionAttributes > ) => { @@ -82,9 +53,10 @@ const ProductCollectionInspectorControls = ( const displayInheritQueryControls = isEmpty( collection ) || collection === collections.defaultQuery.name; const displayQueryControls = inherit === false; - const displayOrderBy = shouldDisplayOrderBy( collection ); - const displayFeatured = shouldDisplayFeatured( collection ); - const displayOnSale = shouldDisplayOnSale( collection ); + const unchangeableFilters = getUnchangeableFilters( collection ); + const shouldDisplayFilter = ( filter ) => { + return ! unchangeableFilters.includes( filter ); + }; const setQueryAttributeBind = useMemo( () => setQueryAttribute.bind( null, props ), @@ -117,7 +89,7 @@ const ProductCollectionInspectorControls = ( { displayInheritQueryControls ? ( ) : null } - { displayQueryControls && displayOrderBy ? ( + { displayQueryControls && shouldDisplayFilter( 'orderBy' ) ? ( ) : null } @@ -133,7 +105,7 @@ const ProductCollectionInspectorControls = ( } } className="wc-block-editor-product-collection-inspector-toolspanel__filters" > - { displayOnSale ? ( + { shouldDisplayFilter( 'onSale' ) ? ( ) : null } @@ -141,7 +113,7 @@ const ProductCollectionInspectorControls = ( - { displayFeatured ? ( + { shouldDisplayFilter( 'featured' ) ? ( ) : null } From d70b1ab613bc510497d68e133998e505eb3da85d Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:04:54 +0100 Subject: [PATCH 093/111] Type the Collections and Filters --- .../collections/best-sellers.tsx | 5 ++-- .../collections/featured.tsx | 5 ++-- .../collections/new-arrivals.tsx | 5 ++-- .../collections/on-sale.tsx | 5 ++-- .../collections/top-rated.tsx | 5 ++-- assets/js/blocks/product-collection/types.ts | 25 +++++++++++++++++++ 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/best-sellers.tsx b/assets/js/blocks/product-collection/collections/best-sellers.tsx index 2790a6e9b53..e605d4a8835 100644 --- a/assets/js/blocks/product-collection/collections/best-sellers.tsx +++ b/assets/js/blocks/product-collection/collections/best-sellers.tsx @@ -12,9 +12,10 @@ import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_PRODUCT_TEMPLATE, } from '../constants'; +import { CoreCollectionNames, CoreFilterNames } from '../types'; const collection = { - name: 'woocommerce-blocks/product-collection/best-sellers', + name: CoreCollectionNames.BEST_SELLERS, title: __( 'Best Sellers', 'woo-gutenberg-products-block' ), icon: ( ) as BlockIcon, description: __( @@ -23,7 +24,7 @@ const collection = { ), keywords: [ 'best selling' ], scope: [], - unchangeableFilters: [ 'order', 'orderBy' ], + unchangeableFilters: [ CoreFilterNames.INHERIT, CoreFilterNames.ORDER ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/featured.tsx b/assets/js/blocks/product-collection/collections/featured.tsx index c0bc226fe95..744156187c8 100644 --- a/assets/js/blocks/product-collection/collections/featured.tsx +++ b/assets/js/blocks/product-collection/collections/featured.tsx @@ -16,9 +16,10 @@ import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_PRODUCT_TEMPLATE, } from '../constants'; +import { CoreCollectionNames, CoreFilterNames } from '../types'; const collection = { - name: 'woocommerce-blocks/product-collection/featured', + name: CoreCollectionNames.FEATURED, title: __( 'Featured', 'woo-gutenberg-products-block' ), icon: ( ) as BlockIcon, description: __( @@ -27,7 +28,7 @@ const collection = { ), keywords: [], scope: [], - unchangeableFilters: [ 'featured' ], + unchangeableFilters: [ CoreFilterNames.INHERIT, CoreFilterNames.FEATURED ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/new-arrivals.tsx b/assets/js/blocks/product-collection/collections/new-arrivals.tsx index 943b1c587d9..3765fe08c5f 100644 --- a/assets/js/blocks/product-collection/collections/new-arrivals.tsx +++ b/assets/js/blocks/product-collection/collections/new-arrivals.tsx @@ -16,9 +16,10 @@ import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_PRODUCT_TEMPLATE, } from '../constants'; +import { CoreCollectionNames, CoreFilterNames } from '../types'; const collection = { - name: 'woocommerce-blocks/product-collection/new-arrivals', + name: CoreCollectionNames.NEW_ARRIVALS, title: __( 'New Arrivals', 'woo-gutenberg-products-block' ), icon: ( ) as BlockIcon, description: __( @@ -27,7 +28,7 @@ const collection = { ), keywords: [ 'newest products' ], scope: [], - unchangeableFilters: [ 'order', 'orderBy' ], + unchangeableFilters: [ CoreFilterNames.INHERIT, CoreFilterNames.ORDER ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/on-sale.tsx b/assets/js/blocks/product-collection/collections/on-sale.tsx index 7b75f34a5f9..95e967d4750 100644 --- a/assets/js/blocks/product-collection/collections/on-sale.tsx +++ b/assets/js/blocks/product-collection/collections/on-sale.tsx @@ -16,9 +16,10 @@ import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_PRODUCT_TEMPLATE, } from '../constants'; +import { CoreCollectionNames, CoreFilterNames } from '../types'; const collection = { - name: 'woocommerce-blocks/product-collection/on-sale', + name: CoreCollectionNames.ON_SALE, title: __( 'On Sale', 'woo-gutenberg-products-block' ), icon: ( ) as BlockIcon, description: __( @@ -27,7 +28,7 @@ const collection = { ), keywords: [], scope: [], - unchangeableFilters: [ 'onSale' ], + unchangeableFilters: [ CoreFilterNames.INHERIT, CoreFilterNames.ON_SALE ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/collections/top-rated.tsx b/assets/js/blocks/product-collection/collections/top-rated.tsx index 2a9de1d1605..9b473c028fa 100644 --- a/assets/js/blocks/product-collection/collections/top-rated.tsx +++ b/assets/js/blocks/product-collection/collections/top-rated.tsx @@ -16,9 +16,10 @@ import { DEFAULT_ATTRIBUTES, INNER_BLOCKS_PRODUCT_TEMPLATE, } from '../constants'; +import { CoreCollectionNames, CoreFilterNames } from '../types'; const collection = { - name: 'woocommerce-blocks/product-collection/top-rated', + name: CoreCollectionNames.TOP_RATED, title: __( 'Top Rated', 'woo-gutenberg-products-block' ), icon: ( ) as BlockIcon, description: __( @@ -27,7 +28,7 @@ const collection = { ), keywords: [], scope: [], - unchangeableFilters: [ 'order', 'orderBy' ], + unchangeableFilters: [ CoreFilterNames.INHERIT, CoreFilterNames.ORDER ], }; const attributes = { diff --git a/assets/js/blocks/product-collection/types.ts b/assets/js/blocks/product-collection/types.ts index 686482a79e2..8ef0e27357c 100644 --- a/assets/js/blocks/product-collection/types.ts +++ b/assets/js/blocks/product-collection/types.ts @@ -96,3 +96,28 @@ export type QueryControlProps = { query: ProductCollectionQuery; setQueryAttribute: ( attrs: Partial< ProductCollectionQuery > ) => void; }; + +export enum CoreCollectionNames { + PRODUCT_CATALOG = 'woocommerce-blocks/product-collection/product-catalog', + BEST_SELLERS = 'woocommerce-blocks/product-collection/best-sellers', + FEATURED = 'woocommerce-blocks/product-collection/featured', + NEW_ARRIVALS = 'woocommerce-blocks/product-collection/new-arrivals', + ON_SALE = 'woocommerce-blocks/product-collection/on-sale', + TOP_RATED = 'woocommerce-blocks/product-collection/top-rated', +} + +export enum CoreFilterNames { + ATTRIBUTES = 'attributes', + CREATED = 'created', + FEATURED = 'featured', + HAND_PICKED = 'hand-picked', + INHERIT = 'inherit', + KEYWORD = 'keyword', + ON_SALE = 'on-sale', + ORDER = 'order', + STOCK_STATUS = 'stock-status', + TAXONOMY = 'taxonomy', +} + +export type CollectionName = CoreCollectionNames | string; +export type FilterName = CoreFilterNames | string; From 592f5a57e7641dc9219d00a52c24f5496b255bfa Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:10:22 +0100 Subject: [PATCH 094/111] Extract Product Catalog Collection --- .../product-collection/collections/index.tsx | 12 +----- .../collections/product-catalog.tsx | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 assets/js/blocks/product-collection/collections/product-catalog.tsx diff --git a/assets/js/blocks/product-collection/collections/index.tsx b/assets/js/blocks/product-collection/collections/index.tsx index a45cba5860a..926c07c1a3e 100644 --- a/assets/js/blocks/product-collection/collections/index.tsx +++ b/assets/js/blocks/product-collection/collections/index.tsx @@ -6,33 +6,25 @@ import { registerBlockVariation, BlockAttributes, } from '@wordpress/blocks'; -import { Icon, loop } from '@wordpress/icons'; /** * Internal dependencies */ import blockJson from '../block.json'; +import productCatalog from './product-catalog'; import newArrivals from './new-arrivals'; import topRated from './top-rated'; import bestSellers from './best-sellers'; import onSale from './on-sale'; import featured from './featured'; -const defaultQuery = { - name: 'woocommerce-blocks/product-collection/default-query', - title: 'All Products', - icon: , - description: - 'Display all products. Results may be limited by the current template context.', -}; - export const collections = { + productCatalog, newArrivals, topRated, bestSellers, onSale, featured, - defaultQuery, }; const collectionsArray: BlockVariation[] = [ diff --git a/assets/js/blocks/product-collection/collections/product-catalog.tsx b/assets/js/blocks/product-collection/collections/product-catalog.tsx new file mode 100644 index 00000000000..aa3921192b6 --- /dev/null +++ b/assets/js/blocks/product-collection/collections/product-catalog.tsx @@ -0,0 +1,42 @@ +/** + * External dependencies + */ +import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; +import { Icon, loop } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { + DEFAULT_ATTRIBUTES, + INNER_BLOCKS_PRODUCT_TEMPLATE, +} from '../constants'; +import { CoreCollectionNames } from '../types'; + +const collection = { + name: CoreCollectionNames.PRODUCT_CATALOG, + title: __( 'Product Catalog', 'woo-gutenberg-products-block' ), + icon: ( ) as BlockIcon, + description: + 'Display all products. Results may be limited by the current template context.', + keywords: [ 'all products' ], + scope: [], + unchangeableFilters: [], +}; + +const attributes = { + ...DEFAULT_ATTRIBUTES, + query: { + ...DEFAULT_ATTRIBUTES.query, + inherit: true, + }, +}; + +const innerBlocks: InnerBlockTemplate[] = [ INNER_BLOCKS_PRODUCT_TEMPLATE ]; + +export default { + ...collection, + attributes, + innerBlocks, +}; From cd888eefc893a72ce59ce99a75c526ad5b60c315 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:11:47 +0100 Subject: [PATCH 095/111] Udpate usage of defaultQuery renamed to productCatalog --- .../product-collection/edit/collection-selection-modal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx index f2721eb0c4d..eba355fd9a6 100644 --- a/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx +++ b/assets/js/blocks/product-collection/edit/collection-selection-modal.tsx @@ -73,7 +73,7 @@ const getDefaultChosenCollection = ( // configured. So it's either a collection or we need to return defaultQuery // collection name; if ( attributes.query ) { - return attributes.collection || collections.defaultQuery.name; + return attributes.collection || collections.productCatalog.name; } // Otherwise it should be the first available choice. We control collections @@ -93,7 +93,7 @@ const PatternSelectionModal = ( props: { // Get Collections const blockCollections = [ - collections.defaultQuery, + collections.productCatalog, ...useSelect( ( select ) => { // @ts-expect-error Type definitions are missing // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts From 2c0d51fdbbf188eefc6bc00121fe226a1dd38d48 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:12:09 +0100 Subject: [PATCH 096/111] Update tests --- .../e2e/tests/product-collection/product-collection.page.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 8fc3b654c15..ce5816236e5 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -40,7 +40,7 @@ type Collections = | 'bestSellers' | 'onSale' | 'featured' - | 'defaultQuery'; + | 'productCatalog'; const collectionToButtonNameMap = { newArrivals: 'New Arrivals Recommend your newest products.', @@ -48,8 +48,8 @@ const collectionToButtonNameMap = { bestSellers: 'Best Sellers Recommend your best-selling products.', onSale: 'On Sale Highlight products that are currently on sale.', featured: 'Featured Showcase your featured products.', - defaultQuery: - 'All Products Display all products in your catalog. Results may change to match the current template, page, or search term.', + productCatalog: + 'Product Catalog Display all products in your catalog. Results may change to match the current template, page, or search term.', }; class ProductCollectionPage { From be274ac7f040e948a279267dc75d4b733869cf07 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:12:45 +0100 Subject: [PATCH 097/111] Update README with info Collections are internal and not public API --- assets/js/blocks/product-collection/collections/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index a823a42963b..72ebcbba276 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -1,5 +1,7 @@ # Product Collection - Collections +_Note: Collections documented here are internal implementation. It's not a public API._ + Collections are a variations of Product Collection block with the predefined attributes which includes: - UI aspect - you can define layout, number of columns etc. @@ -29,4 +31,4 @@ As an example please follow `./new-arrivals.tsx`. ## Registering Collection -To register collection import it in `./index.ts` file and add to the `collections` array. +To register collection import it in `./index.ts` file and add to the `collectionsToRegister` array. From 853065ab8507e54e9f9d3ab8ef996cae01611e86 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:13:49 +0100 Subject: [PATCH 098/111] Update Inspector Controls with the mechanisms checking if filters should be displayed --- .../product-collection/collections/index.tsx | 22 +++++----- .../edit/inspector-controls/index.tsx | 40 ++++++++++++------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/index.tsx b/assets/js/blocks/product-collection/collections/index.tsx index 926c07c1a3e..222e9a27ea2 100644 --- a/assets/js/blocks/product-collection/collections/index.tsx +++ b/assets/js/blocks/product-collection/collections/index.tsx @@ -10,6 +10,7 @@ import { /** * Internal dependencies */ +import { CollectionName, FilterName } from '../types'; import blockJson from '../block.json'; import productCatalog from './product-catalog'; import newArrivals from './new-arrivals'; @@ -27,7 +28,7 @@ export const collections = { featured, }; -const collectionsArray: BlockVariation[] = [ +const collectionsToRegister: BlockVariation[] = [ featured, topRated, onSale, @@ -36,7 +37,7 @@ const collectionsArray: BlockVariation[] = [ ]; export const registerCollections = () => { - collectionsArray.forEach( ( collection ) => { + collectionsToRegister.forEach( ( collection ) => { const isActive = ( blockAttrs: BlockAttributes, variationAttributes: BlockAttributes @@ -51,18 +52,21 @@ export const registerCollections = () => { } ); }; -export const getCollectionByName = ( collectionName ) => { - return collectionsArray.find( ( { name } ) => name === collectionName ); +export const getCollectionByName = ( collectionName: CollectionName ) => { + return Object.values( collections ).find( + ( { name } ) => name === collectionName + ); }; -export const getUnchangeableFilters = ( collectionName ) => { - const collection = getCollectionByName( collectionName ); - - if ( ! collection ) { +export const getUnchangeableFilters = ( + collectionName?: CollectionName +): FilterName[] => { + if ( ! collectionName ) { return []; } - return collection.unchangeableFilters; + const collection = getCollectionByName( collectionName ); + return collection ? collection.unchangeableFilters : []; }; export default registerCollections; diff --git a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx index f20915c206e..32ca8818bec 100644 --- a/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/edit/inspector-controls/index.tsx @@ -25,10 +25,14 @@ import { * Internal dependencies */ import metadata from '../../block.json'; -import { ProductCollectionAttributes } from '../../types'; +import { + ProductCollectionAttributes, + CoreFilterNames, + FilterName, +} from '../../types'; import { setQueryAttribute } from '../../utils'; import { DEFAULT_FILTERS, getDefaultSettings } from '../../constants'; -import { collections, getUnchangeableFilters } from '../../collections'; +import { getUnchangeableFilters } from '../../collections'; import UpgradeNotice from './upgrade-notice'; import ColumnsControl from './columns-control'; import InheritQueryControl from './inherit-query-control'; @@ -43,20 +47,28 @@ import LayoutOptionsControl from './layout-options-control'; import FeaturedProductsControl from './featured-products-control'; import CreatedControl from './created-control'; +const prepareShouldShowFilter = + ( unchangeableFilters: FilterName[] ) => ( filter: FilterName ) => { + return ! unchangeableFilters.includes( filter ); + }; + const ProductCollectionInspectorControls = ( props: BlockEditProps< ProductCollectionAttributes > ) => { const { query, collection } = props.attributes; const inherit = query?.inherit; + const unchangeableFilters = getUnchangeableFilters( collection ); + const shouldShowFilter = prepareShouldShowFilter( unchangeableFilters ); + // To be changed - inherit control will be hidden completely once Custom // collection is introduced - const displayInheritQueryControls = - isEmpty( collection ) || collection === collections.defaultQuery.name; - const displayQueryControls = inherit === false; - const unchangeableFilters = getUnchangeableFilters( collection ); - const shouldDisplayFilter = ( filter ) => { - return ! unchangeableFilters.includes( filter ); - }; + const showQueryControls = inherit === false; + const showInheritQueryControls = + isEmpty( collection ) || shouldShowFilter( CoreFilterNames.INHERIT ); + const showOrderControl = + showQueryControls && shouldShowFilter( CoreFilterNames.ORDER ); + const showFeaturedControl = shouldShowFilter( CoreFilterNames.FEATURED ); + const showOnSaleControl = shouldShowFilter( CoreFilterNames.ON_SALE ); const setQueryAttributeBind = useMemo( () => setQueryAttribute.bind( null, props ), @@ -86,15 +98,15 @@ const ProductCollectionInspectorControls = ( > - { displayInheritQueryControls ? ( + { showInheritQueryControls ? ( ) : null } - { displayQueryControls && shouldDisplayFilter( 'orderBy' ) ? ( + { showOrderControl ? ( ) : null } - { displayQueryControls ? ( + { showQueryControls ? ( void )[] ) => { @@ -105,7 +117,7 @@ const ProductCollectionInspectorControls = ( } } className="wc-block-editor-product-collection-inspector-toolspanel__filters" > - { shouldDisplayFilter( 'onSale' ) ? ( + { showOnSaleControl ? ( ) : null } @@ -113,7 +125,7 @@ const ProductCollectionInspectorControls = ( - { shouldDisplayFilter( 'featured' ) ? ( + { showFeaturedControl ? ( ) : null } From 279c20b20bd044e184fb45b3430447bc61b8586c Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:23:50 +0100 Subject: [PATCH 099/111] Update README with information about unchamheableFilters --- .../product-collection/collections/README.md | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index 72ebcbba276..9e000a66eb2 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -13,15 +13,15 @@ Collections are a variations of Product Collection block with the predefined att Collections are in fact Variations and they are registered via Variation API. Hence they should follow the BlockVariation type, providing at least: ```typescript -{ +type Collection ={ name: string; - title: string, - icon: Icon, - description: string, - attributes: ProductCollectionAttributes, - innerBlocks: InnerBlockTemplate[], + title: string; + icon: Icon; + description: string; + attributes: ProductCollectionAttributes; + innerBlocks: InnerBlockTemplate[]; isActive?: - (blockAttrs: BlockAttributes, variationAttributes: BlockAttributes) => boolean, + (blockAttrs: BlockAttributes, variationAttributes: BlockAttributes) => boolean; } ``` @@ -29,6 +29,19 @@ Please be aware you can specify `isActive` function, but if not, the default one As an example please follow `./new-arrivals.tsx`. +## Collection can hide Inspector Controls filters from users + +Let's take New Arrivals as an example. What defined New Arrivals is the product ordering: from newest to oldest. User can apply additional filters on top of it, for example "On Sale" but shouldn't be able to change ordering because that would no longer be New Arrivals Collection. + +To achieve this add additional property to collection definition: + +```typescript +type Collection = { + ...; + unchangeableFilters: FilterName[]; +} +``` + ## Registering Collection To register collection import it in `./index.ts` file and add to the `collectionsToRegister` array. From c27d4fc26e50d5f5240395d9d1bf880d35799606 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:39:30 +0100 Subject: [PATCH 100/111] Fix README typos --- assets/js/blocks/product-collection/collections/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/collections/README.md b/assets/js/blocks/product-collection/collections/README.md index 9e000a66eb2..a3b75e2c96e 100644 --- a/assets/js/blocks/product-collection/collections/README.md +++ b/assets/js/blocks/product-collection/collections/README.md @@ -31,7 +31,7 @@ As an example please follow `./new-arrivals.tsx`. ## Collection can hide Inspector Controls filters from users -Let's take New Arrivals as an example. What defined New Arrivals is the product ordering: from newest to oldest. User can apply additional filters on top of it, for example "On Sale" but shouldn't be able to change ordering because that would no longer be New Arrivals Collection. +Let's take New Arrivals as an example. What defines New Arrivals is the product order: from newest to oldest. Users can apply additional filters on top of it, for example, "On Sale" but shouldn't be able to change ordering because that would no longer be New Arrivals Collection. To achieve this add additional property to collection definition: From 0a9b0433456e2d735f341c846cdc4ae4c4b766cc Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:01:01 +0100 Subject: [PATCH 101/111] Address part of the test updates --- .../product-collection.block_theme.spec.ts | 14 +++++++------- .../product-collection/product-collection.page.ts | 7 +++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts b/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts index cc06e7e4012..26f56d4079e 100644 --- a/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts +++ b/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts @@ -390,9 +390,9 @@ test.describe( 'Product Collection', () => { } ) => { await pageObject.createNewPostAndInsertBlock( 'newArrivals' ); - const orderBy = await pageObject.getOrderBy(); + const orderBy = await pageObject.getOrderByElement(); - expect( orderBy ).toBe( 'date/desc' ); + await expect( orderBy ).toBeHidden(); await expect( pageObject.products ).toHaveCount( 5 ); @@ -404,9 +404,9 @@ test.describe( 'Product Collection', () => { test( 'Top Rated Collection can be added', async ( { pageObject } ) => { await pageObject.createNewPostAndInsertBlock( 'topRated' ); - const orderBy = await pageObject.getOrderBy(); + const orderBy = await pageObject.getOrderByElement(); - expect( orderBy ).toBe( 'rating/desc' ); + await expect( orderBy ).toBeHidden(); await expect( pageObject.products ).toHaveCount( 5 ); @@ -420,9 +420,9 @@ test.describe( 'Product Collection', () => { } ) => { await pageObject.createNewPostAndInsertBlock( 'bestSellers' ); - const orderBy = await pageObject.getOrderBy(); + const orderBy = await pageObject.getOrderByElement(); - expect( orderBy ).toBe( 'popularity/desc' ); + await expect( orderBy ).toBeHidden(); await expect( pageObject.products ).toHaveCount( 5 ); @@ -467,7 +467,7 @@ test.describe( 'Product Collection', () => { test( 'Default Query Collection can be added', async ( { pageObject, } ) => { - await pageObject.createNewPostAndInsertBlock( 'defaultQuery' ); + await pageObject.createNewPostAndInsertBlock( 'productCatalog' ); const orderBy = await pageObject.getOrderBy(); diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index ce5816236e5..eb3b25e5f7b 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -252,12 +252,15 @@ class ProductCollectionPage { await this.refreshLocators( 'editor' ); } - async getOrderBy() { + async getOrderByElement() { const sidebarSettings = await this.locateSidebarSettings(); - const orderByComboBox = sidebarSettings.getByRole( 'combobox', { + return sidebarSettings.getByRole( 'combobox', { name: 'Order by', } ); + } + async getOrderBy() { + const orderByComboBox = await this.getOrderByElement(); return await orderByComboBox.inputValue(); } From 2b482fc5b99b72f80b2f079584f0247702c18056 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:35:28 +0100 Subject: [PATCH 102/111] Update collection description in locator in E2E test --- tests/e2e/tests/product-collection/product-collection.page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 8fc3b654c15..f41926da4cf 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -49,7 +49,7 @@ const collectionToButtonNameMap = { onSale: 'On Sale Highlight products that are currently on sale.', featured: 'Featured Showcase your featured products.', defaultQuery: - 'All Products Display all products in your catalog. Results may change to match the current template, page, or search term.', + 'All Products Display all products. Results may be limited by the current template context.', }; class ProductCollectionPage { From e609230447496579a134d35c0c743f31fa81b200 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:17:23 +0100 Subject: [PATCH 103/111] Update Collection tests so they are based on displayed products and not attributes --- .../product-collection.block_theme.spec.ts | 87 +++++++++++++------ .../product-collection.page.ts | 55 +----------- 2 files changed, 63 insertions(+), 79 deletions(-) diff --git a/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts b/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts index cc06e7e4012..947ba4ec92b 100644 --- a/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts +++ b/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts @@ -385,86 +385,121 @@ test.describe( 'Product Collection', () => { } ); test.describe( 'Collections', () => { - test( 'New Arrivals Collection can be added', async ( { + test( 'New Arrivals Collection can be added and displays proper products', async ( { pageObject, } ) => { await pageObject.createNewPostAndInsertBlock( 'newArrivals' ); - const orderBy = await pageObject.getOrderBy(); - - expect( orderBy ).toBe( 'date/desc' ); + const newArrivalsProducts = [ + 'WordPress Pennant', + 'Logo Collection', + 'Beanie with Logo', + 'T-Shirt with Logo', + 'Single', + ]; await expect( pageObject.products ).toHaveCount( 5 ); + await expect( pageObject.productTitles ).toHaveText( + newArrivalsProducts + ); await pageObject.publishAndGoToFrontend(); await expect( pageObject.products ).toHaveCount( 5 ); } ); - test( 'Top Rated Collection can be added', async ( { pageObject } ) => { + test( 'Top Rated Collection can be added and displays proper products', async ( { + pageObject, + } ) => { await pageObject.createNewPostAndInsertBlock( 'topRated' ); - const orderBy = await pageObject.getOrderBy(); - - expect( orderBy ).toBe( 'rating/desc' ); + const topRatedProducts = [ + 'Beanie', + 'Logo Collection', + 'Belt', + 'WordPress Pennant', + 'Cap', + ]; await expect( pageObject.products ).toHaveCount( 5 ); + await expect( pageObject.productTitles ).toHaveText( + topRatedProducts + ); await pageObject.publishAndGoToFrontend(); await expect( pageObject.products ).toHaveCount( 5 ); } ); - test( 'Best Sellers Collection can be added', async ( { + test( 'Best Sellers Collection can be added and displays proper products', async ( { pageObject, } ) => { await pageObject.createNewPostAndInsertBlock( 'bestSellers' ); - const orderBy = await pageObject.getOrderBy(); - - expect( orderBy ).toBe( 'popularity/desc' ); + const bestSellersProducts = [ + 'Album', + 'Hoodie', + 'Single', + 'Hoodie with Logo', + 'T-Shirt with Logo', + ]; await expect( pageObject.products ).toHaveCount( 5 ); + await expect( pageObject.productTitles ).toHaveText( + bestSellersProducts + ); await pageObject.publishAndGoToFrontend(); await expect( pageObject.products ).toHaveCount( 5 ); } ); - test( 'On Sale Collection can be added', async ( { pageObject } ) => { + test( 'On Sale Collection can be added and displays proper products', async ( { + pageObject, + } ) => { await pageObject.createNewPostAndInsertBlock( 'onSale' ); - const orderBy = await pageObject.getOrderBy(); - const featured = await pageObject.getFeaturedValue(); - - expect( orderBy ).toBe( 'title/asc' ); - expect( featured ).toBe( 'off' ); + const onSaleProducts = [ + 'Beanie', + 'Beanie with Logo', + 'Belt', + 'Cap', + 'Hoodie', + ]; await expect( pageObject.products ).toHaveCount( 5 ); + await expect( pageObject.productTitles ).toHaveText( + onSaleProducts + ); await pageObject.publishAndGoToFrontend(); await expect( pageObject.products ).toHaveCount( 5 ); } ); - test( 'Featured Collection can be added', async ( { pageObject } ) => { + test( 'Featured Collection can be added and displays proper products', async ( { + pageObject, + } ) => { await pageObject.createNewPostAndInsertBlock( 'featured' ); - const orderBy = await pageObject.getOrderBy(); - const featured = await pageObject.getFeaturedValue(); - - expect( orderBy ).toBe( 'title/asc' ); - expect( featured ).toBe( 'on' ); + const featuredProducts = [ + 'Cap', + 'Hoodie with Zipper', + 'Sunglasses', + 'V-Neck T-Shirt', + ]; - // There's 5 columns layout, but only 4 featured products in test set await expect( pageObject.products ).toHaveCount( 4 ); + await expect( pageObject.productTitles ).toHaveText( + featuredProducts + ); await pageObject.publishAndGoToFrontend(); await expect( pageObject.products ).toHaveCount( 4 ); } ); - test( 'Default Query Collection can be added', async ( { + test( 'Default Query Collection can be added and displays proper products', async ( { pageObject, } ) => { await pageObject.createNewPostAndInsertBlock( 'defaultQuery' ); diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index f41926da4cf..990d030dc56 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -286,55 +286,6 @@ class ProductCollectionPage { if ( isLocatorsRefreshNeeded ) await this.refreshLocators( 'editor' ); } - async getOnSaleValue() { - const sidebarSettings = await this.locateSidebarSettings(); - - const input = sidebarSettings.getByLabel( - SELECTORS.onSaleControlLabel - ); - - return await input.inputValue(); - } - - async setFeaturedProducts( - { - featured, - isLocatorsRefreshNeeded, - }: { - featured: boolean; - isLocatorsRefreshNeeded?: boolean; - } = { - isLocatorsRefreshNeeded: true, - featured: true, - } - ) { - const sidebarSettings = await this.locateSidebarSettings(); - const input = sidebarSettings.getByLabel( - SELECTORS.featuredControlLabel - ); - if ( featured ) { - await input.check(); - } else { - await input.uncheck(); - } - - if ( isLocatorsRefreshNeeded ) await this.refreshLocators( 'editor' ); - } - - async getFeaturedValue() { - const sidebarSettings = await this.locateSidebarSettings(); - const visible = await sidebarSettings - .getByLabel( SELECTORS.featuredControlLabel ) - .isVisible(); - - // If input is hidden, it's implicitly in default state, meaning off - if ( ! visible ) return 'off'; - - return await sidebarSettings - .getByLabel( SELECTORS.featuredControlLabel ) - .inputValue(); - } - async setFilterComboboxValue( filterName: string, filterValue: string[] ) { const sidebarSettings = await this.locateSidebarSettings(); const input = sidebarSettings.getByLabel( filterName ); @@ -495,10 +446,8 @@ class ProductCollectionPage { return this.page.getByTestId( testId ); } - async getCollectionHeading( name: string ) { - return this.page.getByRole( 'heading', { - name, - } ); + async getCollectionHeading() { + return this.page.getByRole( 'heading' ); } /** From b622b61d675faf66aadd6bfbcba7f98f0cab6759 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:22:27 +0100 Subject: [PATCH 104/111] Fix incorrect conflict resolution --- .../blocks/product-collection/edit/index.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/assets/js/blocks/product-collection/edit/index.tsx b/assets/js/blocks/product-collection/edit/index.tsx index e69de29bb2d..3c7b46ac530 100644 --- a/assets/js/blocks/product-collection/edit/index.tsx +++ b/assets/js/blocks/product-collection/edit/index.tsx @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { BlockEditProps } from '@wordpress/blocks'; +import { useState } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import type { ProductCollectionAttributes } from '../types'; +import ProductCollectionPlaceholder from './product-collection-placeholder'; +import ProductCollectionContent from './product-collection-content'; +import PatternSelectionModal from './collection-selection-modal'; +import './editor.scss'; + +const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => { + const { clientId, attributes } = props; + + const [ isPatternSelectionModalOpen, setIsPatternSelectionModalOpen ] = + useState( false ); + const hasInnerBlocks = useSelect( + ( select ) => + !! select( blockEditorStore ).getBlocks( clientId ).length, + [ clientId ] + ); + + const Component = hasInnerBlocks + ? ProductCollectionContent + : ProductCollectionPlaceholder; + + return ( + <> + + setIsPatternSelectionModalOpen( true ) + } + /> + { isPatternSelectionModalOpen && ( + + setIsPatternSelectionModalOpen( false ) + } + /> + ) } + + ); +}; + +export default Edit; From aca352b66250f0e61489d5535238c0d14580cd12 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:26:23 +0100 Subject: [PATCH 105/111] Revert unexpected composer.lock changes --- composer.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.lock b/composer.lock index ba2973d51d8..4bf262149ad 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "95c02e99e87012fa1d993c0ac089a6f0", + "content-hash": "cc276b92e545efcc29db6103d53b6480", "packages": [ { "name": "automattic/jetpack-a8c-mc-stats", @@ -3299,5 +3299,5 @@ "platform-overrides": { "php": "7.4.33" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } From 1ffe0288f30d20cba9d9cd0909bef4507964c3c7 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:27:09 +0100 Subject: [PATCH 106/111] Revert lines swap --- assets/js/blocks/product-collection/utils.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/utils.tsx b/assets/js/blocks/product-collection/utils.tsx index 3be6c094439..b26426a4c70 100644 --- a/assets/js/blocks/product-collection/utils.tsx +++ b/assets/js/blocks/product-collection/utils.tsx @@ -1,8 +1,8 @@ /** * External dependencies */ -import { select } from '@wordpress/data'; import { BlockEditProps } from '@wordpress/blocks'; +import { select } from '@wordpress/data'; /** * Internal dependencies From 692e49b7a51892a349f601e6536cdb1a7fb1285b Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:20:57 +0100 Subject: [PATCH 107/111] Move the Collections buttons to Product Collection Placeholder --- .../edit/product-collection-placeholder.tsx | 142 ++++++++++++++++-- 1 file changed, 126 insertions(+), 16 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index 95956016efb..d62cbd2bb01 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -7,7 +7,14 @@ import { useBlockProps, } from '@wordpress/block-editor'; import { Placeholder, Button } from '@wordpress/components'; -import { useDispatch } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { + // @ts-expect-error Type definitions for this function are missing in Guteberg + store as blocksStore, + createBlock, + // @ts-expect-error Type definitions for this function are missing in Guteberg + createBlocksFromInnerBlocksTemplate, +} from '@wordpress/blocks'; /** * Internal dependencies @@ -15,19 +22,114 @@ import { useDispatch } from '@wordpress/data'; import type { ProductCollectionEditComponentProps } from '../types'; import { getDefaultProductCollection } from '../constants'; import Icon from '../icon'; +import blockJson from '../block.json'; +import { defaultQuery } from '../collections'; + +type CollectionButtonProps = { + active: boolean; + title: string; + icon: string; + description: string; + onClick: () => void; +}; + +const CollectionButton = ( { + active, + title, + icon, + description, + onClick, +}: CollectionButtonProps ) => { + const variant = active ? 'primary' : 'secondary'; + + return ( + + ); +}; + +const getDefaultChosenCollection = ( + attributes: ProductCollectionAttributes, + // @ts-expect-error Type definitions are missing + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts + blockCollections +) => { + // If `attributes.query` is truthy, that means Product Collection was already + // configured. So it's either a collection or we need to return defaultQuery + // collection name; + if ( attributes.query ) { + return attributes.collection || defaultQuery.name; + } + + // Otherwise it should be the first available choice. We control collections + // so there's always at least one available. + return blockCollections.length ? blockCollections[ 0 ].name : ''; +}; const ProductCollectionPlaceholder = ( props: ProductCollectionEditComponentProps ) => { - const { clientId, openPatternSelectionModal } = props; const blockProps = useBlockProps(); - - // @ts-expect-error Missing types in Gutenberg + const { clientId, attributes } = props; + // @ts-expect-error Type definitions for this function are missing + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/actions.d.ts const { replaceBlock } = useDispatch( blockEditorStore ); - const addDefaultProductCollection = () => { - const defaultProductCollection = getDefaultProductCollection(); - replaceBlock( clientId, defaultProductCollection ); + // Get Collections + const blockCollections = [ + defaultQuery, + ...useSelect( ( select ) => { + // @ts-expect-error Type definitions are missing + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts + const { getBlockVariations } = select( blocksStore ); + return getBlockVariations( blockJson.name ); + }, [] ), + ]; + + // Prepare Collections + const defaultChosenCollection = getDefaultChosenCollection( + attributes, + blockCollections + ); + + const applyCollection = ( chosenCollectionName: string ) => { + // Case 1: Merchant has chosen Default Query. In that case we create defaultProductCollection + if ( + chosenCollectionName === + 'woocommerce-blocks/product-collection/default-query' + ) { + const defaultProductCollection = getDefaultProductCollection(); + replaceBlock( clientId, defaultProductCollection ); + return; + } + + // Case 2: Merchant has chosen another Collection + const chosenCollection = blockCollections.find( + ( { name }: { name: string } ) => name === chosenCollectionName + ); + + const newBlock = createBlock( + blockJson.name, + chosenCollection.attributes, + createBlocksFromInnerBlocksTemplate( chosenCollection.innerBlocks ) + ); + + replaceBlock( clientId, newBlock ); }; return ( @@ -43,18 +145,26 @@ const ProductCollectionPlaceholder = ( 'woo-gutenberg-products-block' ) } > - - +

+
+ { blockCollections.map( + ( { name, title, icon, description } ) => ( + applyCollection( name ) } + /> + ) + ) } +
); From 5bb072f84a57afe9360add791ad2a25db770dc61 Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:29:00 +0100 Subject: [PATCH 108/111] Fix minor conflict reoslution issue --- .../edit/product-collection-placeholder.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index d62cbd2bb01..de9fede46cc 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -19,11 +19,14 @@ import { /** * Internal dependencies */ -import type { ProductCollectionEditComponentProps } from '../types'; +import type { + ProductCollectionEditComponentProps, + ProductCollectionAttributes, +} from '../types'; import { getDefaultProductCollection } from '../constants'; import Icon from '../icon'; import blockJson from '../block.json'; -import { defaultQuery } from '../collections'; +import productCatalog from '../collections/product-catalog'; type CollectionButtonProps = { active: boolean; @@ -73,7 +76,7 @@ const getDefaultChosenCollection = ( // configured. So it's either a collection or we need to return defaultQuery // collection name; if ( attributes.query ) { - return attributes.collection || defaultQuery.name; + return attributes.collection || productCatalog.name; } // Otherwise it should be the first available choice. We control collections @@ -92,7 +95,7 @@ const ProductCollectionPlaceholder = ( // Get Collections const blockCollections = [ - defaultQuery, + productCatalog, ...useSelect( ( select ) => { // @ts-expect-error Type definitions are missing // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/wordpress__blocks/store/selectors.d.ts From 79936bc048c9d5c1f0c1cba968105f78b70c626b Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:46:48 +0100 Subject: [PATCH 109/111] Adjust tests to the new flow (no modal) --- .../product-collection.page.ts | 58 +++++-------------- 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 59fadb6a02d..853fd16bcdd 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -88,56 +88,24 @@ class ProductCollectionPage { } async chooseCollectionInPost( collection?: Collections ) { - if ( ! collection ) { - await this.admin.page - .getByRole( 'button', { name: 'Create custom' } ) - .click(); - } else { - await this.admin.page - .getByRole( 'button', { name: 'Choose collection' } ) - .click(); - - await this.admin.page.waitForSelector( - '.wc-blocks-product-collection__modal' - ); - - const buttonName = collectionToButtonNameMap[ collection ]; - await this.admin.page - .getByRole( 'button', { name: buttonName } ) - .click(); + const buttonName = collection + ? collectionToButtonNameMap[ collection ] + : collectionToButtonNameMap.defaultQuery; - await this.admin.page - .getByRole( 'button', { name: 'Continue' } ) - .click(); - } + await this.admin.page + .getByRole( 'button', { name: buttonName } ) + .click(); } async chooseCollectionInTemplate( collection?: Collections ) { - if ( ! collection ) { - await this.admin.page - .frameLocator( 'iframe[name="editor-canvas"]' ) - .getByRole( 'button', { name: 'Create custom' } ) - .click(); - } else { - await this.admin.page - .frameLocator( 'iframe[name="editor-canvas"]' ) - .getByRole( 'button', { name: 'Choose collection' } ) - .click(); - - await this.admin.page.waitForSelector( - '.wc-blocks-product-collection__modal' - ); + const buttonName = collection + ? collectionToButtonNameMap[ collection ] + : collectionToButtonNameMap.defaultQuery; - const buttonName = collectionToButtonNameMap[ collection ]; - - await this.admin.page - .getByRole( 'button', { name: buttonName } ) - .click(); - - await this.admin.page - .getByRole( 'button', { name: 'Continue' } ) - .click(); - } + await this.admin.page + .frameLocator( 'iframe[name="editor-canvas"]' ) + .getByRole( 'button', { name: buttonName } ) + .click(); } async createNewPostAndInsertBlock( collection?: Collections ) { From ab897f111573ce6bc71746b494c96b4935a8ccbc Mon Sep 17 00:00:00 2001 From: Karol Manijak <20098064+kmanijak@users.noreply.github.com> Date: Thu, 7 Dec 2023 17:07:21 +0100 Subject: [PATCH 110/111] Fix styling of the placeholder --- assets/js/blocks/product-collection/edit/editor.scss | 4 +++- .../edit/product-collection-placeholder.tsx | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/js/blocks/product-collection/edit/editor.scss b/assets/js/blocks/product-collection/edit/editor.scss index 07a2deea36f..1b3a6b3b1cc 100644 --- a/assets/js/blocks/product-collection/edit/editor.scss +++ b/assets/js/blocks/product-collection/edit/editor.scss @@ -10,8 +10,9 @@ } } +.wc-blocks-product-collection__placeholder, .wc-blocks-product-collection__modal { - .wc-blocks-product-collection__selection-modal-subtitle { + .wc-blocks-product-collection__selection-subtitle { margin-bottom: $gap-large; } @@ -46,6 +47,7 @@ box-sizing: border-box; box-shadow: none; padding: $gap-smallest $gap-small; + margin: 0; &.is-primary { border: 2px solid var(--wp-admin-theme-color-darker-10, #3858e9); diff --git a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx index d62cbd2bb01..445f5290695 100644 --- a/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx +++ b/assets/js/blocks/product-collection/edit/product-collection-placeholder.tsx @@ -135,6 +135,7 @@ const ProductCollectionPlaceholder = ( return (
Date: Thu, 7 Dec 2023 17:08:45 +0100 Subject: [PATCH 111/111] Fix conflict --- tests/e2e/tests/product-collection/product-collection.page.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/tests/product-collection/product-collection.page.ts b/tests/e2e/tests/product-collection/product-collection.page.ts index 98715b831f8..028d1102fc9 100644 --- a/tests/e2e/tests/product-collection/product-collection.page.ts +++ b/tests/e2e/tests/product-collection/product-collection.page.ts @@ -90,7 +90,7 @@ class ProductCollectionPage { async chooseCollectionInPost( collection?: Collections ) { const buttonName = collection ? collectionToButtonNameMap[ collection ] - : collectionToButtonNameMap.defaultQuery; + : collectionToButtonNameMap.productCatalog; await this.admin.page .getByRole( 'button', { name: buttonName } ) @@ -100,7 +100,7 @@ class ProductCollectionPage { async chooseCollectionInTemplate( collection?: Collections ) { const buttonName = collection ? collectionToButtonNameMap[ collection ] - : collectionToButtonNameMap.defaultQuery; + : collectionToButtonNameMap.productCatalog; await this.admin.page .frameLocator( 'iframe[name="editor-canvas"]' )