Add reorder grouped products option (#42766)
* Add re-order modal * Consolidate some of the styling and components * Add changelog * Only show reorder when products are added, and remove 'x' from reorder modal
This commit is contained in:
parent
3042b9fba6
commit
b406a084e4
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Update products list field to add re-order option.
|
|
@ -24,6 +24,7 @@ import classNames from 'classnames';
|
|||
import {
|
||||
AddProductsModal,
|
||||
getProductImageStyle,
|
||||
ReorderProductsModal,
|
||||
} from '../../../components/add-products-modal';
|
||||
import { ProductEditorBlockEditProps } from '../../../types';
|
||||
import { Shirt, Pants, Glasses } from './images';
|
||||
|
@ -40,6 +41,8 @@ export function Edit( {
|
|||
const { property } = attributes;
|
||||
const blockProps = useWooBlockProps( attributes );
|
||||
const [ openAddProductsModal, setOpenAddProductsModal ] = useState( false );
|
||||
const [ openReorderProductsModal, setOpenReorderProductsModal ] =
|
||||
useState( false );
|
||||
const [ isLoading, setIsLoading ] = useState( false );
|
||||
const [ preventFetch, setPreventFetch ] = useState( false );
|
||||
const [ groupedProductIds, setGroupedProductIds ] = useEntityProp<
|
||||
|
@ -72,6 +75,10 @@ export function Edit( {
|
|||
setOpenAddProductsModal( true );
|
||||
}
|
||||
|
||||
function handleReorderProductsButtonClick() {
|
||||
setOpenReorderProductsModal( true );
|
||||
}
|
||||
|
||||
function handleAddProductsModalSubmit( value: Product[] ) {
|
||||
const newGroupedProducts = [ ...groupedProducts, ...value ];
|
||||
setPreventFetch( true );
|
||||
|
@ -82,10 +89,20 @@ export function Edit( {
|
|||
setOpenAddProductsModal( false );
|
||||
}
|
||||
|
||||
function handleReorderProductsModalSubmit( value: Product[] ) {
|
||||
setGroupedProducts( value );
|
||||
setGroupedProductIds( value.map( ( product ) => product.id ) );
|
||||
setOpenReorderProductsModal( false );
|
||||
}
|
||||
|
||||
function handleAddProductsModalClose() {
|
||||
setOpenAddProductsModal( false );
|
||||
}
|
||||
|
||||
function handleReorderProductsModalClose() {
|
||||
setOpenReorderProductsModal( false );
|
||||
}
|
||||
|
||||
function removeProductHandler( product: Product ) {
|
||||
return function handleRemoveClick() {
|
||||
const newGroupedProducts = groupedProducts.filter(
|
||||
|
@ -104,6 +121,14 @@ export function Edit( {
|
|||
return (
|
||||
<div { ...blockProps }>
|
||||
<div className="wp-block-woocommerce-product-list-field__header">
|
||||
{ ! isLoading && groupedProducts.length > 0 && (
|
||||
<Button
|
||||
onClick={ handleReorderProductsButtonClick }
|
||||
variant="tertiary"
|
||||
>
|
||||
{ __( 'Reorder', 'woocommerce' ) }
|
||||
</Button>
|
||||
) }
|
||||
<Button
|
||||
onClick={ handleAddProductsButtonClick }
|
||||
variant="secondary"
|
||||
|
@ -294,6 +319,13 @@ export function Edit( {
|
|||
onClose={ handleAddProductsModalClose }
|
||||
/>
|
||||
) }
|
||||
{ openReorderProductsModal && (
|
||||
<ReorderProductsModal
|
||||
products={ groupedProducts }
|
||||
onSubmit={ handleReorderProductsModalSubmit }
|
||||
onClose={ handleReorderProductsModalClose }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
gap: $gap-smaller;
|
||||
}
|
||||
|
||||
&__empty-state {
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
useState,
|
||||
} from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { closeSmall, dragHandle } from '@wordpress/icons';
|
||||
import { closeSmall } from '@wordpress/icons';
|
||||
import {
|
||||
__experimentalSelectControl as SelectControl,
|
||||
__experimentalSelectControlMenu as Menu,
|
||||
|
@ -21,13 +21,11 @@ import {
|
|||
} from '@woocommerce/components';
|
||||
import { CurrencyContext } from '@woocommerce/currency';
|
||||
import { PRODUCTS_STORE_NAME, Product } from '@woocommerce/data';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { AddProductsModalProps } from './types';
|
||||
import { useDraggable } from '../../hooks/use-draggable';
|
||||
|
||||
export function getProductImageStyle( product: Product ) {
|
||||
return product.images.length > 0
|
||||
|
@ -103,10 +101,6 @@ export function AddProductsModal( {
|
|||
};
|
||||
}
|
||||
|
||||
const { container, draggable, handler } = useDraggable( {
|
||||
onSort: setSelectedProducts,
|
||||
} );
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={ __( 'Add products to this group', 'woocommerce' ) }
|
||||
|
@ -204,29 +198,12 @@ export function AddProductsModal( {
|
|||
</div>
|
||||
|
||||
{ Boolean( selectedProducts.length ) && (
|
||||
<ul
|
||||
{ ...container }
|
||||
className={ classNames(
|
||||
'woocommerce-add-products-modal__list',
|
||||
container.className
|
||||
) }
|
||||
>
|
||||
<ul className="woocommerce-add-products-modal__list">
|
||||
{ selectedProducts.map( ( item ) => (
|
||||
<li
|
||||
{ ...draggable }
|
||||
key={ item.id }
|
||||
className="woocommerce-add-products-modal__list-item"
|
||||
>
|
||||
<Button
|
||||
{ ...handler }
|
||||
icon={ dragHandle }
|
||||
variant="tertiary"
|
||||
type="button"
|
||||
aria-label={ __(
|
||||
'Sortable handler',
|
||||
'woocommerce'
|
||||
) }
|
||||
/>
|
||||
<div
|
||||
className="woocommerce-add-products-modal__list-item-image"
|
||||
style={ getProductImageStyle( item ) }
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
export * from './add-products-modal';
|
||||
export * from './reorder-products-modal';
|
||||
export * from './types';
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { FormEvent } from 'react';
|
||||
import { Button, Modal } from '@wordpress/components';
|
||||
import { createElement, useState } from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { dragHandle } from '@wordpress/icons';
|
||||
import { Product } from '@woocommerce/data';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ReorderProductsModalProps } from './types';
|
||||
import { useDraggable } from '../../hooks/use-draggable';
|
||||
import { getProductImageStyle } from './add-products-modal';
|
||||
|
||||
export function ReorderProductsModal( {
|
||||
products,
|
||||
onSubmit,
|
||||
onClose,
|
||||
}: ReorderProductsModalProps ) {
|
||||
const [ selectedProducts, setSelectedProducts ] = useState< Product[] >( [
|
||||
...products,
|
||||
] );
|
||||
|
||||
function handleSubmit( event: FormEvent< HTMLFormElement > ) {
|
||||
event.preventDefault();
|
||||
|
||||
onSubmit( [ ...selectedProducts ] );
|
||||
}
|
||||
|
||||
function handleCancelClick() {
|
||||
onClose();
|
||||
}
|
||||
|
||||
const { container, draggable, handler } = useDraggable( {
|
||||
onSort: setSelectedProducts,
|
||||
} );
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={ __( 'Reorder products in this group', 'woocommerce' ) }
|
||||
className="woocommerce-reorder-products-modal"
|
||||
onRequestClose={ onClose }
|
||||
>
|
||||
<form
|
||||
noValidate
|
||||
onSubmit={ handleSubmit }
|
||||
className="woocommerce-add-products-modal__form"
|
||||
>
|
||||
<fieldset className="woocommerce-add-products-modal__form-group">
|
||||
<legend className="woocommerce-add-products-modal__form-group-title">
|
||||
{ __(
|
||||
'Click and drag to reorder on the product page.',
|
||||
'woocommerce'
|
||||
) }
|
||||
</legend>
|
||||
|
||||
{ Boolean( selectedProducts.length ) && (
|
||||
<ul
|
||||
{ ...container }
|
||||
className={ classNames(
|
||||
'woocommerce-add-products-modal__list',
|
||||
container.className
|
||||
) }
|
||||
>
|
||||
{ selectedProducts.map( ( item ) => (
|
||||
<li
|
||||
{ ...draggable }
|
||||
key={ item.id }
|
||||
className="woocommerce-add-products-modal__list-item"
|
||||
>
|
||||
<Button
|
||||
{ ...handler }
|
||||
icon={ dragHandle }
|
||||
variant="tertiary"
|
||||
type="button"
|
||||
aria-label={ __(
|
||||
'Sortable handler',
|
||||
'woocommerce'
|
||||
) }
|
||||
/>
|
||||
<div
|
||||
className="woocommerce-add-products-modal__list-item-image"
|
||||
style={ getProductImageStyle( item ) }
|
||||
/>
|
||||
<div className="woocommerce-add-products-modal__list-item-content">
|
||||
<div className="woocommerce-add-products-modal__list-item-title">
|
||||
{ item.name }
|
||||
</div>
|
||||
|
||||
<div className="woocommerce-add-products-modal__list-item-description">
|
||||
{ item.sku }
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
) ) }
|
||||
</ul>
|
||||
) }
|
||||
</fieldset>
|
||||
|
||||
<div className="woocommerce-add-products-modal__actions">
|
||||
<Button
|
||||
variant="tertiary"
|
||||
type="button"
|
||||
onClick={ handleCancelClick }
|
||||
>
|
||||
{ __( 'Cancel', 'woocommerce' ) }
|
||||
</Button>
|
||||
<Button variant="primary" type="submit">
|
||||
{ __( 'Done', 'woocommerce' ) }
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
.woocommerce-add-products-modal {
|
||||
.woocommerce-add-products-modal,
|
||||
.woocommerce-reorder-products-modal {
|
||||
@include breakpoint(">600px") {
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Product } from '@woocommerce/data';
|
||||
import type { Product } from '@woocommerce/data';
|
||||
|
||||
export type AddProductsModalProps = {
|
||||
initialValue: Product[];
|
||||
onSubmit( value: Product[] ): void;
|
||||
onClose(): void;
|
||||
};
|
||||
|
||||
export type ReorderProductsModalProps = {
|
||||
products: Product[];
|
||||
onSubmit( value: Product[] ): void;
|
||||
onClose(): void;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue