Show a summary when adding or removing variation option values (#40470)
* Fix server error when generating variations after delete an attribute term, stock_quentity=null and low_stock_amount=null brake * Show a summary when adding or removing variation option values * Fix linter error * Make sure to show variations notice only if the attribute is used for variation
This commit is contained in:
parent
53e53c9a63
commit
43a238d730
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Show a summary when adding or removing variation option values
|
|
@ -354,6 +354,7 @@ export const AttributeControl: React.FC< AttributeControlProps > = ( {
|
||||||
handleEdit( updatedAttribute );
|
handleEdit( updatedAttribute );
|
||||||
} }
|
} }
|
||||||
attribute={ currentAttribute }
|
attribute={ currentAttribute }
|
||||||
|
attributes={ value }
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
{ removingAttribute && (
|
{ removingAttribute && (
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Modal,
|
Modal,
|
||||||
CheckboxControl,
|
CheckboxControl,
|
||||||
TextControl,
|
TextControl,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
import { useState, createElement, Fragment } from '@wordpress/element';
|
import { useState, createElement, Fragment, useMemo } from '@wordpress/element';
|
||||||
import {
|
import {
|
||||||
__experimentalTooltip as Tooltip,
|
__experimentalTooltip as Tooltip,
|
||||||
__experimentalSelectControlMenuSlot as SelectControlMenuSlot,
|
__experimentalSelectControlMenuSlot as SelectControlMenuSlot,
|
||||||
|
@ -22,6 +22,8 @@ import {
|
||||||
CustomAttributeTermInputField,
|
CustomAttributeTermInputField,
|
||||||
} from '../attribute-term-input-field';
|
} from '../attribute-term-input-field';
|
||||||
import { EnhancedProductAttribute } from '../../hooks/use-product-attributes';
|
import { EnhancedProductAttribute } from '../../hooks/use-product-attributes';
|
||||||
|
import { Notice } from '../notice';
|
||||||
|
import { getAttributeId } from './utils';
|
||||||
|
|
||||||
type EditAttributeModalProps = {
|
type EditAttributeModalProps = {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -43,6 +45,7 @@ type EditAttributeModalProps = {
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
onEdit: ( alteredAttribute: EnhancedProductAttribute ) => void;
|
onEdit: ( alteredAttribute: EnhancedProductAttribute ) => void;
|
||||||
attribute: EnhancedProductAttribute;
|
attribute: EnhancedProductAttribute;
|
||||||
|
attributes: EnhancedProductAttribute[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
|
export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
|
||||||
|
@ -77,6 +80,7 @@ export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
|
||||||
onCancel,
|
onCancel,
|
||||||
onEdit,
|
onEdit,
|
||||||
attribute,
|
attribute,
|
||||||
|
attributes,
|
||||||
} ) => {
|
} ) => {
|
||||||
const [ editableAttribute, setEditableAttribute ] = useState<
|
const [ editableAttribute, setEditableAttribute ] = useState<
|
||||||
EnhancedProductAttribute | undefined
|
EnhancedProductAttribute | undefined
|
||||||
|
@ -84,6 +88,71 @@ export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
|
||||||
|
|
||||||
const isCustomAttribute = editableAttribute?.id === 0;
|
const isCustomAttribute = editableAttribute?.id === 0;
|
||||||
|
|
||||||
|
const { additions, deletions } = useMemo( () => {
|
||||||
|
if ( ! attribute.variation ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const variationsSubTotal = attributes
|
||||||
|
.filter(
|
||||||
|
( otherAttribute ) =>
|
||||||
|
getAttributeId( otherAttribute ) !==
|
||||||
|
getAttributeId( attribute )
|
||||||
|
)
|
||||||
|
.reduce(
|
||||||
|
( subTotal, { terms } ) => subTotal * ( terms?.length ?? 1 ),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentAttributeTermsCount = attribute.terms?.length ?? 0;
|
||||||
|
const variationsTotal = variationsSubTotal * currentAttributeTermsCount;
|
||||||
|
|
||||||
|
const addedTermsCount =
|
||||||
|
editableAttribute?.terms?.filter(
|
||||||
|
( editedTerm ) =>
|
||||||
|
! attribute.terms?.some(
|
||||||
|
( currentTerm ) => currentTerm.id === editedTerm.id
|
||||||
|
)
|
||||||
|
)?.length ?? 0;
|
||||||
|
const addedTermsTotal =
|
||||||
|
currentAttributeTermsCount + addedTermsCount || 1;
|
||||||
|
|
||||||
|
const remainedTermsCount =
|
||||||
|
attribute.terms?.filter( ( currentTerm ) =>
|
||||||
|
editableAttribute?.terms?.some(
|
||||||
|
( editedTerm ) => currentTerm.id === editedTerm.id
|
||||||
|
)
|
||||||
|
)?.length ?? 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
additions: Math.abs(
|
||||||
|
variationsTotal - variationsSubTotal * addedTermsTotal
|
||||||
|
),
|
||||||
|
deletions: Math.abs(
|
||||||
|
variationsTotal - variationsSubTotal * remainedTermsCount
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}, [ attributes, attribute, editableAttribute ] );
|
||||||
|
|
||||||
|
function getNoticeMessage() {
|
||||||
|
const additionsMessage = sprintf(
|
||||||
|
// translators: %d is the amount of variations to be added
|
||||||
|
__( '%d variations will be added', 'woocommerce' ),
|
||||||
|
additions
|
||||||
|
);
|
||||||
|
const deletionsMessage = sprintf(
|
||||||
|
// translators: %d is the amount of variations to be removed
|
||||||
|
__( '%d variations will be removed', 'woocommerce' ),
|
||||||
|
deletions
|
||||||
|
);
|
||||||
|
if ( additions && deletions ) {
|
||||||
|
return sprintf( '%s, %s.', additionsMessage, deletionsMessage );
|
||||||
|
} else if ( additions ) {
|
||||||
|
return sprintf( '%s.', additionsMessage );
|
||||||
|
}
|
||||||
|
return sprintf( '%s.', deletionsMessage );
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -186,6 +255,10 @@ export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
|
||||||
</div>
|
</div>
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{ Boolean( additions || deletions ) && (
|
||||||
|
<Notice>{ getNoticeMessage() }</Notice>
|
||||||
|
) }
|
||||||
</div>
|
</div>
|
||||||
<div className="woocommerce-edit-attribute-modal__buttons">
|
<div className="woocommerce-edit-attribute-modal__buttons">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -43,10 +43,10 @@ async function getDefaultVariationValues(
|
||||||
if ( products && products.length > 0 && products[ 0 ].regular_price ) {
|
if ( products && products.length > 0 && products[ 0 ].regular_price ) {
|
||||||
return {
|
return {
|
||||||
regular_price: products[ 0 ].regular_price,
|
regular_price: products[ 0 ].regular_price,
|
||||||
stock_quantity: products[ 0 ].stock_quantity,
|
stock_quantity: products[ 0 ].stock_quantity ?? undefined,
|
||||||
stock_status: products[ 0 ].stock_status,
|
stock_status: products[ 0 ].stock_status,
|
||||||
manage_stock: products[ 0 ].manage_stock,
|
manage_stock: products[ 0 ].manage_stock,
|
||||||
low_stock_amount: products[ 0 ].low_stock_amount,
|
low_stock_amount: products[ 0 ].low_stock_amount ?? undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
Loading…
Reference in New Issue