From 23f073339a6537df462d8b9770ee4686e46d826e Mon Sep 17 00:00:00 2001 From: magdev Date: Wed, 4 Feb 2026 10:22:14 +0100 Subject: [PATCH] Fix WooCommerce sync button: AJAX handler registration and icon alignment - Register ProductSync AJAX handler independently from full integration init - AJAX now available on settings page even when integration is not yet enabled - Improved icon vertical alignment with explicit margin-top adjustment - Added better error handling and console logging in JS Co-Authored-By: Claude Opus 4.5 --- assets/css/admin.css | 10 +++++--- assets/js/admin.js | 16 +++++++++---- src/Integration/WooCommerce/Manager.php | 5 +++- src/Integration/WooCommerce/ProductSync.php | 26 +++++++++++++++++++++ 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 480d71a..bfb0475 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -2103,16 +2103,20 @@ WooCommerce Sync Button ============================================ */ .bnb-sync-rooms-btn { - display: inline-flex; - align-items: center; + display: inline-flex !important; + align-items: center !important; gap: 6px; + vertical-align: middle; } .bnb-sync-rooms-btn .dashicons { font-size: 16px; width: 16px; height: 16px; - line-height: 1; + line-height: 16px; + display: inline-block; + vertical-align: middle; + margin-top: -2px; } .bnb-sync-rooms-btn .dashicons.bnb-spin { diff --git a/assets/js/admin.js b/assets/js/admin.js index bc31c42..213b2b7 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -1213,7 +1213,7 @@ e.preventDefault(); var $btn = $(this); - var $status = $btn.siblings('.sync-status'); + var $status = $btn.parent().find('.sync-status'); $btn.prop('disabled', true); $btn.find('.dashicons').addClass('bnb-spin'); @@ -1230,11 +1230,19 @@ if (response.success) { $status.html('' + response.data.message + ''); } else { - $status.html('' + (response.data.message || 'Error') + ''); + var errorMsg = response.data && response.data.message ? response.data.message : 'Unknown error'; + $status.html('' + errorMsg + ''); } }, - error: function() { - $status.html('' + (wpBnbAdmin.i18n.error || 'Error occurred') + ''); + error: function(xhr, status, error) { + var errorMsg = wpBnbAdmin.i18n.error || 'Error occurred'; + if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) { + errorMsg = xhr.responseJSON.data.message; + } else if (error) { + errorMsg = error; + } + $status.html('' + errorMsg + ''); + console.error('WP-BnB Sync Error:', status, error, xhr.responseText); }, complete: function() { $btn.prop('disabled', false); diff --git a/src/Integration/WooCommerce/Manager.php b/src/Integration/WooCommerce/Manager.php index e68fc2d..4490c98 100644 --- a/src/Integration/WooCommerce/Manager.php +++ b/src/Integration/WooCommerce/Manager.php @@ -130,7 +130,10 @@ final class Manager { // Declare HPOS compatibility. add_action( 'before_woocommerce_init', array( self::class, 'declare_hpos_compatibility' ) ); - // Only initialize components if integration is enabled. + // Always register admin AJAX handlers (for settings page). + add_action( 'woocommerce_loaded', array( ProductSync::class, 'init_admin_ajax' ) ); + + // Only initialize full components if integration is enabled. if ( ! self::is_enabled() ) { return; } diff --git a/src/Integration/WooCommerce/ProductSync.php b/src/Integration/WooCommerce/ProductSync.php index b58f2cf..0fe43c8 100644 --- a/src/Integration/WooCommerce/ProductSync.php +++ b/src/Integration/WooCommerce/ProductSync.php @@ -25,6 +25,13 @@ use Magdev\WpBnb\Taxonomies\RoomType; */ final class ProductSync { + /** + * Track if admin AJAX has been initialized. + * + * @var bool + */ + private static bool $admin_ajax_initialized = false; + /** * Initialize product synchronization. * @@ -40,8 +47,27 @@ final class ProductSync { // Add linked room info to product edit screen. add_action( 'woocommerce_product_options_general_product_data', array( self::class, 'add_product_room_info' ) ); + // Register admin AJAX if not already done. + self::init_admin_ajax(); + } + + /** + * Initialize admin AJAX handlers only. + * + * Called separately from init() to ensure AJAX is available on settings page + * even when full integration is not yet enabled. + * + * @return void + */ + public static function init_admin_ajax(): void { + if ( self::$admin_ajax_initialized ) { + return; + } + // AJAX handler for syncing all rooms. add_action( 'wp_ajax_wp_bnb_sync_all_rooms', array( self::class, 'ajax_sync_all_rooms' ) ); + + self::$admin_ajax_initialized = true; } /**