diff --git a/addons/delivery_mondialrelay/__manifest__.py b/addons/delivery_mondialrelay/__manifest__.py index 65302a814ba..56d3be8dba1 100644 --- a/addons/delivery_mondialrelay/__manifest__.py +++ b/addons/delivery_mondialrelay/__manifest__.py @@ -19,7 +19,7 @@ ], 'assets': { 'web.assets_backend': [ - 'delivery_mondialrelay/static/src/js/mondialrelay.js', + 'delivery_mondialrelay/static/src/components/**/*.js', 'delivery_mondialrelay/static/src/scss/mondialrelay.scss', ], }, diff --git a/addons/delivery_mondialrelay/static/src/components/mondialrelay_field.js b/addons/delivery_mondialrelay/static/src/components/mondialrelay_field.js new file mode 100644 index 00000000000..343632e00ae --- /dev/null +++ b/addons/delivery_mondialrelay/static/src/components/mondialrelay_field.js @@ -0,0 +1,111 @@ +/** @odoo-module **/ + +import { registry } from "@web/core/registry"; + +// temporary for OnNoResultReturned bug +import { UncaughtCorsError } from "@web/core/errors/error_service"; +const errorHandlerRegistry = registry.category("error_handlers"); + +const { Component, onWillRender, useEffect, useRef, useState, xml } = owl; + +const MONDIALRELAY_SCRIPT_URL = "https://widget.mondialrelay.com/parcelshop-picker/jquery.plugin.mondialrelay.parcelshoppicker.min.js" +let SCRIPT_LOADED = false; + +function corsIgnoredErrorHandler(env, error) { + if (error instanceof UncaughtCorsError) { + return true; + } +} + +export class MondialRelayField extends Component { + setup() { + this.root = useRef("root"); + this.state = useState({ + libLoaded: false, // Whether the library is loaded or not + }); + onWillRender(() => { + // Do nothing if the record is not of type mondial_relay + if (!this.enabled || this.state.libLoaded) { + return; + } + // Check if lib is already loaded + let script = document.querySelector(`script[src="${MONDIALRELAY_SCRIPT_URL}"]`) + if (script) { + if (!SCRIPT_LOADED) { + script.onload = () => { + this.state.libLoaded = true; + SCRIPT_LOADED = true; + } + } else { + this.state.libLoaded = true; + } + return; + } + // Make sure the library is loaded + script = document.createElement('script'); + script.src = MONDIALRELAY_SCRIPT_URL; + script.onload = () => { + this.state.libLoaded = true; + SCRIPT_LOADED = true; + }; + document.body.appendChild(script); + }); + + useEffect( + (el) => { + if (!el) { + return; + } + this.insertWidget($(el)); + }, + () => [this.state.libLoaded && this.root.el], + ) + } + + get enabled() { + return this.props.record.data.is_mondialrelay; + } + + insertWidget($el) { + const params = { + Target: "", // required but handled by OnParcelShopSelected + Brand: this.props.record.data.mondialrelay_brand, + ColLivMod: this.props.record.data.mondial_realy_colLivMod, + AllowedCountries: this.props.record.data.mondialrelay_allowed_countries, + PostCode: this.props.record.data.shipping_zip || '', + Country: this.props.record.data.shipping_country_code || '', + Responsive: true, + ShowResultsOnMap: true, + AutoSelect: this.props.record.data.mondialrelay_last_selected_id, + OnParcelShopSelected: (RelaySelected) => { + const values = JSON.stringify({ + 'id': RelaySelected.ID, + 'name': RelaySelected.Nom, + 'street': RelaySelected.Adresse1, + 'street2': RelaySelected.Adresse2, + 'zip': RelaySelected.CP, + 'city': RelaySelected.Ville, + 'country': RelaySelected.Pays, + }); + this.props.update(values); + }, + OnNoResultReturned: () => { + // HACK while Mondial Relay fix his bug + // disable corsErrorHandler for 10 seconds + // If code postal not valid, it will crash with Cors Error: + // Cannot read property 'on' of undefined at u.MR_FitBounds + const randInt = Math.floor(Math.random() * 100); + errorHandlerRegistry.add("corsIgnoredErrorHandler" + randInt, corsIgnoredErrorHandler, {sequence: 10}); + setTimeout(function () { + errorHandlerRegistry.remove("corsIgnoredErrorHandler" + randInt); + }, 10000); + }, + }; + $el.show(); + $el.MR_ParcelShopPicker(params); + $el.trigger("MR_RebindMap"); + } +} +MondialRelayField.template = xml`
`; + +registry.category("fields").add("mondialrelay_relay", MondialRelayField); diff --git a/addons/delivery_mondialrelay/static/src/js/mondialrelay.js b/addons/delivery_mondialrelay/static/src/js/mondialrelay.js deleted file mode 100644 index 3de83dc5f24..00000000000 --- a/addons/delivery_mondialrelay/static/src/js/mondialrelay.js +++ /dev/null @@ -1,91 +0,0 @@ -/** @odoo-module **/ - -import AbstractField from 'web.AbstractField'; -import fieldRegistry from 'web.field_registry'; - -// temporary for OnNoResultReturned bug -import {registry} from "@web/core/registry"; -import {UncaughtCorsError} from "@web/core/errors/error_service"; -const errorHandlerRegistry = registry.category("error_handlers"); - -function corsIgnoredErrorHandler(env, error) { - if (error instanceof UncaughtCorsError) { - return true; - } -} - -var MondialRelayWidget = AbstractField.extend({ - resetOnAnyFieldChange: true, - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - * @private - */ - _render: function () { - if (this.recordData.is_mondialrelay) { - if (!this.mondialRelayInitialized) { - const script = document.createElement('script'); - script.src = "https://widget.mondialrelay.com/parcelshop-picker/jquery.plugin.mondialrelay.parcelshoppicker.min.js"; - script.onload = () => { - this.mondialRelayInitialized = true; - this._loadWidget(); - }; - document.body.appendChild(script); - } else { - this._loadWidget(); - } - } else { - this.$el.hide(); - } - }, - - /** - * - * @private - */ - _loadWidget: function () { - const params = { - Target: "", // required but handled by OnParcelShopSelected - Brand: this.recordData.mondialrelay_brand, - ColLivMod: this.recordData.mondial_realy_colLivMod, - AllowedCountries: this.recordData.mondialrelay_allowed_countries, - PostCode: this.recordData.shipping_zip || '', - Country: this.recordData.shipping_country_code || '', - Responsive: true, - ShowResultsOnMap: true, - AutoSelect: this.recordData.mondialrelay_last_selected_id, - OnParcelShopSelected: (RelaySelected) => { - const values = JSON.stringify({ - 'id': RelaySelected.ID, - 'name': RelaySelected.Nom, - 'street': RelaySelected.Adresse1, - 'street2': RelaySelected.Adresse2, - 'zip': RelaySelected.CP, - 'city': RelaySelected.Ville, - 'country': RelaySelected.Pays, - }); - this._setValue(values); - }, - OnNoResultReturned: () => { - // HACK while Mondial Relay fix his bug - // disable corsErrorHandler for 10 seconds - // If code postal not valid, it will crash with Cors Error: - // Cannot read property 'on' of undefined at u.MR_FitBounds - const randInt = Math.floor(Math.random() * 100); - errorHandlerRegistry.add("corsIgnoredErrorHandler" + randInt, corsIgnoredErrorHandler, {sequence: 10}); - setTimeout(function () { - errorHandlerRegistry.remove("corsIgnoredErrorHandler" + randInt); - }, 10000); - }, - }; - this.$el.show(); - this.$el.MR_ParcelShopPicker(params); - this.$el.trigger("MR_RebindMap"); - }, - -}); - -fieldRegistry.add("mondialrelay_relay", MondialRelayWidget);