Product Collection: Redesigned Collection Insertion Selection (#48911)
* Updated Collection Selection Buttons Rather than using normal buttons we're going to replace these with cards that we want to use instead. * Reworked Product Catalog Creation * Added Dropdown Collection Option * Changelog * Added Collection Dashicon Support * Fixed Collection Change Modal This is going to get replaced soon but it may as well look nicer than it does right now. * Type Fix * Fixed `:focus` Hover Border * Simplified Click Handler * Style Fixes * Gutenberg Style Fixes * E2E Fixes * Fixed E2E Test * Added Dropdown Inserter E2E Support * Logging * Fixed Default Insertion Options * Prevent Premature Rendering * E2E Fix Attempt * Lint Fix * E2E Fix * Fix test chaking if custom registred collections are available in the collection chooser * Improve logic of choosing collection to cover both dropdown and placeholder --------- Co-authored-by: Karol Manijak <20098064+kmanijak@users.noreply.github.com>
This commit is contained in:
parent
dacee984fa
commit
7d71e2235a
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, chartBar } from '@wordpress/icons';
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { CoreCollectionNames, CoreFilterNames } from '../types';
|
|||
const collection = {
|
||||
name: CoreCollectionNames.BEST_SELLERS,
|
||||
title: __( 'Best Sellers', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ chartBar } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ chartBar } />,
|
||||
description: __( 'Recommend your best-selling products.', 'woocommerce' ),
|
||||
keywords: [ 'best selling', 'product collection' ],
|
||||
scope: [],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, starFilled } from '@wordpress/icons';
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { CoreCollectionNames, CoreFilterNames } from '../types';
|
|||
const collection = {
|
||||
name: CoreCollectionNames.FEATURED,
|
||||
title: __( 'Featured', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ starFilled } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ starFilled } />,
|
||||
description: __( 'Showcase your featured products.', 'woocommerce' ),
|
||||
keywords: [ 'product collection' ],
|
||||
scope: [],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, calendar } from '@wordpress/icons';
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {
|
|||
const collection = {
|
||||
name: CoreCollectionNames.NEW_ARRIVALS,
|
||||
title: __( 'New Arrivals', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ calendar } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ calendar } />,
|
||||
description: __( 'Recommend your newest products.', 'woocommerce' ),
|
||||
keywords: [ 'newest products', 'product collection' ],
|
||||
scope: [],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, percent } from '@wordpress/icons';
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { CoreCollectionNames, CoreFilterNames } from '../types';
|
|||
const collection = {
|
||||
name: CoreCollectionNames.ON_SALE,
|
||||
title: __( 'On Sale', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ percent } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ percent } />,
|
||||
description: __(
|
||||
'Highlight products that are currently on sale.',
|
||||
'woocommerce'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, loop } from '@wordpress/icons';
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { CoreCollectionNames } from '../types';
|
|||
const collection = {
|
||||
name: CoreCollectionNames.PRODUCT_CATALOG,
|
||||
title: __( 'Product Catalog', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ loop } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ loop } />,
|
||||
description:
|
||||
'Display all products in your catalog. Results can (change to) match the current template, page, or search term.',
|
||||
keywords: [ 'all products' ],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { InnerBlockTemplate, BlockIcon } from '@wordpress/blocks';
|
||||
import type { InnerBlockTemplate } from '@wordpress/blocks';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Icon, starEmpty } from '@wordpress/icons';
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { CoreCollectionNames, CoreFilterNames } from '../types';
|
|||
const collection = {
|
||||
name: CoreCollectionNames.TOP_RATED,
|
||||
title: __( 'Top Rated', 'woocommerce' ),
|
||||
icon: ( <Icon icon={ starEmpty } /> ) as BlockIcon,
|
||||
icon: <Icon icon={ starEmpty } />,
|
||||
description: __(
|
||||
'Recommend products with the highest review ratings.',
|
||||
'woocommerce'
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Button, Dropdown, Icon, Tooltip } from '@wordpress/components';
|
||||
import { useResizeObserver } from '@wordpress/compose';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
BlockInstance,
|
||||
createBlock,
|
||||
|
@ -10,6 +13,8 @@ import {
|
|||
createBlocksFromInnerBlocksTemplate,
|
||||
// @ts-expect-error Type definitions for this function are missing in Guteberg
|
||||
store as blocksStore,
|
||||
BlockVariation,
|
||||
BlockIcon,
|
||||
} from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
|
@ -21,13 +26,19 @@ import { getCollectionByName } from '../collections';
|
|||
import { getDefaultProductCollection } from '../utils';
|
||||
|
||||
type CollectionButtonProps = {
|
||||
active?: boolean;
|
||||
title: string;
|
||||
icon: string;
|
||||
description: string;
|
||||
icon: BlockIcon | undefined;
|
||||
description: string | undefined;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
type CollectionOptionsProps = {
|
||||
chosenCollection?: CollectionName | undefined;
|
||||
catalogVariation: BlockVariation;
|
||||
collectionVariations: BlockVariation[];
|
||||
onCollectionClick: ( name: string ) => void;
|
||||
};
|
||||
|
||||
export const applyCollection = (
|
||||
collectionName: CollectionName,
|
||||
clientId: string,
|
||||
|
@ -54,65 +65,165 @@ export const applyCollection = (
|
|||
};
|
||||
|
||||
const CollectionButton = ( {
|
||||
active = false,
|
||||
title,
|
||||
icon,
|
||||
description,
|
||||
onClick,
|
||||
}: CollectionButtonProps ) => {
|
||||
const variant = active ? 'primary' : 'secondary';
|
||||
|
||||
return (
|
||||
<Button
|
||||
className="wc-blocks-product-collection__collection-button"
|
||||
variant={ variant }
|
||||
onClick={ onClick }
|
||||
>
|
||||
<div className="wc-blocks-product-collection__collection-button-icon">
|
||||
{ icon }
|
||||
</div>
|
||||
<div className="wc-blocks-product-collection__collection-button-text">
|
||||
<Tooltip text={ description } placement="top">
|
||||
<Button
|
||||
className="wc-blocks-product-collection__collection-button"
|
||||
onClick={ onClick }
|
||||
>
|
||||
<div className="wc-blocks-product-collection__collection-button-icon">
|
||||
<Icon icon={ icon as Icon.IconType< BlockIcon > } />
|
||||
</div>
|
||||
<p className="wc-blocks-product-collection__collection-button-title">
|
||||
{ title }
|
||||
</p>
|
||||
<p className="wc-blocks-product-collection__collection-button-description">
|
||||
{ description }
|
||||
</p>
|
||||
</div>
|
||||
</Button>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const CollectionChooser = ( props: {
|
||||
chosenCollection?: CollectionName | undefined;
|
||||
onCollectionClick: ( name: string ) => void;
|
||||
} ) => {
|
||||
const { chosenCollection, onCollectionClick } = props;
|
||||
|
||||
// Get Collections
|
||||
const blockCollections = [
|
||||
...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 );
|
||||
}, [] ),
|
||||
];
|
||||
const CreateCollectionButton = ( props: CollectionButtonProps ) => {
|
||||
const { description, onClick } = props;
|
||||
|
||||
return (
|
||||
<div className="wc-blocks-product-collection__collections-section">
|
||||
{ blockCollections.map( ( { name, title, icon, description } ) => (
|
||||
<CollectionButton
|
||||
active={ chosenCollection === name }
|
||||
key={ name }
|
||||
title={ title }
|
||||
description={ description }
|
||||
icon={ icon }
|
||||
onClick={ () => onCollectionClick( name ) }
|
||||
/>
|
||||
) ) }
|
||||
<div className="wc-blocks-product-collection__collections-create">
|
||||
<span>{ __( 'or', 'woocommerce' ) }</span>
|
||||
<Tooltip text={ description } placement="top">
|
||||
<Button onClick={ onClick }>
|
||||
{ __( 'create your own', 'woocommerce' ) }
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const GridCollectionOptions = ( props: CollectionOptionsProps ) => {
|
||||
const { onCollectionClick, catalogVariation, collectionVariations } = props;
|
||||
|
||||
return (
|
||||
<div className="wc-blocks-product-collection__collections-grid">
|
||||
<div className="wc-blocks-product-collection__collections-section">
|
||||
{ collectionVariations.map(
|
||||
( { name, title, icon, description } ) => (
|
||||
<CollectionButton
|
||||
key={ name }
|
||||
title={ title }
|
||||
description={ description }
|
||||
icon={ icon }
|
||||
onClick={ () => onCollectionClick( name ) }
|
||||
/>
|
||||
)
|
||||
) }
|
||||
</div>
|
||||
<CreateCollectionButton
|
||||
title={ catalogVariation.title }
|
||||
description={ catalogVariation.description }
|
||||
icon={ catalogVariation.icon }
|
||||
onClick={ () => onCollectionClick( catalogVariation.name ) }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownCollectionOptions = ( props: CollectionOptionsProps ) => {
|
||||
const { onCollectionClick, catalogVariation, collectionVariations } = props;
|
||||
|
||||
return (
|
||||
<div className="wc-blocks-product-collection__collections-dropdown">
|
||||
<Dropdown
|
||||
className="wc-blocks-product-collection__collections-dropdown-toggle"
|
||||
contentClassName="wc-blocks-product-collection__collections-dropdown-content"
|
||||
renderToggle={ ( { isOpen, onToggle } ) => (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ onToggle }
|
||||
aria-expanded={ isOpen }
|
||||
>
|
||||
{ __( 'Choose collection', 'woocommerce' ) }
|
||||
</Button>
|
||||
) }
|
||||
renderContent={ () => (
|
||||
<>
|
||||
{ collectionVariations.map(
|
||||
( { name, title, icon, description } ) => (
|
||||
<CollectionButton
|
||||
key={ name }
|
||||
title={ title }
|
||||
description={ description }
|
||||
icon={ icon }
|
||||
onClick={ () => onCollectionClick( name ) }
|
||||
/>
|
||||
)
|
||||
) }
|
||||
</>
|
||||
) }
|
||||
></Dropdown>
|
||||
<CreateCollectionButton
|
||||
title={ catalogVariation.title }
|
||||
description={ catalogVariation.description }
|
||||
icon={ catalogVariation.icon }
|
||||
onClick={ () => onCollectionClick( catalogVariation.name ) }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const CollectionChooser = (
|
||||
props: Pick<
|
||||
CollectionOptionsProps,
|
||||
'chosenCollection' | 'onCollectionClick'
|
||||
>
|
||||
) => {
|
||||
// Get Collections
|
||||
const blockCollections = 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 );
|
||||
}, [] ) as BlockVariation[];
|
||||
|
||||
const productCatalog = useMemo(
|
||||
() =>
|
||||
blockCollections.find(
|
||||
( { name } ) => name === CoreCollectionNames.PRODUCT_CATALOG
|
||||
) as BlockVariation,
|
||||
[ blockCollections ]
|
||||
);
|
||||
|
||||
const collectionVariations = useMemo(
|
||||
() =>
|
||||
blockCollections.filter(
|
||||
( { name } ) => name !== CoreCollectionNames.PRODUCT_CATALOG
|
||||
) as BlockVariation[],
|
||||
[ blockCollections ]
|
||||
);
|
||||
|
||||
const [ resizeListener, { width } ] = useResizeObserver();
|
||||
|
||||
let OptionsComponent;
|
||||
if ( width !== null && width >= 600 ) {
|
||||
OptionsComponent = GridCollectionOptions;
|
||||
} else {
|
||||
OptionsComponent = DropdownCollectionOptions;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ resizeListener }
|
||||
{ !! width && (
|
||||
<OptionsComponent
|
||||
{ ...props }
|
||||
catalogVariation={ productCatalog }
|
||||
collectionVariations={ collectionVariations }
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollectionChooser;
|
||||
|
|
|
@ -36,18 +36,12 @@ const PatternSelectionModal = ( props: {
|
|||
return (
|
||||
<Modal
|
||||
overlayClassName="wc-blocks-product-collection__modal"
|
||||
title={ __( 'Choose a collection', 'woocommerce' ) }
|
||||
title={ __( 'What products do you want to show?', 'woocommerce' ) }
|
||||
onRequestClose={ props.closePatternSelectionModal }
|
||||
// @ts-expect-error Type definitions are missing in the version we are using i.e. 19.1.5,
|
||||
size={ 'large' }
|
||||
>
|
||||
<div className="wc-blocks-product-collection__content">
|
||||
<p className="wc-blocks-product-collection__subtitle">
|
||||
{ __(
|
||||
"Pick what products are shown. Don't worry, you can switch and tweak this collection any time.",
|
||||
'woocommerce'
|
||||
) }
|
||||
</p>
|
||||
<CollectionChooser
|
||||
chosenCollection={ chosenCollection }
|
||||
onCollectionClick={ selectCollectionName }
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
$max-columns: 3;
|
||||
$min-button-width: 250px;
|
||||
$gap-count: calc(#{$max-columns} - 1);
|
||||
$total-gap-width: calc(#{$gap-count} * #{$gap-small});
|
||||
$max-button-width: calc((100% - #{$total-gap-width}) / #{$max-columns});
|
||||
$max-button-columns: 6;
|
||||
$min-button-width: 80px;
|
||||
$max-button-width: calc(100% / #{$max-button-columns});
|
||||
|
||||
.wc-block-editor-product-collection-inspector-toolspanel__filters {
|
||||
.wc-block-editor-product-collection-inspector__taxonomy-control:not(:last-child) {
|
||||
|
@ -17,11 +15,18 @@ $max-button-width: calc((100% - #{$total-gap-width}) / #{$max-columns});
|
|||
}
|
||||
|
||||
// Need to override high-specificity styles
|
||||
.wc-blocks-product-collection__placeholder.is-medium {
|
||||
.wc-blocks-product-collection__placeholder {
|
||||
.components-placeholder__fieldset {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.is-medium,
|
||||
&.is-small {
|
||||
.components-button {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.components-button.wc-blocks-product-collection__collection-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -29,58 +34,87 @@ $max-button-width: calc((100% - #{$total-gap-width}) / #{$max-columns});
|
|||
|
||||
.wc-blocks-product-collection__placeholder,
|
||||
.wc-blocks-product-collection__modal {
|
||||
.components-placeholder__instructions {
|
||||
width: 100%;
|
||||
margin: $gap-small 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collections-grid {
|
||||
.wc-blocks-product-collection__collections-create {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collections-dropdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__selection-subtitle {
|
||||
margin-bottom: $gap-large;
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collections-section {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(#{$min-button-width}, #{$max-button-width}), 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(max(#{$min-button-width}, #{$max-button-width}), 1fr));
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: $gap-small;
|
||||
margin: $gap-large auto;
|
||||
margin: $gap-small auto;
|
||||
max-width: 1000px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collection-button {
|
||||
color: var(--wp-admin-theme-color);
|
||||
box-shadow: none;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
height: auto;
|
||||
border-radius: $universal-border-radius;
|
||||
box-sizing: border-box;
|
||||
padding: $gap-smallest $gap-small;
|
||||
padding: $gap-small;
|
||||
margin: 0;
|
||||
|
||||
&.is-primary {
|
||||
box-shadow: 0 0 0 2px var(--wp-admin-theme-color, #3858e9);
|
||||
color: var(--wp-admin-theme-color-darker-20);
|
||||
background-color: var(--wc-content-bg, #fff);
|
||||
&:hover {
|
||||
color: var(--wp-admin-theme-color);
|
||||
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.04);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--wc-content-bg, #fff);
|
||||
color: var(--wp-admin-theme-color-darker-20);
|
||||
&:not(:focus) {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collection-button-icon {
|
||||
margin: 1em 0;
|
||||
&:focus {
|
||||
color: var(--wp-admin-theme-color);
|
||||
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collection-button-text {
|
||||
padding: 0 $gap-small;
|
||||
text-align: left;
|
||||
white-space: break-spaces;
|
||||
&-icon {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collection-button-title {
|
||||
@include font-size(large);
|
||||
line-height: 1;
|
||||
&-title {
|
||||
@include font-size(small);
|
||||
width: 100%;
|
||||
text-wrap: balance;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collection-button-description {
|
||||
white-space: wrap;
|
||||
.wc-blocks-product-collection__collections-create {
|
||||
padding: 0 $gap-smallest;
|
||||
text-align: center;
|
||||
|
||||
button {
|
||||
color: var(--wp-admin-theme-color);
|
||||
padding: 0;
|
||||
margin-left: $gap-smallest;
|
||||
|
||||
&:hover {
|
||||
color: var(--wp-admin-theme-color-darker-20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +124,15 @@ $max-button-width: calc((100% - #{$total-gap-width}) / #{$max-columns});
|
|||
}
|
||||
}
|
||||
|
||||
.wc-blocks-product-collection__collections-dropdown-content {
|
||||
.components-popover__content {
|
||||
width: 20em;
|
||||
display: flex;
|
||||
flex: flex-grow;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
// Price Range Filter
|
||||
.wc-block-product-price-range-control {
|
||||
input {
|
||||
|
|
|
@ -19,7 +19,6 @@ import type {
|
|||
CollectionName,
|
||||
ProductCollectionEditComponentProps,
|
||||
} from '../types';
|
||||
import Icon from '../icon';
|
||||
|
||||
const ProductCollectionPlaceholder = (
|
||||
props: ProductCollectionEditComponentProps
|
||||
|
@ -47,10 +46,8 @@ const ProductCollectionPlaceholder = (
|
|||
<div { ...blockProps }>
|
||||
<Placeholder
|
||||
className="wc-blocks-product-collection__placeholder"
|
||||
icon={ Icon }
|
||||
label={ __( 'Product Collection', 'woocommerce' ) }
|
||||
instructions={ __(
|
||||
"Choose a collection to get started. Don't worry, you can change and tweak this any time.",
|
||||
'What products do you want to show?',
|
||||
'woocommerce'
|
||||
) }
|
||||
>
|
||||
|
|
|
@ -1419,9 +1419,15 @@ test.describe( 'Testing registerProductCollection', () => {
|
|||
pageObject,
|
||||
editor,
|
||||
admin,
|
||||
page,
|
||||
} ) => {
|
||||
await admin.createNewPost();
|
||||
await editor.insertBlockUsingGlobalInserter( pageObject.BLOCK_NAME );
|
||||
await page
|
||||
.getByRole( 'button', {
|
||||
name: 'Choose collection',
|
||||
} )
|
||||
.click();
|
||||
|
||||
// Get text of all buttons in the collection chooser
|
||||
const collectionChooserButtonsTexts = await editor.page
|
||||
|
|
|
@ -60,6 +60,8 @@ export const SELECTORS = {
|
|||
max: 'MAX',
|
||||
},
|
||||
previewButtonTestID: 'product-collection-preview-button',
|
||||
collectionPlaceholder:
|
||||
'[data-type="woocommerce/product-collection"] .components-placeholder',
|
||||
};
|
||||
|
||||
export type Collections =
|
||||
|
@ -74,18 +76,16 @@ export type Collections =
|
|||
| 'myCustomCollectionWithAdvancedPreview';
|
||||
|
||||
const collectionToButtonNameMap = {
|
||||
newArrivals: 'New Arrivals Recommend your newest products.',
|
||||
topRated: 'Top Rated Recommend products with the highest review ratings.',
|
||||
bestSellers: 'Best Sellers Recommend your best-selling products.',
|
||||
onSale: 'On Sale Highlight products that are currently on sale.',
|
||||
featured: 'Featured Showcase your featured products.',
|
||||
productCatalog:
|
||||
'Product Catalog Display all products in your catalog. Results can (change to) match the current template, page, or search term.',
|
||||
myCustomCollection: 'My Custom Collection This is a custom collection.',
|
||||
myCustomCollectionWithPreview:
|
||||
'My Custom Collection with Preview This is a custom collection with preview.',
|
||||
newArrivals: 'New Arrivals',
|
||||
topRated: 'Top Rated',
|
||||
bestSellers: 'Best Sellers',
|
||||
onSale: 'On Sale',
|
||||
featured: 'Featured',
|
||||
productCatalog: 'create your own',
|
||||
myCustomCollection: 'My Custom Collection',
|
||||
myCustomCollectionWithPreview: 'My Custom Collection with Preview',
|
||||
myCustomCollectionWithAdvancedPreview:
|
||||
'My Custom Collection with Advanced Preview This is a custom collection with advanced preview.',
|
||||
'My Custom Collection with Advanced Preview',
|
||||
};
|
||||
|
||||
class ProductCollectionPage {
|
||||
|
@ -121,9 +121,35 @@ class ProductCollectionPage {
|
|||
? collectionToButtonNameMap[ collection ]
|
||||
: collectionToButtonNameMap.productCatalog;
|
||||
|
||||
await this.admin.page
|
||||
.getByRole( 'button', { name: buttonName } )
|
||||
.click();
|
||||
const placeholderSelector = this.admin.page.locator(
|
||||
SELECTORS.collectionPlaceholder
|
||||
);
|
||||
|
||||
const chooseCollectionFromPlaceholder = async () => {
|
||||
await placeholderSelector
|
||||
.getByRole( 'button', { name: buttonName, exact: true } )
|
||||
.click();
|
||||
};
|
||||
|
||||
const chooseCollectionFromDropdown = async () => {
|
||||
await placeholderSelector
|
||||
.getByRole( 'button', {
|
||||
name: 'Choose collection',
|
||||
} )
|
||||
.click();
|
||||
|
||||
await this.admin.page
|
||||
.locator(
|
||||
'.wc-blocks-product-collection__collections-dropdown-content'
|
||||
)
|
||||
.getByRole( 'button', { name: buttonName, exact: true } )
|
||||
.click();
|
||||
};
|
||||
|
||||
await Promise.any( [
|
||||
chooseCollectionFromPlaceholder(),
|
||||
chooseCollectionFromDropdown(),
|
||||
] );
|
||||
}
|
||||
|
||||
async chooseCollectionInTemplate( collection?: Collections ) {
|
||||
|
@ -131,9 +157,34 @@ class ProductCollectionPage {
|
|||
? collectionToButtonNameMap[ collection ]
|
||||
: collectionToButtonNameMap.productCatalog;
|
||||
|
||||
await this.editor.canvas
|
||||
.getByRole( 'button', { name: buttonName } )
|
||||
.click();
|
||||
const inserterClass = await this.editor.canvas
|
||||
.locator( SELECTORS.collectionPlaceholder )
|
||||
.locator(
|
||||
'.wc-blocks-product-collection__collections-grid, .wc-blocks-product-collection__collections-dropdown'
|
||||
)
|
||||
.getAttribute( 'class' );
|
||||
|
||||
const isDropdown = inserterClass?.includes(
|
||||
'wc-blocks-product-collection__collections-dropdown'
|
||||
);
|
||||
|
||||
if ( isDropdown ) {
|
||||
await this.editor.canvas
|
||||
.getByRole( 'button', { name: 'Choose collection' } )
|
||||
.click();
|
||||
|
||||
await this.editor.canvas
|
||||
.locator(
|
||||
'.wc-blocks-product-collection__collections-dropdown-content'
|
||||
)
|
||||
.getByRole( 'button', { name: buttonName, exact: true } )
|
||||
.click();
|
||||
} else {
|
||||
await this.editor.canvas
|
||||
.locator( SELECTORS.collectionPlaceholder )
|
||||
.getByRole( 'button', { name: buttonName, exact: true } )
|
||||
.click();
|
||||
}
|
||||
}
|
||||
|
||||
async createNewPostAndInsertBlock( collection?: Collections ) {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Redesigned the Product Collection block's insertion journey.
|
|
@ -299,8 +299,11 @@ test.describe(
|
|||
|
||||
// Product Collection requires choosing some collection.
|
||||
await page
|
||||
.locator(
|
||||
'[data-type="woocommerce/product-collection"] .components-placeholder'
|
||||
)
|
||||
.getByRole( 'button', {
|
||||
name: 'Product Catalog Display all products in your catalog. Results can (change to) match the current template, page, or search term.',
|
||||
name: 'create your own',
|
||||
} )
|
||||
.click();
|
||||
|
||||
|
|
Loading…
Reference in New Issue