[REF] point_of_sale, *: move things out of Chrome and store

*: pos_hr_restaurant, pos_restaurant

This commit continues the work of simplifying the Chrome component, it
moves the popup controller and the notification to their own component
and service, and moves the state of the notification, sound and debug
widget into their own services.

closes odoo/odoo#111553

Related: odoo/enterprise#36573
Signed-off-by: Samuel Degueldre <sad@odoo.com>
This commit is contained in:
Samuel Degueldre
2023-02-01 14:38:03 +01:00
parent 7618e2e657
commit e57719733d
22 changed files with 270 additions and 156 deletions
+1
View File
@@ -125,6 +125,7 @@
'point_of_sale/static/src/js/**/*.js',
'web/static/lib/zxing-library/zxing-library.js',
'point_of_sale/static/src/xml/**/*.xml',
'point_of_sale/static/src/utils.js',
'point_of_sale/static/src/app/**/*',
],
# This bundle contains the code responsible for starting the POS UI.
@@ -0,0 +1,34 @@
/** @odoo-module */
import { reactive } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { DebugWidget } from "./debug_widget";
import { withComputedProperties } from "@point_of_sale/utils";
const debugService = {
dependencies: ["pos"],
/**
* @param {{ debug: string }} env
* @param {object} deps
* @param {import("@point_of_sale/app/pos_store").PosStore} deps.pos
*/
start(env, { pos }) {
const internalState = reactive({ widgetOpen: true });
const state = withComputedProperties(reactive({}), [internalState, pos], {
showWidget(internalState, pos) {
return env.debug && pos.uiState === "READY" && internalState.widgetOpen;
},
});
registry.category("main_components").add("DebugWidget", {
Component: DebugWidget,
props: { state },
});
return {
toggleWidget() {
internalState.widgetOpen = !internalState.widgetOpen;
},
};
},
};
registry.category("services").add("debug", debugService);
@@ -3,21 +3,20 @@
import { parse } from "web.field_utils";
import { numberBuffer } from "@point_of_sale/js/Misc/NumberBuffer";
import { PosComponent } from "@point_of_sale/js/PosComponent";
import { usePos } from "@point_of_sale/app/pos_store";
import { registry } from "@web/core/registry";
import { Transition } from "@web/core/transition";
import { Draggable } from "@point_of_sale/js/Misc/Draggable";
import { ConfirmPopup } from "@point_of_sale/js/Popups/ConfirmPopup";
import { OrderImportPopup } from "@point_of_sale/js/Popups/OrderImportPopup";
import { useService } from "@web/core/utils/hooks";
const { onMounted, onWillUnmount, useRef, useState } = owl;
import { onMounted, onWillUnmount, useRef, useState } from "@odoo/owl";
export class DebugWidget extends PosComponent {
static components = { Transition, Draggable };
static template = "point_of_sale.DebugWidget";
setup() {
super.setup();
this.pos = usePos();
this.debug = useService("debug");
this.state = useState({
barcodeInput: "",
weightInput: "",
@@ -162,5 +161,3 @@ export class DebugWidget extends PosComponent {
return `"${this.state.buffer}"`;
}
}
registry.category("main_components").add("DebugWidget", { Component: DebugWidget });
@@ -2,13 +2,13 @@
<templates id="template" xml:space="preserve">
<t t-name="point_of_sale.DebugWidget" owl="1">
<Transition t-if="env.isDebug() and pos.uiState === 'READY'" visible="pos.debugWidgetIsShown" name="'o-fade'" leaveDuration="200" t-slot-scope="transition">
<Transition visible="props.state.showWidget" name="'o-fade'" leaveDuration="200" t-slot-scope="transition">
<Draggable limitArea="'.pos'">
<div class="debug-widget" t-att-class="transition.className">
<header class="drag-handle">
<h1>Debug Window</h1>
</header>
<div class="toggle" t-on-click="() => pos.toggleDebugWidget()" title="Dismiss"
<div class="toggle" t-on-click="() => debug.toggleWidget()" title="Dismiss"
role="img" aria-label="Dismiss"><i class="fa fa-times" /></div>
<div class="content">
<p class="category">Electronic Scale</p>
@@ -2,6 +2,7 @@
import { PosComponent } from "@point_of_sale/js/PosComponent";
import { usePos } from "@point_of_sale/app/pos_store";
import { useService } from "@web/core/utils/hooks";
import { CashierName } from "@point_of_sale/js/ChromeWidgets/CashierName";
import { CashMoveButton } from "@point_of_sale/js/ChromeWidgets/CashMoveButton";
@@ -30,6 +31,7 @@ export class Navbar extends PosComponent {
};
setup() {
this.pos = usePos();
this.debug = useService("debug");
}
get customerFacingDisplayButtonIsShown() {
return this.env.pos.config.iface_customer_facing_display;
@@ -5,7 +5,7 @@
<div class="pos-topheader">
<div t-if="pos.tempScreen" class="block-top-header" />
<div class="pos-branding">
<img t-if="!env.isMobile" class="pos-logo" t-on-click="() => pos.toggleDebugWidget()" src="/point_of_sale/static/src/img/logo.png" alt="Logo" />
<img t-if="!env.isMobile" class="pos-logo" t-on-click="() => debug.toggleWidget()" src="/point_of_sale/static/src/img/logo.png" alt="Logo" />
<CashMoveButton t-if="props.showCashMoveButton" />
<TicketButton />
</div>
@@ -0,0 +1,25 @@
.o_pos_notification_manager {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
padding: 2rem;
justify-content: end;
align-items: center;
pointer-events: none;
}
.o_notification {
pointer-events: auto;
width: 350px;
background-color: #333333AA;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
margin: .5rem;
font-size: 1rem;
}
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="point_of_sale.Notification" owl="1">
<div class="o_notification" t-att-class="props.className" t-on-click="props.close">
<span t-esc="props.message"/>
</div>
</t>
<t t-name="point_of_sale.NotificationContainer" owl="1">
<div class="o_pos_notification_manager">
<t t-foreach="props.notifications" t-as="notification" t-key="notification">
<Transition name="'o-fade'" visible="notification_value.visible" leaveDuration="leaveDuration" t-slot-scope="transition" onLeave="notification_value.delete">
<Notification message="notification_value.message" close="notification_value.close" className="transition.className"/>
</Transition>
</t>
</div>
</t>
</templates>
@@ -0,0 +1,50 @@
/** @odoo-module */
import { reactive, Component } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Transition } from "@web/core/transition";
const TRANSITION_LEAVE_DURATION = 200; // ms
class Notification extends Component {
static template = "point_of_sale.Notification";
static props = { message: String, close: Function, className: String };
}
class NotificationContainer extends Component {
static template = "point_of_sale.NotificationContainer";
static components = { Transition, Notification };
static props = {
notifications: Object,
};
leaveDuration = TRANSITION_LEAVE_DURATION;
}
// FIXME: probably should use the main notification service from web long term.
export const notificationService = {
start() {
const notifications = reactive({});
let notifId = 0;
registry.category("main_components").add("PosNotificationContainer", {
Component: NotificationContainer,
props: { notifications },
});
return {
add(message, duration = 2000) {
const id = ++notifId;
notifications[id] = {
message,
visible: true,
close() {
notifications[id].visible = false;
},
delete() {
delete notifications[id];
},
};
setTimeout(() => notifications?.[id]?.close(), duration);
},
};
},
};
registry.category("services").add("pos_notification", notificationService);
@@ -1,32 +1,27 @@
/** @odoo-module */
import { PosGlobalState } from "@point_of_sale/js/models";
import { pos_env as legacyEnv } from "@point_of_sale/js/pos_env";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { debounce } from "@web/core/utils/timing";
import { reactive, useState, toRaw } from "@odoo/owl";
import { reactive, useState, markRaw } from "@odoo/owl";
export class PosStore {
/** @type {'LOADING' | 'READY' | 'CLOSING'} */
uiState = "LOADING";
debugWidgetIsShown = true;
hasBigScrollBars = false;
notification = {
isShown: false,
message: "",
duration: 2000,
};
loadingSkipButtonIsShown = false;
// not using an arrow function here because we need the correct `this`
toggleDebugWidget = debounce(function toggleDebugWidget() {
this.debugWidgetIsShown = !toRaw(this).debugWidgetIsShown;
}, 100);
mainScreen = { name: null, component: null };
tempScreen = null;
legacyEnv = legacyEnv;
constructor() {
this.setup();
}
// to allow other modules to add things to the store.
setup() {}
// use setup instead of constructor because setup can be patched.
setup() {
this.globalState = new PosGlobalState({ env: markRaw(legacyEnv) });
}
}
export const posService = {
@@ -37,6 +32,9 @@ export const posService = {
registry.category("services").add("pos", posService);
/**
* @returns {PosStore}
*/
export function usePos() {
return useState(useService("pos"));
}
+17 -44
View File
@@ -15,13 +15,10 @@ import { Navbar } from "@point_of_sale/app/navbar/navbar";
// ChromeAdapter imports
import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductScreen";
import { PosGlobalState } from "@point_of_sale/js/models";
import { configureGui } from "@point_of_sale/js/Gui";
import { registry } from "@web/core/registry";
import { pos_env as env } from "@point_of_sale/js/pos_env";
import { Notification } from "./Notification";
import { PosPopupController } from "./Popups/PosPopupController";
import { ErrorTracebackPopup } from "./Popups/ErrorTracebackPopup";
import { CashOpeningPopup } from "./Popups/CashOpeningPopup";
import { ConfirmPopup } from "./Popups/ConfirmPopup";
@@ -32,7 +29,6 @@ import {
useExternalListener,
useSubEnv,
reactive,
markRaw,
onWillUnmount,
} from "@odoo/owl";
import { usePos } from "@point_of_sale/app/pos_store";
@@ -43,18 +39,15 @@ import { usePos } from "@point_of_sale/app/pos_store";
export class Chrome extends PosComponent {
static template = "Chrome"; // FIXME POSREF namespace templates
setup() {
this.pos = usePos();
// BEGIN ChromeAdapter
ProductScreen.sortControlButtons();
const legacyActionManager = useService("legacy_action_manager");
// Instantiate PosGlobalState here to ensure that every extension
// (or class overloads) is taken into consideration.
const pos = new PosGlobalState({ env: markRaw(env) });
this.batchedCustomerDisplayRender = batched(() => {
reactivePos.send_current_order_to_customer_facing_display();
});
const reactivePos = reactive(pos, this.batchedCustomerDisplayRender);
const reactivePos = reactive(this.pos.globalState, this.batchedCustomerDisplayRender);
env.pos = reactivePos;
env.legacyActionManager = legacyActionManager;
@@ -63,12 +56,13 @@ export class Chrome extends PosComponent {
// TODO: Should we continue on exposing posmodel as global variable?
// Expose only the reactive version of `pos` when in debug mode.
window.posmodel = pos.debug ? reactivePos : pos;
window.posmodel = this.pos.globalState.debug ? reactivePos : this.pos.globalState;
this.wowlEnv = this.env;
env.services.pos = this.wowlEnv.services.pos;
env.services.sound = this.wowlEnv.services.sound;
window.sound = env.services.sound;
for (const service of ["pos", "sound", "debug", "pos_notification"]) {
env.services[service] = this.wowlEnv.services[service];
}
this.env = env;
this.__owl__.childEnv = env;
useSubEnv({
@@ -94,20 +88,11 @@ export class Chrome extends PosComponent {
useListener("close-temp-screen", this.__closeTempScreen);
useListener("close-pos", this._closePos);
useListener("loading-skip-callback", () => this.env.proxy.stop_searching());
const sound = useService("sound");
useListener("play-sound", ({ detail: name }) => sound.play(name));
useListener("set-sync-status", this._onSetSyncStatus);
useListener("show-notification", this._onShowNotification);
useListener("close-notification", this._onCloseNotification);
useListener("connect-to-proxy", this.connect_to_proxy);
useBus(this.env.posbus, "start-cash-control", this.openCashControl);
numberBuffer.activate();
this.state = usePos();
this.mainScreen = this.state.mainScreen;
this.mainScreenProps = {};
useSubEnv({
pos: reactive(
this.env.pos,
@@ -145,9 +130,9 @@ export class Chrome extends PosComponent {
* NOTE: Wait for pos data to be completed before calling this getter.
*/
get startScreen() {
if (this.state.uiState !== "READY") {
if (this.pos.uiState !== "READY") {
console.warn(
`Accessing startScreen of Chrome component before 'state.uiState' to be 'READY' is not recommended.`
`Accessing startScreen of Chrome component before 'pos.uiState' to be 'READY' is not recommended.`
);
}
return { name: "ProductScreen" };
@@ -184,7 +169,7 @@ export class Chrome extends PosComponent {
this.env.pos.config.start_category && this.env.pos.config.iface_start_categ_id
? this.env.pos.config.iface_start_categ_id[0]
: 0;
this.state.uiState = "READY";
this.pos.uiState = "READY";
this._showStartScreen();
setTimeout(() => this._runBackgroundTasks());
} catch (error) {
@@ -267,7 +252,7 @@ export class Chrome extends PosComponent {
connect_to_proxy() {
return new Promise((resolve, reject) => {
this.env.barcode_reader.disconnect_from_proxy();
this.state.loadingSkipButtonIsShown = true;
this.pos.loadingSkipButtonIsShown = true;
this.env.proxy
.autoconnect({
force_ip: this.env.pos.config.proxy_ip || undefined,
@@ -326,21 +311,19 @@ export class Chrome extends PosComponent {
}
__showTempScreen(event) {
const { name, props, resolve } = event.detail;
this.state.tempScreen = {
this.pos.tempScreen = {
name,
component: registry.category("pos_screens").get(name),
props: { ...props, resolve },
};
}
__closeTempScreen() {
this.state.tempScreen = null;
this.pos.tempScreen = null;
}
__showScreen({ detail: { name, props = {} } }) {
const component = registry.category("pos_screens").get(name);
// 1. Set the information of the screen to display.
this.mainScreen.name = name;
this.mainScreen.component = component;
this.mainScreenProps = props;
this.pos.mainScreen = { name, component, props };
// 2. Save the screen to the order.
// - This screen is shown when the order is selected.
@@ -402,8 +385,8 @@ export class Chrome extends PosComponent {
});
if (confirmed) {
// FIXME POSREF setting the location prevents the next render, the loading screen never shows
this.state.uiState = "CLOSING";
this.state.loadingSkipButtonIsShown = false;
this.pos.uiState = "CLOSING";
this.pos.loadingSkipButtonIsShown = false;
window.location = "/web#action=point_of_sale.action_client_pos_menu";
}
}
@@ -413,14 +396,6 @@ export class Chrome extends PosComponent {
this.env.pos.synch.status = status;
this.env.pos.synch.pending = pending;
}
_onShowNotification({ detail: { message, duration } }) {
this.state.notification.isShown = true;
this.state.notification.message = message;
this.state.notification.duration = duration;
}
_onCloseNotification() {
this.state.notification.isShown = false;
}
/**
* Save `env.pos.toRefundLines` in localStorage on beforeunload - closing the
* browser, reloading or going to other page.
@@ -458,7 +433,7 @@ export class Chrome extends PosComponent {
}
if (this.env.pos.config.iface_big_scrollbars) {
this.state.hasBigScrollBars = true;
this.pos.hasBigScrollBars = true;
}
this._disableBackspaceBack();
@@ -507,8 +482,6 @@ Object.defineProperty(Chrome, "components", {
MainComponentsContainer,
WithEnv,
Navbar,
PosPopupController,
Notification,
},
PosComponent.components
);
@@ -1,21 +0,0 @@
/** @odoo-module */
import { useListener } from "@web/core/utils/hooks";
import { PosComponent } from "@point_of_sale/js/PosComponent";
const { onMounted } = owl;
export class Notification extends PosComponent {
static template = "Notification";
setup() {
super.setup();
useListener("click", this.closeNotification);
onMounted(() => {
setTimeout(() => {
this.closeNotification();
}, this.props.duration);
});
}
}
@@ -2,6 +2,9 @@
import { PosComponent } from "@point_of_sale/js/PosComponent";
import { useBus } from "@web/core/utils/hooks";
import { registry } from "@web/core/registry";
import { usePos } from "@point_of_sale/app/pos_store";
import { useExternalListener, useState } from "@odoo/owl";
/**
* This component is responsible in controlling the popups. It does so
@@ -29,11 +32,15 @@ export class PosPopupController extends PosComponent {
static components = {};
setup() {
this.pos = usePos();
// FIXME POSREF stop overwriting env
this.env = this.pos.legacyEnv;
this.__owl__.childEnv = this.env;
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([]);
useExternalListener(window, "keyup", this._onWindowKeyup);
this.popups = useState([]);
}
/**
* A popup can be cancelled/confirmed with 'Escape'/'Enter' key by default.
@@ -109,3 +116,7 @@ export class PosPopupController extends PosComponent {
return this.topPopup === popup || popup.props.keepBehind;
}
}
registry.category("main_components").add("PosPopupController", {
Component: PosPopupController,
});
@@ -1,11 +1,16 @@
/** @odoo-module */
import { useService } from "@web/core/utils/hooks";
import { LegacyComponent } from "@web/legacy/legacy_component";
let nextId = 0;
export class PosComponent extends LegacyComponent {
static components = {};
setup() {
this.notification = useService("pos_notification");
this.sound = useService("sound");
}
/**
* This function is available to all Components that inherit this class.
* The goal of this function is to show an awaitable dialog (popup) that
@@ -42,7 +47,7 @@ export class PosComponent extends LegacyComponent {
* @param {String} name 'bell' | 'error'
*/
playSound(name) {
this.trigger("play-sound", name);
this.sound.play(name);
}
/**
* Control the SyncNotification component.
@@ -52,10 +57,7 @@ export class PosComponent extends LegacyComponent {
setSyncStatus(status, pending) {
this.trigger("set-sync-status", { status, pending });
}
showNotification(message, duration = 2000) {
this.trigger("show-notification", { message, duration });
}
closeNotification() {
this.trigger("close-notification");
showNotification(message, duration) {
this.notification.add(message, duration);
}
}
@@ -3676,24 +3676,6 @@ td {
}
}
/**
* Notification
*/
.pos .notification {
width: 350px;
background-color: #333333AA;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: calc((100% - 350px - 32px)/2);
bottom: 5%;
font-size: 17px;
}
.pos .pos-topheader .status-buttons > div:not(.not-clickable):hover {
background: rgba(0, 0, 0, .08);
}
+43
View File
@@ -0,0 +1,43 @@
/** @odoo-module */
import { reactive } from "@odoo/owl";
/**
* Creates a side-effect that runs based on the content of reactive objects.
*
* @template {object[]} T
* @param {(...args: [...T]) => void} cb callback for the effect
* @param {[...T]} deps the reactive objects that the effect depends on
*/
export function effect(cb, deps) {
const reactiveDeps = reactive(deps, () => {
cb(...reactiveDeps);
});
cb(...reactiveDeps);
}
/**
* Adds computed properties to a reactive object derived from multiples sources.
*
* @template {object} T
* @template {object[]} U
* @template {{[key: string]: (this: T, ...rest: [...U]) => unknown}} V
* @param {T} obj the reactive object on which to add the computed
* properties
* @param {[...U]} sources the reactive objects which are needed to compute
* the properties
* @param {V} descriptor the object containing methods to compute the
* properties
* @returns {T & {[key in keyof V]: ReturnType<V[key]>}}
*/
export function withComputedProperties(obj, sources, descriptor) {
for (const [key, compute] of Object.entries(descriptor)) {
effect(
(obj, sources) => {
obj[key] = compute.call(obj, ...sources);
},
[obj, sources]
);
}
return obj;
}
+8 -16
View File
@@ -2,19 +2,19 @@
<templates id="template" xml:space="preserve">
<t t-name="Chrome" owl="1">
<div class="pos" t-att-class="{ 'big-scrollbars': state.hasBigScrollBars }">
<div class="pos" t-att-class="{ 'big-scrollbars': pos.hasBigScrollBars }">
<div class="pos-receipt-print"></div>
<t t-if="state.uiState === 'READY'">
<t t-if="pos.uiState === 'READY'">
<Navbar showCashMoveButton="showCashMoveButton"/>
<div class="pos-content">
<div class="window">
<div class="subwindow">
<div class="subwindow-container">
<div class="subwindow-container-fix screens">
<t isShown="!state.tempScreen" t-component="mainScreen.component"
t-props="mainScreenProps" t-key="mainScreen.name" />
<t t-if="state.tempScreen" t-component="state.tempScreen.component"
t-props="state.tempScreen.props" t-key="state.tempScreen.name" />
<t isShown="!pos.tempScreen" t-component="pos.mainScreen.component"
t-props="pos.mainScreen.props" t-key="pos.mainScreen.name" />
<t t-if="pos.tempScreen" t-component="pos.tempScreen.component"
t-props="pos.tempScreen.props" t-key="pos.tempScreen.name" />
</div>
</div>
</div>
@@ -22,12 +22,12 @@
</div>
</t>
<Transition visible="['LOADING', 'CLOSING'].includes(state.uiState)" name="'o-swing'" leaveDuration="800" t-slot-scope="transition">
<Transition visible="['LOADING', 'CLOSING'].includes(pos.uiState)" name="'o-swing'" leaveDuration="800" t-slot-scope="transition">
<div class="loader" t-att-class="transition.className">
<div class="loader-feedback">
<!-- spinner from https://loading.io/css/ -->
<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>
<t t-if="state.loadingSkipButtonIsShown">
<t t-if="pos.loadingSkipButtonIsShown">
<h1 class="message">Connecting to devices</h1>
<div class="button skip" t-on-click="() => this.trigger('loading-skip-callback')">
Skip
@@ -36,14 +36,6 @@
</div>
</div>
</Transition>
<!-- Allow popups to be visible at any state of the ui. -->
<PosPopupController />
<Transition name="'o-fade'" visible="state.notification.isShown" leaveDuration="200" t-slot-scope="transition">
<Notification message="state.notification.message" duration="state.notification.duration" className="transition.className"/>
</Transition>
</div>
<WithEnv env="wowlEnv">
<MainComponentsContainer/>
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="Notification" owl="1">
<div class="notification" t-att-class="props.className">
<span>
<t t-esc="props.message" />
</span>
</div>
</t>
</templates>
@@ -6,6 +6,8 @@ import { PosComponent } from "@point_of_sale/js/PosComponent";
import makeTestEnvironment from "web.test_env";
import testUtils from "web.test_utils";
import { mount } from "@web/../tests/helpers/utils";
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
import { registry } from "@web/core/registry";
const { EventBus, useSubEnv, xml } = owl;
@@ -35,29 +37,46 @@ CustomPopup2.template = xml/* html */ `
</div>
`;
QUnit.module("unit tests for PosPopupController");
let env;
QUnit.module("unit tests for PosPopupController", {
async beforeEach() {
const posbus = new EventBus();
const makeService = (obj) => ({
start() {
return obj;
},
});
const legacyEnv = makeTestEnvironment();
registry.category("services").add("pos_notification", makeService({ add() {} }));
registry.category("services").add("sound", makeService({ play() {} }));
registry.category("services").add("pos", makeService({ legacyEnv }));
env = await makeTestEnv();
for (const service of ["pos", "pos_notification", "sound"]) {
legacyEnv.services[service] = env.services[service];
}
env.posbus = posbus;
legacyEnv.posbus = posbus;
},
});
QUnit.test("allow multiple popups at the same time", async function (assert) {
assert.expect(12);
class Root extends PosComponent {
static components = { PosPopupController };
setup() {
super.setup();
useSubEnv({
isDebug: () => false,
posbus: new EventBus(),
});
}
}
Root.env = makeTestEnvironment();
Root.template = xml/* html */ `
<div>
<PosPopupController />
</div>
`;
const root = await mount(Root, testUtils.prepareTarget());
const root = await mount(Root, testUtils.prepareTarget(), { env });
// Check 1 popup
let popup1Promise = root.showPopup(CustomPopup1, {});
@@ -117,18 +136,16 @@ QUnit.test("pressing cancel/confirm key should only close the top popup", async
super.setup();
useSubEnv({
isDebug: () => false,
posbus: new EventBus(),
});
}
}
Root.env = makeTestEnvironment();
Root.template = xml/* html */ `
<div>
<PosPopupController />
</div>
`;
const root = await mount(Root, testUtils.prepareTarget());
const root = await mount(Root, testUtils.prepareTarget(), { env });
const popup1Promise = root.showPopup(CustomPopup1, {
confirmKey: "Enter",
@@ -1,11 +1,11 @@
/* @odoo-module alias=pos_restaurant_hr.chrome */
import { Chrome } from '@point_of_sale/js/Chrome';
import { Chrome } from "@point_of_sale/js/Chrome";
import { patch } from "@web/core/utils/patch";
patch(Chrome.prototype, "pos_hr_restaurant.Chrome", {
//@override
_shouldResetIdleTimer() {
return this._super() && this.state.tempScreen?.name !== 'LoginScreen';
}
return this._super() && this.pos.tempScreen?.name !== "LoginScreen";
},
});
@@ -58,7 +58,7 @@ patch(Chrome.prototype, "pos_restaurant.Chrome", {
this.env.posbus.trigger("close-popups-but-error", { resolve })
);
if (isPopupClosed) {
if (this.state.tempScreen) {
if (this.pos.tempScreen) {
this.trigger("close-temp-screen");
}
const table = this.env.pos.table;
@@ -73,12 +73,12 @@ patch(Chrome.prototype, "pos_restaurant.Chrome", {
},
_shouldResetIdleTimer() {
const stayPaymentScreen =
this.mainScreen.name === "PaymentScreen" &&
this.pos.mainScreen.name === "PaymentScreen" &&
this.env.pos.get_order().paymentlines.length > 0;
return (
this.env.pos.config.iface_floorplan &&
!stayPaymentScreen &&
this.mainScreen.name !== "FloorScreen"
this.pos.mainScreen.name !== "FloorScreen"
);
},
__showScreen() {