-
Notifications
You must be signed in to change notification settings - Fork 37
fix: keep Meta Boxes pane open by default for WooCommerce Builder products #2926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
2c25fcd
1ae8200
3bc2a95
f247f06
6fd2307
6c74b2a
9a2a00e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,65 @@ public function init() { | |
| add_filter( 'wc_get_template_part', array( $this, 'wc_get_template_part' ), 1000, 3 ); | ||
| add_action( 'otter_blocks_woocommerce_content', 'the_content' ); | ||
| add_filter( 'body_class', array( $this, 'add_body_class' ), 1000, 1 ); | ||
| add_action( 'enqueue_block_editor_assets', array( $this, 'show_meta_boxes_pane' ) ); | ||
| add_filter( 'get_user_option_meta-box-order_product', array( $this, 'restore_product_data_location' ) ); | ||
| } | ||
|
|
||
| /** | ||
| * Keep the Product data metabox out of the narrow side column. | ||
| * | ||
| * The metabox "Move up/down" arrows persist the order instantly and, at the | ||
| * edge of an area, relocate a box into the adjacent area. From the block | ||
| * editor (used by WooCommerce Builder products) one accidental click can | ||
| * move WooCommerce's Product data box into "side", where it renders inside | ||
| * the ~280px sidebar and its layout breaks. Correct it at read time; the | ||
| * stored user option is left untouched. | ||
| * | ||
| * @param mixed $order Saved metabox order for the product screen. | ||
| * | ||
| * @access public | ||
| * @return mixed | ||
| */ | ||
| public function restore_product_data_location( $order ) { | ||
| if ( ! boolval( get_post_meta( get_the_ID(), '_themeisle_gutenberg_woo_builder', true ) ) ) { | ||
| return $order; | ||
| } | ||
|
|
||
| if ( ! is_array( $order ) || ! isset( $order['side'] ) || false === strpos( $order['side'], 'woocommerce-product-data' ) ) { | ||
|
Soare-Robert-Daniel marked this conversation as resolved.
|
||
| return $order; | ||
| } | ||
|
|
||
| $side = array_diff( explode( ',', $order['side'] ), array( 'woocommerce-product-data' ) ); | ||
| $normal = empty( $order['normal'] ) ? array() : explode( ',', $order['normal'] ); | ||
| array_unshift( $normal, 'woocommerce-product-data' ); | ||
|
|
||
| $order['side'] = implode( ',', $side ); | ||
| $order['normal'] = implode( ',', array_unique( $normal ) ); | ||
|
|
||
| return $order; | ||
| } | ||
|
|
||
| /** | ||
| * Keep the Meta Boxes pane open by default in the block editor. | ||
| * | ||
| * Since WP 6.7 the iframed post editor renders meta boxes inside a bottom | ||
| * drawer that is collapsed unless the user opened it before. On builder | ||
| * products that hides the WooCommerce Product data panel (price, inventory | ||
| * etc.), so default the drawer to open. An explicit user preference is not | ||
| * overridden, as setDefaults only applies to unset preferences. | ||
| * | ||
| * @access public | ||
| * @return void | ||
| */ | ||
| public function show_meta_boxes_pane() { | ||
| if ( 'product' !== get_post_type() || ! boolval( get_post_meta( get_the_ID(), '_themeisle_gutenberg_woo_builder', true ) ) ) { | ||
|
Comment on lines
+83
to
+84
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added in |
||
| return; | ||
| } | ||
|
|
||
| wp_add_inline_script( | ||
| 'wp-edit-post', | ||
| 'window.wp && wp.data && wp.data.dispatch( "core/preferences" ).setDefaults( "core/edit-post", { metaBoxesMainIsOpen: true } );' | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { test, expect } from '../fixtures'; | ||
|
|
||
| /** | ||
| * WooCommerce Builder forces the block editor for enabled products. Since | ||
| * WP 6.7 the iframed post editor renders meta boxes in a bottom drawer, so | ||
| * these tests pin the two guarantees that keep WooCommerce's Product data | ||
| * panel (price, inventory, …) reachable there: | ||
| * | ||
| * 1. the drawer defaults to open (an explicit user preference still wins); | ||
| * 2. a `meta-box-order_product` that strands the Product data box in the | ||
| * "side" area (one accidental click on the metabox move arrows persists | ||
| * that) is corrected back into the main area at render time. | ||
| */ | ||
|
|
||
| const PRODUCT_DATA = '#woocommerce-product-data'; | ||
| const META_BOXES_DRAWER = '.edit-post-meta-boxes-main'; | ||
|
|
||
| /** | ||
| * The Otter welcome tour pops on fresh profiles; close it if it appears. | ||
| * | ||
| * @param {import('@playwright/test').Page} page Playwright page. | ||
| */ | ||
| const dismissOtterTour = async( page ) => { | ||
| const guide = page.locator( '.components-guide' ); | ||
| if ( await guide.isVisible({ timeout: 2000 }).catch( () => false ) ) { | ||
| await page.keyboard.press( 'Escape' ); | ||
| await expect( guide ).toBeHidden(); | ||
| } | ||
| }; | ||
|
|
||
| test.describe( 'WooCommerce Builder product editor', () => { | ||
| // WooCommerce is mounted by wp-env but only activated around this spec — | ||
| // its editor integrations would change load behavior (and performance | ||
| // numbers) for every other suite. Serial project only. | ||
| test.beforeAll( async({ requestUtils }) => { | ||
| await requestUtils.activatePlugin( 'woocommerce' ); | ||
| }); | ||
|
|
||
| test.afterAll( async({ requestUtils }) => { | ||
| await requestUtils.deactivatePlugin( 'woocommerce' ); | ||
| }); | ||
|
|
||
| // A drawer preference or metabox order left by an earlier run would skew | ||
| // the first test as much as a later one, so reset on both sides. | ||
| const resetSharedUserState = async( otterUtils ) => { | ||
| await otterUtils.setProductMetaBoxOrder( null ); | ||
| await otterUtils.resetMetaBoxesPane(); | ||
| }; | ||
|
|
||
| test.beforeEach( async({ otterUtils }) => { | ||
| await resetSharedUserState( otterUtils ); | ||
| }); | ||
|
|
||
| test.afterEach( async({ otterUtils }) => { | ||
| await resetSharedUserState( otterUtils ); | ||
| }); | ||
|
|
||
| test( 'builder products open in the block editor with the Product data panel visible', async({ admin, page, otterUtils }) => { | ||
| const { id } = await otterUtils.createWooProduct({ builder: true }); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in |
||
|
|
||
| await admin.editPost( id ); | ||
| await dismissOtterTour( page ); | ||
|
|
||
| // Block editor is active for the builder product… | ||
| await expect( page.locator( 'body.block-editor-page' ) ).toHaveCount( 1 ); | ||
|
|
||
| // …and the Product data metabox is visible without any interaction: | ||
| // the meta boxes drawer defaults to open on builder products. | ||
| await expect( page.locator( PRODUCT_DATA ) ).toBeVisible(); | ||
| await expect( page.locator( `${ PRODUCT_DATA } input[name="_regular_price"]` ) ).toHaveValue( '49.99' ); | ||
| }); | ||
|
|
||
| test( 'Product data stranded in the side area is rescued into the drawer', async({ admin, page, otterUtils }) => { | ||
| const { id } = await otterUtils.createWooProduct({ builder: true }); | ||
|
|
||
| // The corrupted layout one metabox arrow click can persist: Product | ||
| // data serialized into "side", which renders inside the ~280px | ||
| // sidebar where its layout breaks. | ||
| await otterUtils.setProductMetaBoxOrder({ | ||
| normal: '', | ||
| advanced: 'commentsdiv,postexcerpt', | ||
| side: 'woocommerce-product-data,otter_woo_builder,woocommerce-product-images' | ||
| }); | ||
|
|
||
| await admin.editPost( id ); | ||
| await dismissOtterTour( page ); | ||
|
|
||
| await expect( page.locator( `${ META_BOXES_DRAWER } ${ PRODUCT_DATA }` ) ).toBeVisible(); | ||
| await expect( page.locator( `.interface-complementary-area ${ PRODUCT_DATA }` ) ).toHaveCount( 0 ); | ||
| }); | ||
|
|
||
| test( 'products without the builder keep the classic editor', async({ admin, page, otterUtils }) => { | ||
| const { id } = await otterUtils.createWooProduct({ builder: false }); | ||
|
|
||
| await admin.visitAdminPage( 'post.php', `post=${ id }&action=edit` ); | ||
|
|
||
| await expect( page.locator( 'body.block-editor-page' ) ).toHaveCount( 0 ); | ||
| await expect( page.locator( PRODUCT_DATA ) ).toBeVisible(); | ||
| }); | ||
|
|
||
| test( 'an explicitly collapsed drawer stays collapsed (user preference wins)', async({ admin, page, otterUtils }) => { | ||
| const { id } = await otterUtils.createWooProduct({ builder: true }); | ||
|
|
||
| await admin.editPost( id ); | ||
| await dismissOtterTour( page ); | ||
| await expect( page.locator( PRODUCT_DATA ) ).toBeVisible(); | ||
|
|
||
| // Collapse the drawer — this persists the user preference, which | ||
| // setDefaults() must not override on the next load. Keyboard: the | ||
| // toggle's click point is covered by its drag-resize separator. The | ||
| // preference write is debounced, so hold for the REST flush before | ||
| // reloading. | ||
| await Promise.all([ | ||
| page.waitForResponse( ( response ) => response.url().includes( '/wp/v2/users/me' ) ), | ||
| page.getByRole( 'button', { name: 'Meta Boxes' }).press( 'Enter' ) | ||
| ]); | ||
| await expect( page.locator( PRODUCT_DATA ) ).toBeHidden(); | ||
|
|
||
| await admin.editPost( id ); | ||
| await expect( page.locator( META_BOXES_DRAWER ) ).toBeVisible(); | ||
| await expect( page.locator( PRODUCT_DATA ) ).toBeHidden(); | ||
| }); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.