From f4bb46cd2938dbc98dd2080793d8a93c0210c6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 3 Jun 2021 16:49:57 +0200 Subject: [PATCH] [REF] web: update systray registry to take Component/props --- .../static/src/core/debug/debug_service.js | 8 +- .../static/src/legacy/systray_menu_item.js | 2 +- .../web/static/src/webclient/navbar/navbar.js | 30 ++- .../static/src/webclient/navbar/navbar.xml | 4 +- .../switch_company_menu.js | 15 +- .../src/webclient/user_menu/user_menu.js | 23 +- .../static/tests/webclient/navbar_tests.js | 223 +++++++++--------- 7 files changed, 163 insertions(+), 142 deletions(-) diff --git a/addons/web/static/src/core/debug/debug_service.js b/addons/web/static/src/core/debug/debug_service.js index 8717e78da2b..a29948abc29 100644 --- a/addons/web/static/src/core/debug/debug_service.js +++ b/addons/web/static/src/core/debug/debug_service.js @@ -21,7 +21,13 @@ export const debugService = { start(env, { orm }) { let accessRightsProm; if (env.debug !== "") { - registry.category("systray").add("web.debug_mode_menu", DebugMenu, { sequence: 100 }); + registry.category("systray").add( + "web.debug_mode_menu", + { + Component: DebugMenu, + }, + { sequence: 100 } + ); } return { diff --git a/addons/web/static/src/legacy/systray_menu_item.js b/addons/web/static/src/legacy/systray_menu_item.js index 3af51cebacb..44adf61ec56 100644 --- a/addons/web/static/src/legacy/systray_menu_item.js +++ b/addons/web/static/src/legacy/systray_menu_item.js @@ -32,7 +32,7 @@ function addSystrayItem(Widget) { SystrayItem.template = tags.xml``; SystrayItem.components = { SystrayItemAdapter }; - systrayRegistry.add(name, SystrayItem, { sequence: Widget.prototype.sequence }); + systrayRegistry.add(name, { Component: SystrayItem }, { sequence: Widget.prototype.sequence }); convertedItems.push(Widget); } diff --git a/addons/web/static/src/webclient/navbar/navbar.js b/addons/web/static/src/webclient/navbar/navbar.js index 7f9a9e287cb..d90abd68e7a 100644 --- a/addons/web/static/src/webclient/navbar/navbar.js +++ b/addons/web/static/src/webclient/navbar/navbar.js @@ -14,12 +14,15 @@ const systrayRegistry = registry.category("systray"); export class MenuDropdown extends Dropdown { setup() { super.setup(); - useEffect(() => { - if (this.props.xmlid) { - const toggler = this.el.querySelector("button.o_dropdown_toggler"); - toggler.dataset.menuXmlid = this.props.xmlid; - } - }, () => []); + useEffect( + () => { + if (this.props.xmlid) { + const toggler = this.el.querySelector("button.o_dropdown_toggler"); + toggler.dataset.menuXmlid = this.props.xmlid; + } + }, + () => [] + ); } } MenuDropdown.props.xmlid = { @@ -30,11 +33,14 @@ MenuDropdown.props.xmlid = { export class MenuItem extends DropdownItem { setup() { super.setup(); - useEffect(() => { - if (this.props.payload.xmlid) { - this.el.dataset.menuXmlid = this.props.payload.xmlid; - } - }, () => []); + useEffect( + () => { + if (this.props.payload.xmlid) { + this.el.dataset.menuXmlid = this.props.payload.xmlid; + } + }, + () => [] + ); } } @@ -77,7 +83,7 @@ export class NavBar extends Component { get systrayItems() { return systrayRegistry .getAll() - .filter((Item) => ("isDisplayed" in Item ? Item.isDisplayed(this.env) : true)) + .filter((item) => ("isDisplayed" in item ? item.isDisplayed(this.env) : true)) .reverse(); } diff --git a/addons/web/static/src/webclient/navbar/navbar.xml b/addons/web/static/src/webclient/navbar/navbar.xml index cbf8a0cb295..db4e8fa1d07 100644 --- a/addons/web/static/src/webclient/navbar/navbar.xml +++ b/addons/web/static/src/webclient/navbar/navbar.xml @@ -24,8 +24,8 @@ diff --git a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js index 4a8ebc5d1f0..0688c2617e3 100644 --- a/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js +++ b/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js @@ -9,11 +9,6 @@ const { Component, hooks } = owl; const { useState } = hooks; export class SwitchCompanyMenu extends Component { - static isDisplayed(env) { - const { availableCompanies } = env.services.company; - return Object.keys(availableCompanies).length > 1 && !env.isSmall; - } - setup() { this.companyService = useService("company"); this.currentCompany = this.companyService.currentCompany; @@ -45,4 +40,12 @@ export class SwitchCompanyMenu extends Component { SwitchCompanyMenu.template = "web.SwitchCompanyMenu"; SwitchCompanyMenu.toggleDelay = 1000; -registry.category("systray").add("SwitchCompanyMenu", SwitchCompanyMenu, { sequence: 1 }); +const systrayItem = { + Component: SwitchCompanyMenu, + isDisplayed(env) { + const { availableCompanies } = env.services.company; + return Object.keys(availableCompanies).length > 1 && !env.isSmall; + }, +}; + +registry.category("systray").add("SwitchCompanyMenu", systrayItem, { sequence: 1 }); 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 388bbf1eb5c..d44cff2b55a 100644 --- a/addons/web/static/src/webclient/user_menu/user_menu.js +++ b/addons/web/static/src/webclient/user_menu/user_menu.js @@ -13,19 +13,18 @@ const userMenuRegistry = registry.category("user_menuitems"); class UserMenuItem extends DropdownItem { setup() { super.setup(); - useEffect(() => { - if (this.props.payload.id) { - this.el.dataset.menu = this.props.payload.id; - } - }, () => []); + useEffect( + () => { + if (this.props.payload.id) { + this.el.dataset.menu = this.props.payload.id; + } + }, + () => [] + ); } } export class UserMenu extends Component { - static isDisplayed(env) { - return !env.isSmall; - } - setup() { this.user = useService("user"); const { origin } = browser.location; @@ -58,4 +57,8 @@ export class UserMenu extends Component { UserMenu.template = "web.UserMenu"; UserMenu.components = { UserMenuItem }; -registry.category("systray").add("web.user_menu", UserMenu, { sequence: 0 }); +const systrayItem = { + Component: UserMenu, + isDisplayed: (env) => !env.isSmall, +}; +registry.category("systray").add("web.user_menu", systrayItem, { sequence: 0 }); diff --git a/addons/web/static/tests/webclient/navbar_tests.js b/addons/web/static/tests/webclient/navbar_tests.js index 3bdd5fd7b09..7176376bc7e 100644 --- a/addons/web/static/tests/webclient/navbar_tests.js +++ b/addons/web/static/tests/webclient/navbar_tests.js @@ -27,7 +27,7 @@ QUnit.module("Navbar", { serviceRegistry.add("notification", notificationService); serviceRegistry.add("hotkey", hotkeyService); serviceRegistry.add("ui", uiService); - systrayRegistry.add("addon.myitem", MySystrayItem); + systrayRegistry.add("addon.myitem", { Component: MySystrayItem }); patchWithCleanup(browser, { setTimeout: (handler, delay, ...args) => handler(...args), clearTimeout: () => {}, @@ -154,10 +154,10 @@ QUnit.test("navbar can display systray items ordered based on their sequence", a MyItem4.template = xml`
  • my item 4
  • `; clearRegistryWithCleanup(systrayRegistry); - systrayRegistry.add("addon.myitem2", MyItem2); - systrayRegistry.add("addon.myitem1", MyItem1, { sequence: 0 }); - systrayRegistry.add("addon.myitem3", MyItem3, { sequence: 100 }); - systrayRegistry.add("addon.myitem4", MyItem4); + systrayRegistry.add("addon.myitem2", { Component: MyItem2 }); + systrayRegistry.add("addon.myitem1", { Component: MyItem1 }, { sequence: 0 }); + systrayRegistry.add("addon.myitem3", { Component: MyItem3 }, { sequence: 100 }); + systrayRegistry.add("addon.myitem4", { Component: MyItem4 }); const env = await makeTestEnv(baseConfig); const target = getFixture(); const navbar = await mount(NavBar, { env, target }); @@ -202,11 +202,7 @@ QUnit.test("can adapt with 'more' menu sections behavior", async (assert) => { 3, "should have 3 menu sections displayed (that are not the 'more' menu)" ); - assert.containsNone( - navbar.el, - ".o_menu_sections_more", - "the 'more' menu should not exist" - ); + assert.containsNone(navbar.el, ".o_menu_sections_more", "the 'more' menu should not exist"); // Force minimal width and dispatch window resize event navbar.el.style.width = "0%"; window.dispatchEvent(new Event("resize")); @@ -238,11 +234,7 @@ QUnit.test("can adapt with 'more' menu sections behavior", async (assert) => { 3, "should have 3 menu sections displayed (that are not the 'more' menu)" ); - assert.containsNone( - navbar.el, - ".o_menu_sections_more", - "the 'more' menu should not exist" - ); + assert.containsNone(navbar.el, ".o_menu_sections_more", "the 'more' menu should not exist"); // Check the navbar adaptation calls assert.verifySteps([ "adapt -> hide 0/3 sections", @@ -252,104 +244,115 @@ QUnit.test("can adapt with 'more' menu sections behavior", async (assert) => { navbar.destroy(); }); -QUnit.test("'more' menu sections adaptations do not trigger render in some cases", async (assert) => { - let adaptRunning = false; - let adaptCount = 0; - let adaptRenderCount = 0; - class MyNavbar extends NavBar { - async adapt() { - adaptRunning = true; - adaptCount++; - await super.adapt(); - adaptRunning = false; - } - async render() { - if (adaptRunning) { - adaptRenderCount++; +QUnit.test( + "'more' menu sections adaptations do not trigger render in some cases", + async (assert) => { + let adaptRunning = false; + let adaptCount = 0; + let adaptRenderCount = 0; + class MyNavbar extends NavBar { + async adapt() { + adaptRunning = true; + adaptCount++; + await super.adapt(); + adaptRunning = false; + } + async render() { + if (adaptRunning) { + adaptRenderCount++; + } + await super.render(...arguments); } - await super.render(...arguments); } + + const newMenus = { + root: { id: "root", children: [1], name: "root", appID: "root" }, + 1: { id: 1, children: [11, 12, 13], name: "App1", appID: 1 }, + 11: { id: 11, children: [], name: "Section 1", appID: 1 }, + 12: { id: 12, children: [], name: "Section 2", appID: 1 }, + 13: { id: 13, children: [], name: "Section 3", appID: 1 }, + }; + baseConfig.serverData.menus = newMenus; + + // Force the parent width, to make this test independent of screen size + const target = getFixture(); + target.style.width = "600px"; + + const env = await makeTestEnv(baseConfig); + const navbar = await mount(MyNavbar, { env, target }); + assert.strictEqual(navbar.currentAppSections.length, 0, "0 app sub menus"); + assert.strictEqual(navbar.el.offsetWidth, 600); + assert.strictEqual(adaptCount, 1); + assert.strictEqual( + adaptRenderCount, + 0, + "during adapt, render not triggered as the navbar has no app sub menus" + ); + + // Force minimal width and dispatch window resize event + navbar.el.style.width = "0%"; + window.dispatchEvent(new Event("resize")); + await nextTick(); + assert.strictEqual(navbar.el.offsetWidth, 0); + assert.strictEqual(adaptCount, 2); + assert.strictEqual( + adaptRenderCount, + 0, + "during adapt, render not triggered as the navbar has no app sub menus" + ); + + // Set menu + env.services.menu.setCurrentMenu(1); + await nextTick(); + assert.strictEqual(navbar.currentAppSections.length, 3, "3 app sub menus"); + assert.strictEqual( + navbar.currentAppSectionsExtra.length, + 3, + "all app sub menus are inside the more menu" + ); + assert.strictEqual(adaptCount, 3); + assert.strictEqual( + adaptRenderCount, + 1, + "during adapt, render triggered as the navbar does not have enough space for app sub menus" + ); + + // Force 40% width and dispatch window resize event + navbar.el.style.width = "40%"; + window.dispatchEvent(new Event("resize")); + await nextTick(); + assert.strictEqual( + navbar.currentAppSectionsExtra.length, + 3, + "all app sub menus are STILL inside the more menu" + ); + assert.strictEqual(adaptCount, 4); + assert.strictEqual( + adaptRenderCount, + 1, + "during adapt, render not triggered as the more menu dropdown is STILL the same" + ); + + // Reset to full width and dispatch window resize event + navbar.el.style.width = "100%"; + window.dispatchEvent(new Event("resize")); + await nextTick(); + assert.strictEqual(navbar.currentAppSections.length, 3, "still 3 app sub menus"); + assert.strictEqual( + navbar.currentAppSectionsExtra.length, + 0, + "all app sub menus are NO MORE inside the more menu" + ); + assert.strictEqual(adaptCount, 5); + assert.strictEqual( + adaptRenderCount, + 2, + "during adapt, render triggered as the more menu dropdown is NO MORE the same" + ); + + navbar.destroy(); } - - const newMenus = { - root: { id: "root", children: [1], name: "root", appID: "root" }, - 1: { id: 1, children: [11, 12, 13], name: "App1", appID: 1 }, - 11: { id: 11, children: [], name: "Section 1", appID: 1 }, - 12: { id: 12, children: [], name: "Section 2", appID: 1 }, - 13: { id: 13, children: [], name: "Section 3", appID: 1 }, - }; - baseConfig.serverData.menus = newMenus; - - // Force the parent width, to make this test independent of screen size - const target = getFixture(); - target.style.width = "600px"; - - const env = await makeTestEnv(baseConfig); - const navbar = await mount(MyNavbar, { env, target }); - assert.strictEqual(navbar.currentAppSections.length, 0, "0 app sub menus"); - assert.strictEqual(navbar.el.offsetWidth, 600); - assert.strictEqual(adaptCount, 1); - assert.strictEqual( - adaptRenderCount, 0, - "during adapt, render not triggered as the navbar has no app sub menus" - ); - - // Force minimal width and dispatch window resize event - navbar.el.style.width = "0%"; - window.dispatchEvent(new Event("resize")); - await nextTick(); - assert.strictEqual(navbar.el.offsetWidth, 0); - assert.strictEqual(adaptCount, 2); - assert.strictEqual( - adaptRenderCount, 0, - "during adapt, render not triggered as the navbar has no app sub menus" - ); - - // Set menu - env.services.menu.setCurrentMenu(1); - await nextTick(); - assert.strictEqual(navbar.currentAppSections.length, 3, "3 app sub menus"); - assert.strictEqual( - navbar.currentAppSectionsExtra.length, 3, - "all app sub menus are inside the more menu" - ); - assert.strictEqual(adaptCount, 3); - assert.strictEqual( - adaptRenderCount, 1, - "during adapt, render triggered as the navbar does not have enough space for app sub menus" - ); - - // Force 40% width and dispatch window resize event - navbar.el.style.width = "40%"; - window.dispatchEvent(new Event("resize")); - await nextTick(); - assert.strictEqual( - navbar.currentAppSectionsExtra.length, 3, - "all app sub menus are STILL inside the more menu" - ); - assert.strictEqual(adaptCount, 4); - assert.strictEqual( - adaptRenderCount, 1, - "during adapt, render not triggered as the more menu dropdown is STILL the same" - ); - - // Reset to full width and dispatch window resize event - navbar.el.style.width = "100%"; - window.dispatchEvent(new Event("resize")); - await nextTick(); - assert.strictEqual(navbar.currentAppSections.length, 3, "still 3 app sub menus"); - assert.strictEqual( - navbar.currentAppSectionsExtra.length, 0, - "all app sub menus are NO MORE inside the more menu" - ); - assert.strictEqual(adaptCount, 5); - assert.strictEqual( - adaptRenderCount, 2, - "during adapt, render triggered as the more menu dropdown is NO MORE the same" - ); - - navbar.destroy(); -}); +); QUnit.test("'more' menu sections properly updated on app change", async (assert) => { const newMenus = {