From 016f87d920bc859f6ebb9c2606352aef10d51bde Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Thu, 28 Sep 2023 08:48:59 +1300 Subject: [PATCH 01/23] Shipping Settings: Add React base Region Picker (#40184) --- .../shipping-settings-region-picker/index.js | 32 +++++++ .../region-picker.js | 27 ++++++ plugins/woocommerce-admin/webpack.config.js | 1 + .../js/admin/wc-shipping-zone-methods.js | 10 +++ .../settings/class-wc-settings-shipping.php | 85 +++++++++++++++---- .../html-admin-page-shipping-zone-methods.php | 30 ++----- .../src/Internal/Admin/WCAdminAssets.php | 5 +- .../merchant/create-shipping-zones.spec.js | 83 ++++++++++-------- 8 files changed, 195 insertions(+), 78 deletions(-) create mode 100644 plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/index.js create mode 100644 plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/region-picker.js diff --git a/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/index.js b/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/index.js new file mode 100644 index 00000000000..bdf2ef1ba0d --- /dev/null +++ b/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/index.js @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { render, createRoot } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { RegionPicker } from './region-picker'; + +const shippingZoneRegionPickerRoot = document.getElementById( + 'wc-shipping-zone-region-picker-root' +); + +const options = window.shippingZoneMethodsLocalizeScript?.region_options ?? []; +const initialValues = window.shippingZoneMethodsLocalizeScript?.locations ?? []; + +if ( shippingZoneRegionPickerRoot ) { + if ( createRoot ) { + createRoot( shippingZoneRegionPickerRoot ).render( + + ); + } else { + render( + , + shippingZoneRegionPickerRoot + ); + } +} diff --git a/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/region-picker.js b/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/region-picker.js new file mode 100644 index 00000000000..0c68e4dccd5 --- /dev/null +++ b/plugins/woocommerce-admin/client/wp-admin-scripts/shipping-settings-region-picker/region-picker.js @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { useState } from '@wordpress/element'; +import { TreeSelectControl } from '@woocommerce/components'; + +export const RegionPicker = ( { options, initialValues } ) => { + const [ selected, setSelected ] = useState( initialValues ); + const onChange = ( value ) => { + document.body.dispatchEvent( + /* global CustomEvent */ + new CustomEvent( 'wc_region_picker_update', { detail: value } ) + ); + setSelected( value ); + }; + + return ( + + ); +}; diff --git a/plugins/woocommerce-admin/webpack.config.js b/plugins/woocommerce-admin/webpack.config.js index 18e1e098a16..8879239ea7d 100644 --- a/plugins/woocommerce-admin/webpack.config.js +++ b/plugins/woocommerce-admin/webpack.config.js @@ -70,6 +70,7 @@ const wpAdminScripts = [ 'product-import-tracking', 'variable-product-tour', 'product-category-metabox', + 'shipping-settings-region-picker', ]; const getEntryPoints = () => { const entryPoints = { diff --git a/plugins/woocommerce/client/legacy/js/admin/wc-shipping-zone-methods.js b/plugins/woocommerce/client/legacy/js/admin/wc-shipping-zone-methods.js index db7bae0dd38..5e829673f39 100644 --- a/plugins/woocommerce/client/legacy/js/admin/wc-shipping-zone-methods.js +++ b/plugins/woocommerce/client/legacy/js/admin/wc-shipping-zone-methods.js @@ -101,9 +101,19 @@ $( document.body ).on( 'click', '.wc-shipping-zone-add-method', { view: this }, this.onAddShippingMethod ); $( document.body ).on( 'wc_backbone_modal_response', this.onConfigureShippingMethodSubmitted ); $( document.body ).on( 'wc_backbone_modal_response', this.onAddShippingMethodSubmitted ); + $( document.body ).on( 'wc_region_picker_update', this.onUpdateZoneRegionPicker ); $( document.body ).on( 'change', '.wc-shipping-zone-method-selector select', this.onChangeShippingMethodSelector ); $( document.body ).on( 'click', '.wc-shipping-zone-postcodes-toggle', this.onTogglePostcodes ); }, + onUpdateZoneRegionPicker: function( event ) { + var value = event.detail, + attribute = 'zone_locations', + changes = {}; + + changes[ attribute ] = value; + shippingMethodView.model.set( attribute, value ); + shippingMethodView.model.logChanges( changes ); + }, onUpdateZone: function( event ) { var view = event.data.view, model = view.model, diff --git a/plugins/woocommerce/includes/admin/settings/class-wc-settings-shipping.php b/plugins/woocommerce/includes/admin/settings/class-wc-settings-shipping.php index 3a625055b8e..2abda371ec4 100644 --- a/plugins/woocommerce/includes/admin/settings/class-wc-settings-shipping.php +++ b/plugins/woocommerce/includes/admin/settings/class-wc-settings-shipping.php @@ -7,6 +7,7 @@ */ use Automattic\Jetpack\Constants; +use Automattic\WooCommerce\Internal\Admin\WCAdminAssets; defined( 'ABSPATH' ) || exit; @@ -247,6 +248,48 @@ class WC_Settings_Shipping extends WC_Settings_Page { // phpcs:enable WordPress.Security.NonceVerification.Recommended } + /** + * Get all available regions. + * + * @param int $allowed_countries Zone ID. + * @param int $shipping_continents Zone ID. + */ + protected function get_region_options( $allowed_countries, $shipping_continents ) { + $options = array(); + foreach ( $shipping_continents as $continent_code => $continent ) { + $continent_data = array( + 'value' => 'continent:' . esc_attr( $continent_code ), + 'label' => esc_html( $continent['name'] ), + 'children' => array(), + ); + + $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] ); + + foreach ( $countries as $country_code ) { + $country_data = array( + 'value' => 'country:' . esc_attr( $country_code ), + 'label' => esc_html( $allowed_countries[ $country_code ] ), + 'children' => array(), + ); + + $states = WC()->countries->get_states( $country_code ); + + if ( $states ) { + foreach ( $states as $state_code => $state_name ) { + $country_data['children'][] = array( + 'value' => 'state:' . esc_attr( $country_code . ':' . $state_code ), + 'label' => esc_html( $state_name . ', ' . $allowed_countries[ $country_code ] ), + ); + } + } + $continent_data['children'][] = $country_data; + } + $options[] = $continent_data; + } + + return $options; + } + /** * Show method for a zone * @@ -278,26 +321,34 @@ class WC_Settings_Shipping extends WC_Settings_Page { } } + $localized_object = array( + 'methods' => $zone->get_shipping_methods( false, 'json' ), + 'zone_name' => $zone->get_zone_name(), + 'zone_id' => $zone->get_id(), + 'locations' => $locations, + 'wc_shipping_zones_nonce' => wp_create_nonce( 'wc_shipping_zones_nonce' ), + 'strings' => array( + 'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ), + 'save_changes_prompt' => __( 'Do you wish to save your changes first? Your changed data will be discarded if you choose to cancel.', 'woocommerce' ), + 'save_failed' => __( 'Your changes were not saved. Please retry.', 'woocommerce' ), + 'add_method_failed' => __( 'Shipping method could not be added. Please retry.', 'woocommerce' ), + 'remove_method_failed' => __( 'Shipping method could not be removed. Please retry.', 'woocommerce' ), + 'yes' => __( 'Yes', 'woocommerce' ), + 'no' => __( 'No', 'woocommerce' ), + 'default_zone_name' => __( 'Zone', 'woocommerce' ), + 'delete_shipping_method_confirmation' => __( 'Are you sure you want to delete this shipping method?', 'woocommerce' ), + ), + ); + + if ( 0 !== $zone->get_id() ) { + WCAdminAssets::register_script( 'wp-admin-scripts', 'shipping-settings-region-picker', true, array( 'wc-shipping-zone-methods' ) ); + $localized_object['region_options'] = $this->get_region_options( $allowed_countries, $shipping_continents ); + } + wp_localize_script( 'wc-shipping-zone-methods', 'shippingZoneMethodsLocalizeScript', - array( - 'methods' => $zone->get_shipping_methods( false, 'json' ), - 'zone_name' => $zone->get_zone_name(), - 'zone_id' => $zone->get_id(), - 'wc_shipping_zones_nonce' => wp_create_nonce( 'wc_shipping_zones_nonce' ), - 'strings' => array( - 'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ), - 'save_changes_prompt' => __( 'Do you wish to save your changes first? Your changed data will be discarded if you choose to cancel.', 'woocommerce' ), - 'save_failed' => __( 'Your changes were not saved. Please retry.', 'woocommerce' ), - 'add_method_failed' => __( 'Shipping method could not be added. Please retry.', 'woocommerce' ), - 'remove_method_failed' => __( 'Shipping method could not be removed. Please retry.', 'woocommerce' ), - 'yes' => __( 'Yes', 'woocommerce' ), - 'no' => __( 'No', 'woocommerce' ), - 'default_zone_name' => __( 'Zone', 'woocommerce' ), - 'delete_shipping_method_confirmation' => __( 'Are you sure you want to delete this shipping method?', 'woocommerce' ), - ), - ) + $localized_object, ); wp_enqueue_script( 'wc-shipping-zone-methods' ); diff --git a/plugins/woocommerce/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php b/plugins/woocommerce/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php index d556c53c5bd..aab2466b149 100644 --- a/plugins/woocommerce/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php +++ b/plugins/woocommerce/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php @@ -38,28 +38,10 @@ if ( ! defined( 'ABSPATH' ) ) { - - + +
+
+
@@ -69,8 +51,8 @@ if ( ! defined( 'ABSPATH' ) ) { 90210...99000) are also supported. Please see the shipping zones documentation for more information.', 'woocommerce' ), 'https://woo.com/document/setting-up-shipping-zones/#section-3' ); ?>
- - + +