Commit 5f8ff204f43 for woocommerce
commit 5f8ff204f43f1b62b9a28fe42ed84a4171cc9682
Author: Luigi Teschio <gigitux@gmail.com>
Date: Fri May 15 12:52:00 2026 +0200
Update products quick edit fields (#65001)
* Update products quick edit fields
* Add changelog entry for products quick edit fields
diff --git a/packages/js/experimental-products-app/changelog/update-products-quick-edit-fields b/packages/js/experimental-products-app/changelog/update-products-quick-edit-fields
new file mode 100644
index 00000000000..fb256dd90c1
--- /dev/null
+++ b/packages/js/experimental-products-app/changelog/update-products-quick-edit-fields
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Update quick edit fields for simple, variable parent, and variation products.
diff --git a/packages/js/experimental-products-app/src/fields/components/dimension.tsx b/packages/js/experimental-products-app/src/fields/components/dimension.tsx
index 42fce7e14ff..abeb39add05 100644
--- a/packages/js/experimental-products-app/src/fields/components/dimension.tsx
+++ b/packages/js/experimental-products-app/src/fields/components/dimension.tsx
@@ -14,10 +14,13 @@ import type { ProductEntityRecord, SettingsEntityRecord } from '../types';
export type DimensionKey = 'height' | 'width' | 'length';
export function isDimensionVisible( item: ProductEntityRecord ) {
- return (
- ! item.virtual &&
- ( ( item.type === 'simple' && ! item.parent_id ) || item.downloadable )
- );
+ const isSellableInstance =
+ ( item.type === 'simple' && ! item.parent_id ) ||
+ ( item.type === 'variable' && ! item.parent_id ) ||
+ item.type === 'variation' ||
+ Boolean( item.parent_id );
+
+ return ! item.virtual && ( isSellableInstance || item.downloadable );
}
export const createDimensionField = (
diff --git a/packages/js/experimental-products-app/src/product-edit/utils.test.ts b/packages/js/experimental-products-app/src/product-edit/utils.test.ts
index 69373177989..7c518ba9057 100644
--- a/packages/js/experimental-products-app/src/product-edit/utils.test.ts
+++ b/packages/js/experimental-products-app/src/product-edit/utils.test.ts
@@ -293,7 +293,6 @@ describe( 'product edit utils', () => {
'name',
'short_description',
'description',
- 'product_status',
'catalog_visibility',
'categories',
'brands',
@@ -357,6 +356,7 @@ describe( 'product edit utils', () => {
'categories',
'brands',
'tags',
+ 'featured',
'weight',
'length',
'width',
@@ -374,7 +374,6 @@ describe( 'product edit utils', () => {
'tax_status',
'upsell_ids',
'cross_sell_ids',
- 'featured',
] );
} );
@@ -519,7 +518,7 @@ describe( 'product edit utils', () => {
] );
} );
- it( 'hides parent pricing and downloads for variable products', () => {
+ it( 'shows variable parent fields in quick edit order', () => {
const fieldIds = getVisibleFieldIds( [
buildProduct( {
type: 'variable',
@@ -535,23 +534,31 @@ describe( 'product edit utils', () => {
'date_on_sale_to',
'downloadable',
] );
- expect( fieldIds ).toEqual(
- expect.arrayContaining( [
- 'sku',
- 'upsell_ids',
- 'cross_sell_ids',
- 'stock',
- 'manage_stock',
- 'shipping_class',
- 'tax_status',
- ] )
- );
- expectFieldsHidden( fieldIds, [
- 'stock_quantity',
- 'weight',
+ expect( fieldIds ).toEqual( [
+ 'name',
+ 'product_status',
+ 'catalog_visibility',
+ 'images',
+ 'sku',
+ 'manage_stock',
+ 'stock',
+ 'categories',
+ 'brands',
+ 'tags',
+ 'featured',
+ 'shipping_class',
'length',
'width',
'height',
+ 'weight',
+ ] );
+ expectFieldsHidden( fieldIds, [
+ 'short_description',
+ 'description',
+ 'stock_quantity',
+ 'tax_status',
+ 'upsell_ids',
+ 'cross_sell_ids',
] );
} );
@@ -579,20 +586,23 @@ describe( 'product edit utils', () => {
'product_status',
'catalog_visibility',
'categories',
+ 'brands',
'tags',
- ...bulkSellableInstanceFieldIds,
+ 'featured',
+ 'images',
+ 'manage_stock',
+ 'weight',
+ 'length',
+ 'width',
+ 'height',
] )
);
expectFieldsHidden( fieldIds, [
- 'featured',
'upsell_ids',
'cross_sell_ids',
'shipping_class',
'tax_status',
- 'weight',
- 'length',
- 'width',
- 'height',
+ 'stock_quantity',
] );
} );
@@ -641,12 +651,18 @@ describe( 'product edit utils', () => {
expect( fieldIds ).toEqual(
expect.arrayContaining( [
+ 'product_status',
'regular_price',
'sale_price',
'images',
'sku',
'manage_stock',
'stock_quantity',
+ 'shipping_class',
+ 'weight',
+ 'length',
+ 'width',
+ 'height',
] )
);
expectFieldsHidden( fieldIds, [
@@ -657,7 +673,6 @@ describe( 'product edit utils', () => {
'schedule_sale',
'date_on_sale_from',
'date_on_sale_to',
- ...shippingFieldIds,
'tax_status',
] );
} );
@@ -682,6 +697,12 @@ describe( 'product edit utils', () => {
'sale_price',
'stock',
'manage_stock',
+ 'product_status',
+ 'shipping_class',
+ 'weight',
+ 'length',
+ 'width',
+ 'height',
] )
);
expectFieldsHidden( fieldIds, parentOwnedFieldIds );
@@ -690,12 +711,11 @@ describe( 'product edit utils', () => {
'schedule_sale',
'date_on_sale_from',
'date_on_sale_to',
- ...shippingFieldIds,
'tax_status',
] );
} );
- it( 'shows downloads and hides shipping for virtual downloadable variations', () => {
+ it( 'hides shipping fields for virtual variations', () => {
const fieldIds = getVisibleFieldIds( [
buildProduct( {
id: 34,
@@ -706,24 +726,23 @@ describe( 'product edit utils', () => {
} ),
] );
- expect( fieldIds ).toContain( 'downloadable' );
+ expectFieldsHidden( fieldIds, [ 'downloadable' ] );
expectFieldsHidden( fieldIds, shippingFieldIds );
} );
- it( 'shows dimensions for physical downloadable variations', () => {
+ it( 'shows shipping and dimensions for physical variations', () => {
const fieldIds = getVisibleFieldIds( [
buildProduct( {
id: 34,
parent_id: 12,
type: 'variation',
virtual: false,
- downloadable: true,
} ),
] );
expect( fieldIds ).toEqual(
expect.arrayContaining( [
- 'downloadable',
+ 'shipping_class',
'weight',
'length',
'width',
@@ -802,7 +821,7 @@ describe( 'product edit utils', () => {
] );
} );
- it( 'shows downloadable fields when every bulk sellable item is downloadable', () => {
+ it( 'hides downloadable fields for simple product and variation selections', () => {
const fieldIds = getVisibleFieldIds( [
buildProduct( {
id: 1,
@@ -817,7 +836,7 @@ describe( 'product edit utils', () => {
} ),
] );
- expect( fieldIds ).toContain( 'downloadable' );
+ expectFieldsHidden( fieldIds, [ 'downloadable' ] );
} );
it( 'hides downloadable fields unless every bulk item supports downloads', () => {
@@ -856,14 +875,24 @@ describe( 'product edit utils', () => {
] );
expect( fieldIds ).toEqual(
- expect.arrayContaining( [ ...managedStockFieldIds ] )
+ expect.arrayContaining( [
+ 'product_status',
+ 'images',
+ 'manage_stock',
+ 'shipping_class',
+ 'weight',
+ 'length',
+ 'width',
+ 'height',
+ ] )
);
expectFieldsHidden( fieldIds, [
...parentOwnedFieldIds,
...priceFieldIds,
'downloadable',
'sku',
- ...shippingFieldIds,
+ 'stock',
+ 'stock_quantity',
'tax_status',
] );
} );
@@ -895,14 +924,24 @@ describe( 'product edit utils', () => {
] );
expect( fieldIds ).toEqual(
- expect.arrayContaining( [ 'images', ...managedStockFieldIds ] )
+ expect.arrayContaining( [
+ 'product_status',
+ 'images',
+ 'manage_stock',
+ 'weight',
+ 'length',
+ 'width',
+ 'height',
+ ] )
);
expectFieldsHidden( fieldIds, [
...parentOwnedFieldIds,
...priceFieldIds,
'downloadable',
'sku',
- ...shippingFieldIds,
+ 'stock',
+ 'stock_quantity',
+ 'shipping_class',
'tax_status',
] );
} );
@@ -951,6 +990,7 @@ describe( 'product edit utils', () => {
'categories',
'brands',
'tags',
+ 'featured',
{
id: 'dimensions',
layout: { type: 'row' },
@@ -960,6 +1000,34 @@ describe( 'product edit utils', () => {
] );
} );
+ it( 'uses variable parent form config in design order', () => {
+ const product = buildProduct( {
+ type: 'variable',
+ virtual: false,
+ } );
+
+ expect( getProductTypeFormFields( [ product ] ) ).toEqual( [
+ 'name',
+ 'product_status',
+ 'catalog_visibility',
+ 'images',
+ 'sku',
+ 'manage_stock',
+ 'stock',
+ 'categories',
+ 'brands',
+ 'tags',
+ 'featured',
+ 'shipping_class',
+ {
+ id: 'parent-dimensions',
+ layout: { type: 'row' },
+ children: [ 'length', 'width', 'height' ],
+ },
+ 'weight',
+ ] );
+ } );
+
it( 'uses variation product form config', () => {
const product = buildProduct( {
id: 34,
@@ -970,14 +1038,15 @@ describe( 'product edit utils', () => {
} );
expect( getProductTypeFormFields( [ product ] ) ).toEqual( [
+ 'product_status',
'regular_price',
'sale_price',
'images',
- 'downloadable',
'sku',
- 'stock',
'manage_stock',
+ 'stock',
'stock_quantity',
+ 'shipping_class',
{
id: 'dimensions',
layout: { type: 'row' },
diff --git a/packages/js/experimental-products-app/src/product-edit/utils.ts b/packages/js/experimental-products-app/src/product-edit/utils.ts
index 9c1c4893f0a..9958c1c4ea9 100644
--- a/packages/js/experimental-products-app/src/product-edit/utils.ts
+++ b/packages/js/experimental-products-app/src/product-edit/utils.ts
@@ -83,6 +83,12 @@ const DIMENSIONS_FORM_FIELD: ProductEditFormField = {
children: [ ...DIMENSION_GROUP_FIELD_IDS ],
};
+const PARENT_DIMENSIONS_FORM_FIELD: ProductEditFormField = {
+ id: 'parent-dimensions',
+ layout: { type: 'row' as const },
+ children: [ 'length', 'width', 'height' ],
+};
+
const SIMPLE_PRODUCT_EDIT_FORM_FIELDS = [
'name',
'product_status',
@@ -98,43 +104,40 @@ const SIMPLE_PRODUCT_EDIT_FORM_FIELDS = [
'categories',
'brands',
'tags',
+ 'featured',
DIMENSIONS_FORM_FIELD,
'height',
] satisfies ProductEditFormField[];
const VARIATION_PRODUCT_EDIT_FORM_FIELDS = [
+ 'product_status',
'regular_price',
'sale_price',
'images',
- 'downloadable',
'sku',
- 'stock',
'manage_stock',
+ 'stock',
'stock_quantity',
+ 'shipping_class',
DIMENSIONS_FORM_FIELD,
'height',
] satisfies ProductEditFormField[];
const VARIABLE_PRODUCT_EDIT_FORM_FIELDS = [
'name',
- 'short_description',
- 'description',
- 'images',
'product_status',
+ 'catalog_visibility',
+ 'images',
'sku',
- 'stock',
- 'stock_quantity',
'manage_stock',
- 'shipping_class',
- 'tax_status',
+ 'stock',
'categories',
+ 'brands',
'tags',
'featured',
- 'catalog_visibility',
- 'upsell_ids',
- 'cross_sell_ids',
- DIMENSIONS_FORM_FIELD,
- 'height',
+ 'shipping_class',
+ PARENT_DIMENSIONS_FORM_FIELD,
+ 'weight',
] satisfies ProductEditFormField[];
const EXTERNAL_PRODUCT_EDIT_FORM_FIELDS = [
@@ -178,7 +181,6 @@ const PARENT_OWNED_PRODUCT_EDIT_FIELD_ID_SET = new Set< ProductEditFieldId >( [
'name',
'short_description',
'description',
- 'product_status',
'catalog_visibility',
'categories',
'brands',