[FIX] web: mail.MessagingMenu isn't always added in the systray

Steps to follow

  - Use chrome
  - Connect to a runbot with the demo account
  - After a couple refreshes, the mail.MessagingMenu isn't displayed

Cause of the issue

  The navbar should be updated when there is a new item added to the systray registry.
  For that, the navbar listen to the update event with the `useBus` function.
  `useBus` itself uses `useEffect` which only starts listening after a component has been mounted/patched.
  -> The update callback is never called in this case because new items are added before the callback is registered.

opw-2801467

closes odoo/odoo#92768

X-original-commit: c2fd26881ceae95417e2a0afc71fdf8567e3b8c0
Signed-off-by: Samuel Degueldre <sad@odoo.com>
Signed-off-by: Hubert Van De Walle <huvw@odoo.com>
This commit is contained in:
Hubert Van de Walle (huvw)
2022-06-02 16:54:25 +02:00
parent cef01fa521
commit a499263dd3
2 changed files with 38 additions and 5 deletions
@@ -2,12 +2,12 @@
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { useService, useBus } from "@web/core/utils/hooks";
import { useService } from "@web/core/utils/hooks";
import { registry } from "@web/core/registry";
import { debounce } from "@web/core/utils/timing";
import { ErrorHandler } from "@web/core/utils/components";
const { Component, onWillDestroy, useExternalListener, useEffect, useRef } = owl;
const { Component, onWillDestroy, onWillUnmount, useExternalListener, useEffect, useRef } = owl;
const systrayRegistry = registry.category("systray");
const getBoundingClientRect = Element.prototype.getBoundingClientRect;
@@ -47,8 +47,14 @@ export class NavBar extends Component {
this.render();
};
useBus(systrayRegistry, "UPDATE", renderAndAdapt);
useBus(this.env.bus, "MENUS:APP-CHANGED", renderAndAdapt);
systrayRegistry.on("UPDATE", this, renderAndAdapt);
this.env.bus.on("MENUS:APP-CHANGED", this, renderAndAdapt);
onWillUnmount(() => {
systrayRegistry.off("UPDATE", this);
this.env.bus.off("MENUS:APP-CHANGED", this);
});
// We don't want to adapt every time we are patched
// rather, we adapt only when menus or systrays have changed.
useEffect(
@@ -19,7 +19,7 @@ import {
mockTimeout,
} from "../helpers/utils";
const { Component, xml } = owl;
const { Component, xml, onRendered } = owl;
const systrayRegistry = registry.category("systray");
const serviceRegistry = registry.category("services");
@@ -174,6 +174,33 @@ QUnit.test("navbar can display systray items ordered based on their sequence", a
assert.strictEqual(menuSystray.innerText, "my item 3\nmy item 4\nmy item 2\nmy item 1");
});
QUnit.test("navbar updates after adding a systray item", async (assert) => {
class MyItem1 extends Component {}
MyItem1.template = xml`<li class="my-item-1">my item 1</li>`;
clearRegistryWithCleanup(systrayRegistry);
systrayRegistry.add('addon.myitem1', { Component: MyItem1 });
const env = await makeTestEnv(baseConfig);
patchWithCleanup(NavBar.prototype, {
setup() {
onRendered(() => {
if (!systrayRegistry.contains('addon.myitem2')) {
class MyItem2 extends Component {}
MyItem2.template = xml`<li class="my-item-2">my item 2</li>`;
systrayRegistry.add('addon.myitem2', {Component: MyItem2});
}
});
this._super();
}
});
await mount(NavBar, target, { env });
const menuSystray = target.getElementsByClassName("o_menu_systray")[0];
assert.containsN(menuSystray, "li", 2, "2 systray items should be displayed");
});
QUnit.test("can adapt with 'more' menu sections behavior", async (assert) => {
class MyNavbar extends NavBar {
async adapt() {