OWL
data_display
Web Client
Odoo 19 OWL component — Web Client (webclient)
Live preview
Interactive
Source excerpt
web/static/src/webclient/webclient.js
import { useOwnDebugContext } from "@web/core/debug/debug_context";
import { Deferred } from "@web/core/utils/concurrency";
import { DebugMenu } from "@web/core/debug/debug_menu";
import { localization } from "@web/core/l10n/localization";
import { MainComponentsContainer } from "@web/core/main_components_container";
import { registry } from "@web/core/registry";
import { useBus, useService } from "@web/core/utils/hooks";
import { ActionContainer } from "./actions/action_container";
import { NavBar } from "./navbar/navbar";
import { Component, onMounted, onWillStart, useExternalListener, useState } from "@odoo/owl";
import { router, routerBus } from "@web/core/browser/router";
import { browser } from "@web/core/browser/browser";
import { rpcBus } from "@web/core/network/rpc";
export class WebClient extends Component {
static template = "web.WebClient";
static props = {};
static components = {
ActionContainer,
NavBar,
MainComponentsContainer,
};
setup() {
this.menuService = useService("menu");
this.actionService = useService("action");
this.title = useService("title");
useOwnDebugContext({ categories: ["default"] });
if (this.env.debug) {
registry.category("systray").add(
"web.debug_mode_menu",
{
Component: DebugMenu,
},
{ sequence: 100 }
);
}
this.localization = localization;
this.state = useState({
fullscreen: false,
});
useBus(routerBus, "ROUTE_CHANGE", async () => {
document.body.style.pointerEvents = "none";
try {
await this.loadRouterState();
} finally {
document.body.style.pointerEvents = "auto";
}
});
useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", ({ detail: mode }) => {
if (mode !== "new") {
this.state.fullscreen = mode === "fullscreen";
}
});
useBus(this.env.bus, "WEBCLIENT:LOAD_DEFAULT_APP", this._loadDefaultApp);
onMounted(() => {
this.loadRouterState();
// the chat window and dialog services listen to 'web_client_ready' event in
// order to initialize themselves:
this.env.bus.trigger("WEB_CLIENT_READY");
});
useExternalListener(window, "click", this.onGlobalClick, { capture: true });
this.serviceWorkerActivatedDeferred = new Deferred();
onWillStart(this.registerServiceWorker);
}
async loadRouterState() {
// ** url-retrocompatibility **
// the menu_id in the url is only possible if we came from an old url
let menuId = Number(router.current.menu_id || 0);
const storedMenuId = Number(browser.sessionStorage.getItem("menu_id"));
const firstAction = router.current.actionStack?.[0]?.action;
if (!menuId && firstAction) {
// Find all menus that match this action
const matchingMenus = this.menuService
.getAll()
.filter((m) => m.actionID === firstAction || m.actionPath === firstAction);
if (matchingMenus.length > 0) {
// Use sessionStorage context to determine the correct menu
menuId = matchingMenus.find(m =>
m.appID === storedMenuId
)?.appID;
if (!menuId) {
menuId = matchingMenus[0]?.appID;
}
}
}
if (menuId) {
this.menuService.setCurrentMenu(menuId);
}
let stateLoaded = await this.actionService.loadState();
// ** url-retrocompatibility **
// when there is only menu_id in url
if (!stateLoaded && menuId) {
// Determines the current actionId based on the current menu
const menu = this.menuService.getAll().find((m) => menuId === m.id);
const actionId = menu && menu.actionID;
if (actionId) {
await this.actionService.doAction(actionId, { clearBreadcrumbs: true });
stateLoaded = true;
}
}
// Setting the menu based on the action after it was loaded (eg when the action in url is an xmlid)
if (stateLoaded && !menuId) {
// Determines the current menu based on the current action
const currentController = this.actionService.currentController;
const actionId = currentController && currentController.action.id;
menuId = this.menuService.getAll().find((m) => m.actionID === actionId)?.appID;
if (!menuId) {
// Setting the menu based on the session storage if no other menu was found
menuId = storedMenuId;
}
if (menuId) {
// Sets the menu according to the current action
this.menuService.setCurrentMenu(menuId);
}
Registry / API
- Registry name
WebClient- Category
—- Module
web- Slug
web-client- Nav group
data_display