diff --git a/addons/point_of_sale/static/src/js/Chrome.js b/addons/point_of_sale/static/src/js/Chrome.js index 730d77b5c42..7ebe3857406 100644 --- a/addons/point_of_sale/static/src/js/Chrome.js +++ b/addons/point_of_sale/static/src/js/Chrome.js @@ -7,7 +7,6 @@ odoo.define('point_of_sale.Chrome', function(require) { const BarcodeParser = require('barcodes.BarcodeParser'); const PosComponent = require('point_of_sale.PosComponent'); const NumberBuffer = require('point_of_sale.NumberBuffer'); - const PopupControllerMixin = require('point_of_sale.PopupControllerMixin'); const Registries = require('point_of_sale.Registries'); const IndependentToOrderScreen = require('point_of_sale.IndependentToOrderScreen'); const { identifyError, batched } = require('point_of_sale.utils'); @@ -32,7 +31,7 @@ odoo.define('point_of_sale.Chrome', function(require) { /** * Chrome is the root component of the PoS App. */ - class Chrome extends PopupControllerMixin(PosComponent) { + class Chrome extends PosComponent { setup() { super.setup(); useExternalListener(window, 'beforeunload', this._onBeforeUnload); @@ -249,7 +248,7 @@ odoo.define('point_of_sale.Chrome', function(require) { openCashControl() { if (this.shouldShowCashControl()) { - this.showPopup('CashOpeningPopup', { notEscapable: true }); + this.showPopup('CashOpeningPopup', { cancelKey: false }); } } diff --git a/addons/point_of_sale/static/src/js/PopupControllerMixin.js b/addons/point_of_sale/static/src/js/PopupControllerMixin.js deleted file mode 100644 index bcafe4a6a06..00000000000 --- a/addons/point_of_sale/static/src/js/PopupControllerMixin.js +++ /dev/null @@ -1,45 +0,0 @@ -odoo.define('point_of_sale.PopupControllerMixin', function(require) { - 'use strict'; - - const { useListener } = require("@web/core/utils/hooks"); - - const { useState } = owl; - - /** - * Allows the component declared with this mixin the ability show popup dynamically, - * provided the following: - * 1. The following element is declared in the template. It is where the Popup will be rendered. - * `` - * 2. The component should trigger `show-popup` event to show the popup and `close-popup` event - * to close. In PosComponent, `showPopup` is conveniently declared to satisfy this requirement. - * @param {Function} x class definition to mix with during extension - */ - const PopupControllerMixin = x => - class extends x { - setup() { - super.setup(); - useListener('show-popup', this.__showPopup); - useListener('close-popup', this.__closePopup); - - this.popup = useState({ isShown: false, name: null, component: null }); - this.popupProps = {}; // We want to avoid making the props to become Proxy! - } - __showPopup(event) { - const { name, props, resolve } = event.detail; - const popupConstructor = this.constructor.components[name]; - if (popupConstructor.dontShow) { - resolve(); - return; - } - this.popup.isShown = true; - this.popup.name = name; - this.popup.component = popupConstructor; - this.popupProps = Object.assign({}, props, { resolve }); - } - __closePopup() { - this.popup.isShown = false; - } - }; - - return PopupControllerMixin; -}); diff --git a/addons/point_of_sale/static/src/js/Popups/AbstractAwaitablePopup.js b/addons/point_of_sale/static/src/js/Popups/AbstractAwaitablePopup.js index ce9d00ae85f..ce88df5fbc2 100644 --- a/addons/point_of_sale/static/src/js/Popups/AbstractAwaitablePopup.js +++ b/addons/point_of_sale/static/src/js/Popups/AbstractAwaitablePopup.js @@ -2,8 +2,7 @@ odoo.define('point_of_sale.AbstractAwaitablePopup', function (require) { 'use strict'; const PosComponent = require('point_of_sale.PosComponent'); - - const { useExternalListener } = owl; + const { useBus } = require('@web/core/utils/hooks'); /** * Implement this abstract class by extending it like so: @@ -33,22 +32,24 @@ odoo.define('point_of_sale.AbstractAwaitablePopup', function (require) { class AbstractAwaitablePopup extends PosComponent { setup() { super.setup(); - if (!this.props.notEscapable) { - useExternalListener(window, 'keyup', this._cancelAtEscape); + if (this.props.confirmKey) { + useBus(this.env.posbus, `confirm-popup-${this.props.id}`, this.confirm); + } + if (this.props.cancelKey) { + useBus(this.env.posbus, `cancel-popup-${this.props.id}`, this.cancel); } } async confirm() { - this.props.resolve({ confirmed: true, payload: await this.getPayload() }); - this.trigger('close-popup'); + this.env.posbus.trigger('close-popup', { + popupId: this.props.id, + response: { confirmed: true, payload: await this.getPayload() }, + }); } cancel() { - this.props.resolve({ confirmed: false, payload: null }); - this.trigger('close-popup'); - } - _cancelAtEscape(event) { - if (event.key === 'Escape') { - this.cancel(); - } + this.env.posbus.trigger('close-popup', { + popupId: this.props.id, + response: { confirmed: false, payload: null }, + }); } /** * Override this in the concrete popup implementation to set the diff --git a/addons/point_of_sale/static/src/js/Popups/PosPopupController.js b/addons/point_of_sale/static/src/js/Popups/PosPopupController.js new file mode 100644 index 00000000000..1a4eba4c962 --- /dev/null +++ b/addons/point_of_sale/static/src/js/Popups/PosPopupController.js @@ -0,0 +1,120 @@ +odoo.define('point_of_sale.PosPopupController', function(require) { + 'use strict'; + + const Registries = require('point_of_sale.Registries'); + const PosComponent = require('point_of_sale.PosComponent'); + const { useBus } = require('@web/core/utils/hooks'); + + /** + * This component is responsible in controlling the popups. It does so + * by coordinating with them thru the `env.posbus`. The basic steps follow: + * 1. `showPopup` method triggers `show-popup` event resulting to the + * mounting of the requested popup. + * 2. When the popup is shown, the `confirm`/`cancel` method of the popup + * will be called after the popup is used. `confirming`/`cancelling` + * will trigger the `close-popup`, which this component also listens to, + * resulting to closing of the popup. + * + * Furthermore, Pressing `confirmKey`/`cancelKey` which defaults to + * 'Enter'/'Escape', will automatically `confirm`/`cancel` the `topPopup`. + * This behavior is accomplished by listening to `keyup` event of the window. + * When the `confirmKey`/`cancelKey` of the `topPopup` is pressed, + * 'cancel-popup-{top-popup-id}'/'confirm-popup-{top-popup-id}' will be triggered + * and since the popup is listening to that event (@see AbstractAwaitablePopup), + * it will result to the call of `confirm`/`cancel` method. + * + * @typedef {{ id: number, resolve: Function, keepBehind?: boolean, cancelKey?: string, confirmKey?: string }} BasePopupProps + * @typedef {{ name: string, component: AbstractAwaitablePopup, props: BasePopupProps, key: string }} Popup + */ + class PosPopupController extends PosComponent { + setup() { + super.setup(); + useBus(this.env.posbus, 'show-popup', this._showPopup); + useBus(this.env.posbus, 'close-popup', this._closePopup); + owl.useExternalListener(window, 'keyup', this._onWindowKeyup); + this.popups = owl.useState([]); + } + _showPopup(event) { + let { id, name, props, resolve } = event.detail; + props = Object.assign(props || {}, { id, resolve }); + const component = this.constructor.components[name]; + if (!component) { + throw new Error(`'${name}' is not found. Make sure the file is loaded and the component is properly registered using 'Registries.Component.add'.`); + } + if (component.dontShow) { + resolve(); + return; + } + this.popups.push({ + name, + component, + props: this._constructPopupProps(component, props), + key: `${name}-${id}`, + }); + } + _closePopup(event) { + const { popupId, response } = event.detail; + const index = this.popups.findIndex((popup) => popup.props.id == popupId); + if (index != -1) { + const popup = this.popups[index]; + popup.props.resolve(response); + this.popups.splice(index, 1); + } + } + _onWindowKeyup(event) { + if (!this.topPopup) return; + if (event.key === this.topPopup.props.cancelKey) { + this.env.posbus.trigger(`cancel-popup-${this.topPopup.props.id}`); + } else if (event.key === this.topPopup.props.confirmKey) { + this.env.posbus.trigger(`confirm-popup-${this.topPopup.props.id}`); + } + } + /** + * A popup can be cancelled/confirmed with 'Escape'/'Enter' key by default. + * Also, if it's not the top popup, it is hidden from the view. + * This can be overridden by the default props of the popop component + * and the props used in requesting to show the popup. + * + * @param {AbstractAwaitablePopup} popupComponent + * @param {Object} props + * @returns {BasePopupProps} + */ + _constructPopupProps(popupComponent, props) { + const defaultProps = popupComponent.defaultProps || {}; + return Object.assign( + { + keepBehind: false, + cancelKey: 'Escape', + confirmKey: 'Enter', + }, + defaultProps, + props + ); + } + /** + * @returns {boolean} Hide the element of this component when this returns false. + */ + isShown() { + return this.popups.length > 0; + } + get topPopup() { + return this.popups[this.popups.length - 1]; + } + /** + * By default, only show the top popup. But always show a popup if + * `keepBehind` props is true. Meaning, if you have 2 popups, and + * the bottom popup has `keepBehind = true`, then the bottom popup + * will be visible if it's not blocked in the view by the top popup. + * + * @param {Popup} popup + * @returns {boolean} + */ + shouldShow(popup) { + return this.topPopup === popup || popup.props.keepBehind; + } + } + PosPopupController.template = 'point_of_sale.PosPopupController'; + Registries.Component.add(PosPopupController); + + return PosPopupController; +}); diff --git a/addons/point_of_sale/static/src/js/PosComponent.js b/addons/point_of_sale/static/src/js/PosComponent.js index 51b82078721..2f969a687ad 100644 --- a/addons/point_of_sale/static/src/js/PosComponent.js +++ b/addons/point_of_sale/static/src/js/PosComponent.js @@ -4,6 +4,8 @@ odoo.define('point_of_sale.PosComponent', function (require) { const { LegacyComponent } = require("@web/legacy/legacy_component"); const { onRendered } = owl; + let nextId = 0; + class PosComponent extends LegacyComponent { setup() { onRendered(() => { @@ -36,7 +38,7 @@ odoo.define('point_of_sale.PosComponent', function (require) { */ showPopup(name, props) { return new Promise((resolve) => { - this.trigger('show-popup', { name, props, resolve }); + this.env.posbus.trigger('show-popup', { name, props, resolve, id: nextId++ }); }); } showTempScreen(name, props) { diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js index 8054aa9f752..0c0799fdffa 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js @@ -14,7 +14,6 @@ odoo.define('point_of_sale.RefundButton', function (require) { _onClick() { const partner = this.env.pos.get_order().get_partner(); const searchDetails = partner ? { fieldName: 'PARTNER', searchTerm: partner.name } : {}; - this.trigger('close-popup'); this.showScreen('TicketScreen', { ui: { filter: 'SYNCED', searchDetails }, destinationOrder: this.env.pos.get_order(), diff --git a/addons/point_of_sale/static/src/xml/Chrome.xml b/addons/point_of_sale/static/src/xml/Chrome.xml index a721a6647cb..ae9164120d5 100644 --- a/addons/point_of_sale/static/src/xml/Chrome.xml +++ b/addons/point_of_sale/static/src/xml/Chrome.xml @@ -62,10 +62,7 @@ -
- -
+ diff --git a/addons/point_of_sale/static/src/xml/Popups/CashMovePopup.xml b/addons/point_of_sale/static/src/xml/Popups/CashMovePopup.xml index 377af74f076..053bc04a5e8 100644 --- a/addons/point_of_sale/static/src/xml/Popups/CashMovePopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/CashMovePopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/CashOpeningPopup.xml b/addons/point_of_sale/static/src/xml/Popups/CashOpeningPopup.xml index cb6544456f0..60e518373d6 100644 --- a/addons/point_of_sale/static/src/xml/Popups/CashOpeningPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/CashOpeningPopup.xml @@ -1,7 +1,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml b/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml index 3a6d191f35f..4c9eeafb815 100644 --- a/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml b/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml index 9950bc3d28d..6be9723f2d0 100644 --- a/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml b/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml index b2f142b9536..ce286454cd2 100644 --- a/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/PosPopupController.xml b/addons/point_of_sale/static/src/xml/Popups/PosPopupController.xml new file mode 100644 index 00000000000..78392b7ef8f --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/PosPopupController.xml @@ -0,0 +1,14 @@ + + + + +
+ + + +
+
+ +
diff --git a/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml index 55ef49a16d7..3188264256a 100644 --- a/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml @@ -2,7 +2,6 @@ - - diff --git a/addons/point_of_sale/static/src/xml/Popups/ProductInfoPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ProductInfoPopup.xml index 9ccfbdcf204..6398d626dd4 100644 --- a/addons/point_of_sale/static/src/xml/Popups/ProductInfoPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/ProductInfoPopup.xml @@ -1,7 +1,6 @@ - - diff --git a/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml b/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml index 249ac8c6815..12add8473ab 100644 --- a/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml b/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml index a142c995719..2e2c67a3212 100644 --- a/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml b/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml index cc28d70638c..3cfb2c21364 100644 --- a/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml +++ b/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml @@ -2,7 +2,6 @@ - - diff --git a/addons/point_of_sale/static/tests/unit/test_PosPopupController.js b/addons/point_of_sale/static/tests/unit/test_PosPopupController.js new file mode 100644 index 00000000000..51e9e39914c --- /dev/null +++ b/addons/point_of_sale/static/tests/unit/test_PosPopupController.js @@ -0,0 +1,165 @@ +odoo.define('point_of_sale.tests.PosPopupController', function(require) { + 'use strict'; + + const PosPopupController = require('point_of_sale.PosPopupController'); + const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup'); + const PosComponent = require('point_of_sale.PosComponent'); + const makeTestEnvironment = require('web.test_env'); + const testUtils = require('web.test_utils'); + const Registries = require('point_of_sale.Registries'); + const { mount } = require('@web/../tests/helpers/utils'); + + const { EventBus, useSubEnv, xml } = owl; + + QUnit.module('unit tests for PosPopupController', { + before() { + Registries.Component.freeze(); + + // Note that we are creating new popups here to decouple this test from the pos app. + class CustomPopup1 extends AbstractAwaitablePopup {} + CustomPopup1.template = xml/* html */` + + `; + + class CustomPopup2 extends AbstractAwaitablePopup {} + CustomPopup2.template = xml/* html */` + + `; + + PosPopupController.components = { CustomPopup1, CustomPopup2 }; + }, + }); + + QUnit.test('allow multiple popups at the same time', async function(assert) { + assert.expect(12); + + class Root extends PosComponent { + setup() { + super.setup(); + useSubEnv({ + isDebug: () => false, + posbus: new EventBus(), + }); + } + } + Root.env = makeTestEnvironment(); + Root.template = xml/* html */ ` +
+ +
+ `; + + const root = await mount(Root, testUtils.prepareTarget()); + + // Check 1 popup + let popup1Promise = root.showPopup('CustomPopup1', {}); + await testUtils.nextTick(); + assert.strictEqual(root.el.querySelectorAll('.popup').length, 1); + testUtils.dom.click(root.el.querySelector('.modal-dialog .custom-popup-1 .confirm')); + let result1 = await popup1Promise; + assert.strictEqual(result1.confirmed, true); + await testUtils.nextTick(); + assert.strictEqual(root.el.querySelectorAll('.popup').length, 0); + + // Check multiple popups + popup1Promise = root.showPopup('CustomPopup1', {}); + await testUtils.nextTick(); + + // Check if the first popup is shown. + assert.strictEqual(root.el.querySelectorAll('.popup').length, 1); + + let popup2Promise = root.showPopup('CustomPopup2', {}); + await testUtils.nextTick(); + + // Check for the second popup. + assert.strictEqual(root.el.querySelectorAll('.popup').length, 2); + + // popup 1 should be hidden + assert.strictEqual(root.el.querySelectorAll('.modal-dialog.oe_hidden').length, 1); + + // click confirm on popup 2 + testUtils.dom.click(root.el.querySelector('.modal-dialog .custom-popup-2 .confirm')); + await testUtils.nextTick(); + + // after confirming on popup 2, only 1 should remain. + assert.strictEqual(root.el.querySelectorAll('.popup').length, 1); + assert.strictEqual(root.el.querySelectorAll('.modal-dialog .custom-popup-2').length, 0); + + // popup 1 should not be hidden + const CustomPopup1 = root.el.querySelector('.modal-dialog') + assert.strictEqual(![...CustomPopup1.classList].includes('oe_hidden'), true); + testUtils.dom.click(root.el.querySelector('.modal-dialog .custom-popup-1 .cancel')); + await testUtils.nextTick(); + + // after cancelling popup 1, no popup should remain. + assert.strictEqual(root.el.querySelectorAll('.popup').length, 0); + + result1 = await popup1Promise; + let result2 = await popup2Promise; + assert.strictEqual(result1.confirmed, false); // false because it's cancelled. + assert.strictEqual(result2.confirmed, true); // true because it's confirmed. + }); + + QUnit.test('pressing cancel/confirm key should only close the top popup', async function(assert) { + assert.expect(6); + + class Root extends PosComponent { + setup() { + super.setup(); + useSubEnv({ + isDebug: () => false, + posbus: new EventBus(), + }); + } + } + Root.env = makeTestEnvironment(); + Root.template = xml/* html */ ` +
+ +
+ `; + + const root = await mount(Root, testUtils.prepareTarget()); + + let popup1Promise = root.showPopup('CustomPopup1', { confirmKey: 'Enter', cancelKey: 'Escape' }); + await testUtils.nextTick(); + assert.strictEqual(root.el.querySelectorAll('.popup').length, 1); + + let popup2Promise = root.showPopup('CustomPopup2', { confirmKey: 'Enter', cancelKey: 'Escape' }); + await testUtils.nextTick(); + assert.strictEqual(root.el.querySelectorAll('.popup').length, 2); + + // Pressing 'Escape' should cancel the top popup which is the CustomPopup2. + testUtils.dom.triggerEvent(window, 'keyup', { key: 'Escape' }); + await testUtils.nextTick(); + + // Therefore, the popup2Promise has now resolved with `confirmed` value = false. + const result2 = await popup2Promise; + assert.strictEqual(result2.confirmed, false); + + assert.strictEqual(root.el.querySelectorAll('.popup').length, 1); + + testUtils.dom.triggerEvent(window, 'keyup', { key: 'Enter' }); + await testUtils.nextTick(); + + assert.strictEqual(root.el.querySelectorAll('.popup').length, 0); + + const result1 = await popup1Promise; + assert.strictEqual(result1.confirmed, true); + }); +}); diff --git a/addons/pos_coupon/static/src/js/ControlButtons/ResetProgramsButton.js b/addons/pos_coupon/static/src/js/ControlButtons/ResetProgramsButton.js index 5b6b0894756..dade62630c0 100644 --- a/addons/pos_coupon/static/src/js/ControlButtons/ResetProgramsButton.js +++ b/addons/pos_coupon/static/src/js/ControlButtons/ResetProgramsButton.js @@ -14,7 +14,6 @@ odoo.define('pos_coupon.ResetProgramsButton', function (require) { async onClick() { const order = this.env.pos.get_order(); order.resetPrograms(); - this.trigger('close-popup'); } } ResetProgramsButton.template = 'ResetProgramsButton'; diff --git a/addons/pos_gift_card/static/src/xml/GiftCardPopup.xml b/addons/pos_gift_card/static/src/xml/GiftCardPopup.xml index a61f3a7e0cf..aea1ffc0478 100644 --- a/addons/pos_gift_card/static/src/xml/GiftCardPopup.xml +++ b/addons/pos_gift_card/static/src/xml/GiftCardPopup.xml @@ -2,7 +2,6 @@ - diff --git a/addons/pos_mercury/static/src/xml/PaymentTransactionPopup.xml b/addons/pos_mercury/static/src/xml/PaymentTransactionPopup.xml index 39c05a8fce0..7bac9c11868 100644 --- a/addons/pos_mercury/static/src/xml/PaymentTransactionPopup.xml +++ b/addons/pos_mercury/static/src/xml/PaymentTransactionPopup.xml @@ -2,7 +2,6 @@ - - diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js index e892a479a75..7d048f0a48f 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js @@ -14,7 +14,6 @@ odoo.define('pos_restaurant.PrintBillButton', function(require) { async onClick() { const order = this.env.pos.get_order(); if (order.get_orderlines().length > 0) { - this.trigger('close-popup'); await this.showTempScreen('BillScreen'); } else { await this.showPopup('ErrorPopup', { diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js index 5e5fdc79ae0..5ecd9627412 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js @@ -14,7 +14,6 @@ odoo.define('pos_restaurant.SplitBillButton', function(require) { async onClick() { const order = this.env.pos.get_order(); if (order.get_orderlines().length > 0) { - this.trigger('close-popup'); this.showScreen('SplitBillScreen'); } } diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js index 67a2c4fb0dc..67211231dfb 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js @@ -12,7 +12,6 @@ odoo.define('pos_restaurant.TransferOrderButton', function(require) { useListener('click', this.onClick); } async onClick() { - this.trigger('close-popup'); this.env.pos.transfer_order_to_different_table(); this.showScreen('FloorScreen'); } diff --git a/addons/pos_sale/static/src/js/SetSaleOrderButton.js b/addons/pos_sale/static/src/js/SetSaleOrderButton.js index d0dd57ecb89..3c7ad5792ef 100644 --- a/addons/pos_sale/static/src/js/SetSaleOrderButton.js +++ b/addons/pos_sale/static/src/js/SetSaleOrderButton.js @@ -24,7 +24,6 @@ odoo.define('pos_sale.SetSaleOrderButton', function(require) { args: [[]], kwargs: { context: this.env.session.user_context }, }); - this.trigger('close-popup'); this.showScreen('SaleOrderManagementScreen'); } catch (error) { if (isConnectionError(error)) {