From ff870d8d15cf65e156f35e3651b670cba2a9d72b Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Wed, 26 May 2021 07:26:28 +0000 Subject: [PATCH] [REF] web: replace use of other hooks with useEffect closes odoo-dev/odoo#883 Signed-off-by: Aaron Bohy (aab) --- addons/web/static/src/core/autofocus_hook.js | 19 ++++--- addons/web/static/src/core/bus_hook.js | 10 ++-- .../web/static/src/core/debug/debug_menu.js | 11 ++-- .../web/static/src/core/dropdown/dropdown.js | 10 ++-- addons/web/static/src/core/hotkey_hook.js | 15 ++---- addons/web/static/src/core/ui_service.js | 11 ++-- .../web/static/src/legacy/action_adapters.js | 51 +++++++++---------- .../static/src/legacy/js/core/custom_hooks.js | 35 ++++++------- .../legacy/js/fields/abstract_field_owl.js | 6 +-- .../legacy/js/views/pivot/pivot_renderer.js | 8 ++- addons/web/static/src/legacy/legacy_dialog.js | 10 ++-- .../src/webclient/actions/action_dialog.js | 5 +- .../src/webclient/actions/action_hook.js | 7 +-- .../src/webclient/commands/command_hook.js | 15 ++---- .../src/webclient/commands/command_palette.js | 5 +- .../src/webclient/effects/rainbow_man.js | 16 +++--- .../web/static/src/webclient/navbar/navbar.js | 11 ++-- .../src/webclient/user_menu/user_menu.js | 7 +-- addons/web/static/src/webclient/webclient.js | 20 ++++---- 19 files changed, 129 insertions(+), 143 deletions(-) diff --git a/addons/web/static/src/core/autofocus_hook.js b/addons/web/static/src/core/autofocus_hook.js index cf07d8bf3de..71ab91e72f4 100644 --- a/addons/web/static/src/core/autofocus_hook.js +++ b/addons/web/static/src/core/autofocus_hook.js @@ -1,6 +1,8 @@ /** @odoo-module **/ -const { onMounted, onPatched, useComponent } = owl.hooks; +import { useEffect } from "./effect_hook"; + +const { useComponent } = owl.hooks; // ----------------------------------------------------------------------------- // Hook functions @@ -23,21 +25,18 @@ export function useAutofocus(params = {}) { return () => {}; } const selector = params.selector || "[autofocus]"; - let target = null; - function autofocus() { - const prevTarget = target; - target = comp.el.querySelector(selector); - if (target && target !== prevTarget) { + let forceFocusCount = 0; + useEffect(function autofocus(target) { + if (target) { target.focus(); if (["INPUT", "TEXTAREA"].includes(target.tagName)) { const inputEl = target; inputEl.selectionStart = inputEl.selectionEnd = inputEl.value.length; } } - } - onMounted(autofocus); - onPatched(autofocus); + }, () => [comp.el.querySelector(selector), forceFocusCount]); + return function focusOnUpdate() { - target = null; + forceFocusCount++; // force the effect to rerun on next patch }; } diff --git a/addons/web/static/src/core/bus_hook.js b/addons/web/static/src/core/bus_hook.js index c6abd15e299..03920472031 100644 --- a/addons/web/static/src/core/bus_hook.js +++ b/addons/web/static/src/core/bus_hook.js @@ -1,6 +1,6 @@ /** @odoo-module **/ - -const { onMounted, onWillUnmount, useComponent } = owl.hooks; +import { useEffect } from "./effect_hook"; +const { useComponent } = owl.hooks; /** * This file contains various custom hooks. @@ -30,6 +30,8 @@ const { onMounted, onWillUnmount, useComponent } = owl.hooks; */ export function useBus(bus, eventName, callback) { const component = useComponent(); - onMounted(() => bus.on(eventName, component, callback)); - onWillUnmount(() => bus.off(eventName, component)); + useEffect(() => { + bus.on(eventName, component, callback); + return () => bus.off(eventName, component); + }, () => []); } diff --git a/addons/web/static/src/core/debug/debug_menu.js b/addons/web/static/src/core/debug/debug_menu.js index b4e6ef0bedf..409dd5a603a 100644 --- a/addons/web/static/src/core/debug/debug_menu.js +++ b/addons/web/static/src/core/debug/debug_menu.js @@ -1,11 +1,12 @@ /** @odoo-module **/ import { useService } from "../service_hook"; +import { useEffect } from "../effect_hook"; import { registry } from "../registry"; const debugRegistry = registry.category("debug"); -const { Component, hooks } = owl; +const { Component } = owl; export class DebugManager extends Component { setup() { @@ -79,10 +80,8 @@ export function useDebugManager(elementsFactory) { elementsFactory, inDialog: env.inDialog, }; - hooks.onMounted(() => { + useEffect(() => { env.bus.trigger("DEBUG-MANAGER:NEW-ITEMS", payload); - }); - hooks.onWillUnmount(() => { - env.bus.trigger("DEBUG-MANAGER:REMOVE-ITEMS", payload); - }); + return () => env.bus.trigger("DEBUG-MANAGER:REMOVE-ITEMS", payload); + }, () => []); } diff --git a/addons/web/static/src/core/dropdown/dropdown.js b/addons/web/static/src/core/dropdown/dropdown.js index 781a2ceed92..8590f4baa5d 100644 --- a/addons/web/static/src/core/dropdown/dropdown.js +++ b/addons/web/static/src/core/dropdown/dropdown.js @@ -2,12 +2,13 @@ import { useBus } from "../bus_hook"; import { useService } from "../service_hook"; +import { useEffect } from "../effect_hook"; import { scrollTo } from "../utils/scrolling"; import { ParentClosingMode } from "./dropdown_item"; const { Component, core, hooks, useState, QWeb } = owl; const { EventBus } = core; -const { useExternalListener, onMounted, onPatched, onWillStart } = hooks; +const { useExternalListener, onWillStart } = hooks; /** * @typedef DropdownState @@ -52,11 +53,11 @@ export class Dropdown extends Component { this.close(); } }); - onMounted(() => { + useEffect(() => { Promise.resolve().then(() => { this.myActiveEl = this.ui.activeElement; }); - }); + }, () => []); // Set up key navigation ----------------------------------------------- this.hotkeyService = useService("hotkey"); @@ -124,8 +125,7 @@ export class Dropdown extends Component { } } - onMounted(autoSubscribeKeynav.bind(this)); - onPatched(autoSubscribeKeynav.bind(this)); + useEffect(autoSubscribeKeynav.bind(this)); } // ------------------------------------------------------------------------- diff --git a/addons/web/static/src/core/hotkey_hook.js b/addons/web/static/src/core/hotkey_hook.js index f00e0844c89..cc7fbac3cb3 100644 --- a/addons/web/static/src/core/hotkey_hook.js +++ b/addons/web/static/src/core/hotkey_hook.js @@ -1,9 +1,7 @@ /** @odoo-module */ import { useService } from "./service_hook"; - -const { hooks } = owl; -const { onMounted, onWillUnmount } = hooks; +import { useEffect } from "./effect_hook"; /** * This hook will register/unregister the given registration @@ -21,11 +19,8 @@ const { onMounted, onWillUnmount } = hooks; */ export function useHotkey(hotkey, callback, options = {}) { const hotkeyService = useService("hotkey"); - let token; - onMounted(() => { - token = hotkeyService.registerHotkey(hotkey, callback, options); - }); - onWillUnmount(() => { - hotkeyService.unregisterHotkey(token); - }); + useEffect(() => { + const token = hotkeyService.registerHotkey(hotkey, callback, options); + return () => hotkeyService.unregisterHotkey(token); + }, () => []); } diff --git a/addons/web/static/src/core/ui_service.js b/addons/web/static/src/core/ui_service.js index ec42d07cb8b..ab1e1c84cd7 100644 --- a/addons/web/static/src/core/ui_service.js +++ b/addons/web/static/src/core/ui_service.js @@ -3,10 +3,11 @@ import { useService } from "./service_hook"; import { registry } from "./registry"; import { debounce } from "./utils/timing"; +import { useEffect } from "./effect_hook"; const { Component, core, hooks } = owl; const { EventBus } = core; -const { onMounted, onWillUnmount, useRef } = hooks; +const { useRef } = hooks; export const SIZES = { XS: 0, VSM: 1, SM: 2, MD: 3, LG: 4, XL: 5, XXL: 6 }; @@ -24,12 +25,10 @@ export const SIZES = { XS: 0, VSM: 1, SM: 2, MD: 3, LG: 4, XL: 5, XXL: 6 }; export function useActiveElement(refName = null) { const uiService = useService("ui"); const owner = refName ? useRef(refName) : Component.current; - onMounted(() => { + useEffect(() => { uiService.activateElement(owner.el); - }); - onWillUnmount(() => { - uiService.deactivateElement(owner.el); - }); + return () => uiService.deactivateElement(owner.el); + }, () => []); } export const uiService = { diff --git a/addons/web/static/src/legacy/action_adapters.js b/addons/web/static/src/legacy/action_adapters.js index 07abbbb7ae4..669586ee023 100644 --- a/addons/web/static/src/legacy/action_adapters.js +++ b/addons/web/static/src/legacy/action_adapters.js @@ -3,6 +3,8 @@ import core from "web.core"; import Context from "web.Context"; import { useService } from "../core/service_hook"; +import { useEffect } from "../core/effect_hook"; +import { useBus } from "../core/bus_hook"; import { ViewNotFoundError } from "../webclient/actions/action_service"; import { useDebugManager } from "../core/debug/debug_menu"; import { objectToQuery } from "../core/browser/router_service"; @@ -11,7 +13,7 @@ import { mapDoActionOptionAPI } from "./utils"; import { setupDebugAction, setupDebugViewForm, setupDebugView } from "./debug_manager"; import { cleanDomFromBootstrap } from "./utils"; -const { Component, hooks, tags } = owl; +const { Component, tags } = owl; function wrapSuccessOrFail(promise, { on_success, on_fail } = {}) { return promise.then(on_success || (() => {})).catch((reason) => { @@ -38,7 +40,7 @@ class ActionAdapter extends ComponentAdapter { // This is protected in legacy (backward compatibility) but should not e supported in Wowl this.tempQuery = {}; let originalUpdateControlPanel; - hooks.onMounted(async () => { + useEffect(() => { this.title.setParts({ action: this.widget.getTitle() }); const query = objectToQuery(this.widget.getState()); Object.assign(query, this.tempQuery); @@ -58,15 +60,14 @@ class ActionAdapter extends ComponentAdapter { this.trigger("controller-title-updated", this.__widget.getTitle()); return originalUpdateControlPanel(newProps); }; - await Promise.resolve(); // see https://github.com/odoo/owl/issues/809 this.trigger("controller-title-updated", this.__widget.getTitle()); - core.bus.trigger("DOM_updated"); - }); - hooks.onWillUnmount(() => { - this.__widget.updateControlPanel = originalUpdateControlPanel; - this.wowlEnv.bus.off("ACTION_MANAGER:UPDATE", this); - }); + + return () => { + this.__widget.updateControlPanel = originalUpdateControlPanel; + this.wowlEnv.bus.off("ACTION_MANAGER:UPDATE", this); + }; + }, () => []); } _trigger_up(ev) { @@ -189,7 +190,7 @@ function useMagicLegacyReload() { let legacyReloadProm = null; const getReloadProm = () => legacyReloadProm; let manualReload; - hooks.onMounted(() => { + useEffect(() => { const widget = comp.widget; const controllerReload = widget.reload; widget.reload = function (...args) { @@ -216,7 +217,7 @@ function useMagicLegacyReload() { }); }; widget[magicReloadSymbol] = getReloadProm; - }); + }, () => []); return getReloadProm; } @@ -240,22 +241,20 @@ export class ViewAdapter extends ActionAdapter { ); } if (!envWowl.inDialog) { - hooks.onMounted(() => { - envWowl.bus.on("ACTION_MANAGER:UPDATE", this, (info) => { - switch (info.type) { - case "OPEN_DIALOG": { - // we are a main action, and a dialog is going to open: - // we should not reload - this.shouldUpdateWidget = false; - break; - } - case "CLOSE_DIALOG": { - this.shouldUpdateWidget = false; - info.closingProms.push(() => this.magicReload()); - break; - } + useBus(envWowl.bus, "ACTION_MANAGER:UPDATE", (info) => { + switch (info.type) { + case "OPEN_DIALOG": { + // we are a main action, and a dialog is going to open: + // we should not reload + this.shouldUpdateWidget = false; + break; } - }); + case "CLOSE_DIALOG": { + this.shouldUpdateWidget = false; + info.closingProms.push(() => this.magicReload()); + break; + } + } }); } this.env = Component.env; diff --git a/addons/web/static/src/legacy/js/core/custom_hooks.js b/addons/web/static/src/legacy/js/core/custom_hooks.js index 883f385ac3c..44515ee3cb5 100644 --- a/addons/web/static/src/legacy/js/core/custom_hooks.js +++ b/addons/web/static/src/legacy/js/core/custom_hooks.js @@ -1,8 +1,8 @@ -odoo.define('web.custom_hooks', function () { +odoo.define('web.custom_hooks', function (require) { "use strict"; - const { Component, hooks } = owl; - const { onMounted, onPatched, onWillUnmount } = hooks; + const { Component } = owl; + const { useEffect } = require("@web/core/effect_hook"); /** * Focus a given selector as soon as it appears in the DOM and if it was not @@ -20,22 +20,19 @@ odoo.define('web.custom_hooks', function () { return () => {}; } const selector = params.selector || '[autofocus]'; - let target = null; - function autofocus() { - const prevTarget = target; - target = comp.el.querySelector(selector); - if (target && target !== prevTarget) { + let forceFocusCount = 0; + useEffect(function autofocus(target) { + if (target) { target.focus(); - if (['INPUT', 'TEXTAREA'].includes(target.tagName)) { - target.selectionStart = target.selectionEnd = target.value.length; + if (["INPUT", "TEXTAREA"].includes(target.tagName)) { + const inputEl = target; + inputEl.selectionStart = inputEl.selectionEnd = inputEl.value.length; } } - } - onMounted(autofocus); - onPatched(autofocus); + }, () => [comp.el.querySelector(selector), forceFocusCount]); return function focusOnUpdate() { - target = null; + forceFocusCount++; // force the effect to rerun on next patch }; } @@ -103,12 +100,12 @@ odoo.define('web.custom_hooks', function () { } else { boundHandler = handler.bind(comp); } - onMounted(function () { + useEffect(() => { comp.el.addEventListener(eventName, boundHandler, addEventListenerOptions); - }); - onWillUnmount(function () { - comp.el.removeEventListener(eventName, boundHandler, addEventListenerOptions); - }); + return () => { + comp.el.removeEventListener(eventName, boundHandler, addEventListenerOptions); + }; + }, () => []); } return { diff --git a/addons/web/static/src/legacy/js/fields/abstract_field_owl.js b/addons/web/static/src/legacy/js/fields/abstract_field_owl.js index 2035c9d7a6f..afce40c9ebb 100644 --- a/addons/web/static/src/legacy/js/fields/abstract_field_owl.js +++ b/addons/web/static/src/legacy/js/fields/abstract_field_owl.js @@ -3,8 +3,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { const field_utils = require('web.field_utils'); const { useListener } = require('web.custom_hooks'); - - const { onMounted, onPatched } = owl.hooks; + const { useEffect } = require('@web/core/effect_hook'); /** * This file defines the Owl version of the AbstractField. Specific fields @@ -71,8 +70,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { useListener('click', this._onClick); useListener('keydown', this._onKeydown); useListener('navigation-move', this._onNavigationMove); - onMounted(() => this._applyDecorations()); - onPatched(() => this._applyDecorations()); + useEffect(() => this._applyDecorations()); } /** * Hack: studio tries to find the field with a selector base on its diff --git a/addons/web/static/src/legacy/js/views/pivot/pivot_renderer.js b/addons/web/static/src/legacy/js/views/pivot/pivot_renderer.js index 67493529613..7e73d761b94 100644 --- a/addons/web/static/src/legacy/js/views/pivot/pivot_renderer.js +++ b/addons/web/static/src/legacy/js/views/pivot/pivot_renderer.js @@ -1,12 +1,13 @@ /** @odoo-module alias=web.PivotRenderer **/ + import { useEffect } from "@web/core/effect_hook"; import DropdownMenu from 'web.DropdownMenu'; import DropdownMenuItem from 'web.DropdownMenuItem'; import OwlAbstractRenderer from '../abstract_renderer_owl'; import field_utils from 'web.field_utils'; import { DEFAULT_INTERVAL, INTERVAL_OPTIONS } from 'web.searchUtils'; - const { useExternalListener, useState, onMounted, onPatched } = owl.hooks; + const { useExternalListener, useState } = owl.hooks; class PivotCustomGroupByItem extends DropdownMenuItem { constructor() { @@ -146,10 +147,7 @@ this.hasSearchArchGroupBys = Boolean(searchArchGroupBys && searchArchGroupBys.length); this.customGroupBys = new Map(); - onMounted(() => this._updateTooltip()); - - onPatched(() => this._updateTooltip()); - + useEffect(() => this._updateTooltip()); useExternalListener(window, 'click', this._resetState); } diff --git a/addons/web/static/src/legacy/legacy_dialog.js b/addons/web/static/src/legacy/legacy_dialog.js index a7e07933fa6..bc3433ab2ec 100644 --- a/addons/web/static/src/legacy/legacy_dialog.js +++ b/addons/web/static/src/legacy/legacy_dialog.js @@ -2,10 +2,10 @@ import { Dialog } from "../core/dialog/dialog"; import { patch } from "@web/core/utils/patch"; +import { useEffect } from "@web/core/effect_hook"; import OwlDialog from "web.OwlDialog"; const { hooks } = owl; -const { onMounted, onWillUnmount } = hooks; /** * This is a patch of the new Dialog class. @@ -14,11 +14,9 @@ const { onMounted, onWillUnmount } = hooks; patch(Dialog.prototype, "Legacy Adapted Dialog", { setup() { this._super(); - onMounted(() => { + useEffect(() => { OwlDialog.display(this); - }); - onWillUnmount(() => { - OwlDialog.hide(this); - }); + return () => OwlDialog.hide(this); + }, () => []); }, }); diff --git a/addons/web/static/src/webclient/actions/action_dialog.js b/addons/web/static/src/webclient/actions/action_dialog.js index 8fbf07aaad8..7ed15852573 100644 --- a/addons/web/static/src/webclient/actions/action_dialog.js +++ b/addons/web/static/src/webclient/actions/action_dialog.js @@ -2,6 +2,7 @@ import { Dialog } from "../../core/dialog/dialog"; import { DebugManager } from "../../core/debug/debug_menu"; +import { useEffect } from "../../core/effect_hook"; const { hooks } = owl; @@ -46,7 +47,7 @@ class LegacyAdaptedActionDialog extends ActionDialog { const ControllerComponent = this.props && this.props.ActionComponent; const Controller = ControllerComponent && ControllerComponent.Component; this.isLegacy = Controller && Controller.isLegacy; - hooks.onMounted(() => { + useEffect(() => { if (this.isLegacy) { // Retrieve the widget climbing the wrappers const componentController = this.actionRef.comp; @@ -57,7 +58,7 @@ class LegacyAdaptedActionDialog extends ActionDialog { const footer = this.modalRef.el.querySelector("footer"); widget.renderButtons($(footer)); } - }); + }, () => []); // TODO: should this depend on actionRef.comp? } } LegacyAdaptedActionDialog.template = "web.LegacyAdaptedActionDialog"; diff --git a/addons/web/static/src/webclient/actions/action_hook.js b/addons/web/static/src/webclient/actions/action_hook.js index 4b0f282acc8..a7e5b1fafbe 100644 --- a/addons/web/static/src/webclient/actions/action_hook.js +++ b/addons/web/static/src/webclient/actions/action_hook.js @@ -1,8 +1,9 @@ /** @odoo-module **/ import { getScrollPosition, setScrollPosition } from "../../core/utils/scrolling"; +import { useEffect } from "../../core/effect_hook"; -const { useComponent, onMounted } = owl.hooks; +const { useComponent } = owl.hooks; // ----------------------------------------------------------------------------- // Action hook @@ -17,7 +18,7 @@ const scrollSymbol = Symbol("scroll"); export function useSetupAction(params) { const component = useComponent(); - onMounted(() => { + useEffect(() => { if (component.props.registerCallback) { if (params.beforeLeave) { component.props.registerCallback("beforeLeave", params.beforeLeave); @@ -34,5 +35,5 @@ export function useSetupAction(params) { if (component.props.state) { setScrollPosition(component, component.props.state[scrollSymbol]); } - }); + }, () => []); } diff --git a/addons/web/static/src/webclient/commands/command_hook.js b/addons/web/static/src/webclient/commands/command_hook.js index 2b405a3d313..b4a900477ac 100644 --- a/addons/web/static/src/webclient/commands/command_hook.js +++ b/addons/web/static/src/webclient/commands/command_hook.js @@ -1,9 +1,7 @@ /** @odoo-module **/ import { useService } from "../../core/service_hook"; - -const { hooks } = owl; -const { onMounted, onWillUnmount } = hooks; +import { useEffect } from "../../core/effect_hook"; /** * @typedef {import("./command_service").Command} Command @@ -17,11 +15,8 @@ const { onMounted, onWillUnmount } = hooks; */ export function useCommand(command) { const commandService = useService("command"); - let token; - onMounted(() => { - token = commandService.registerCommand(command); - }); - onWillUnmount(() => { - commandService.unregisterCommand(token); - }); + useEffect(() => { + const token = commandService.registerCommand(command); + return () => commandService.unregisterCommand(token); + }, () => []); } diff --git a/addons/web/static/src/webclient/commands/command_palette.js b/addons/web/static/src/webclient/commands/command_palette.js index e3b547d9e62..807e7725a28 100644 --- a/addons/web/static/src/webclient/commands/command_palette.js +++ b/addons/web/static/src/webclient/commands/command_palette.js @@ -2,11 +2,12 @@ import { registry } from "@web/core/registry"; import { useAutofocus } from "../../core/autofocus_hook"; +import { useEffect } from "../../core/effect_hook"; import { useHotkey } from "../../core/hotkey_hook"; import { scrollTo } from "../../core/utils/scrolling"; const { Component, hooks } = owl; -const { onPatched, useState } = hooks; +const { useState } = hooks; const commandCategoryRegistry = registry.category("command_categories"); /** @@ -51,7 +52,7 @@ export class CommandPalette extends Component { useAutofocus(); this.mouseSelectionActive = false; - onPatched(() => { + useEffect(() => { const index = this.state.commands.indexOf(this.state.selectedCommand); const listbox = this.el.querySelector(".o_command_palette_listbox"); const command = listbox.querySelector(`#o_command_${index}`); diff --git a/addons/web/static/src/webclient/effects/rainbow_man.js b/addons/web/static/src/webclient/effects/rainbow_man.js index b169a0a11a7..befd1afdcbf 100644 --- a/addons/web/static/src/webclient/effects/rainbow_man.js +++ b/addons/web/static/src/webclient/effects/rainbow_man.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { browser } from "../../core/browser/browser"; +import { useEffect } from "../../core/effect_hook"; const { Component, hooks } = owl; @@ -28,15 +29,14 @@ export class RainbowMan extends Component { const fadeout = "fadeout" in this.props ? this.props.fadeout : "medium"; const delay = fadeout ? RainbowMan.rainbowFadeouts[fadeout] : false; this.delay = typeof delay === "number" ? delay : false; - hooks.onMounted(() => { - if (this.delay !== false) { - browser.setTimeout(() => { - if (this.__owl__.status !== 5 /* DESTROYED */) { - this.el.classList.add("o_reward_fading"); - } + if (this.delay !== false) { + useEffect(() => { + const timeout = browser.setTimeout(() => { + this.el.classList.add("o_reward_fading"); }, this.delay); - } - }); + return () => browser.clearTimeout(timeout); + }, () => []); + } } onAnimationEnd(ev) { diff --git a/addons/web/static/src/webclient/navbar/navbar.js b/addons/web/static/src/webclient/navbar/navbar.js index 51638f20376..206f19bb985 100644 --- a/addons/web/static/src/webclient/navbar/navbar.js +++ b/addons/web/static/src/webclient/navbar/navbar.js @@ -3,22 +3,23 @@ import { Dropdown } from "../../core/dropdown/dropdown"; import { DropdownItem } from "../../core/dropdown/dropdown_item"; import { useService } from "../../core/service_hook"; +import { useEffect } from "../../core/effect_hook"; import { registry } from "../../core/registry"; import { debounce } from "../../core/utils/timing"; const { Component, hooks } = owl; -const { onMounted, useExternalListener } = hooks; +const { useExternalListener } = hooks; const systrayRegistry = registry.category("systray"); export class MenuDropdown extends Dropdown { setup() { super.setup(); - onMounted(() => { + useEffect(() => { if (this.props.xmlid) { const toggler = this.el.querySelector("button.o_dropdown_toggler"); toggler.dataset.menuXmlid = this.props.xmlid; } - }); + }, () => []); } } MenuDropdown.props.xmlid = { @@ -29,11 +30,11 @@ MenuDropdown.props.xmlid = { export class MenuItem extends DropdownItem { setup() { super.setup(); - onMounted(() => { + useEffect(() => { if (this.props.payload.xmlid) { this.el.dataset.menuXmlid = this.props.payload.xmlid; } - }); + }, () => []); } } diff --git a/addons/web/static/src/webclient/user_menu/user_menu.js b/addons/web/static/src/webclient/user_menu/user_menu.js index ccdd8b2bd51..388bbf1eb5c 100644 --- a/addons/web/static/src/webclient/user_menu/user_menu.js +++ b/addons/web/static/src/webclient/user_menu/user_menu.js @@ -4,19 +4,20 @@ import { browser } from "../../core/browser/browser"; import { DropdownItem } from "../../core/dropdown/dropdown_item"; import { useService } from "../../core/service_hook"; import { registry } from "../../core/registry"; +import { useEffect } from "../../core/effect_hook"; -const { Component, hooks } = owl; +const { Component } = owl; const userMenuRegistry = registry.category("user_menuitems"); class UserMenuItem extends DropdownItem { setup() { super.setup(); - hooks.onMounted(() => { + useEffect(() => { if (this.props.payload.id) { this.el.dataset.menu = this.props.payload.id; } - }); + }, () => []); } } diff --git a/addons/web/static/src/webclient/webclient.js b/addons/web/static/src/webclient/webclient.js index b230137fa59..40923ae44f2 100644 --- a/addons/web/static/src/webclient/webclient.js +++ b/addons/web/static/src/webclient/webclient.js @@ -2,10 +2,12 @@ import { registry } from "../core/registry"; import { useService } from "../core/service_hook"; +import { useBus } from "../core/bus_hook"; import { ActionContainer } from "./actions/action_container"; import { NavBar } from "./navbar/navbar"; +import { useEffect } from "@web/core/effect_hook"; -const { Component, hooks } = owl; +const { Component } = owl; const mainComponentRegistry = registry.category("main_components"); export class WebClient extends Component { @@ -18,15 +20,15 @@ export class WebClient extends Component { useService("legacy_service_provider"); this.Components = mainComponentRegistry.getEntries(); this.title.setParts({ zopenerp: "Odoo" }); // zopenerp is easy to grep - hooks.onMounted(() => { - this.env.bus.on("ROUTE_CHANGE", this, this.loadRouterState); - this.env.bus.on("ACTION_MANAGER:UI-UPDATED", this, (mode) => { - if (mode !== "new") { - this.el.classList.toggle("o_fullscreen", mode === "fullscreen"); - } - }); - this.loadRouterState(); + useBus(this.env.bus, "ROUTE_CHANGE", this.loadRouterState); + useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", (mode) => { + if (mode !== "new") { + this.el.classList.toggle("o_fullscreen", mode === "fullscreen"); + } }); + useEffect(() => { + this.loadRouterState(); + }, () => []); } mounted() {