[FIX] web: webclient: navbar: consistently adapt menu items
The use case happens in studio. have some overflowing app submenus in an app go into studio refresh with a simple F5. Before this commit, the navbar's overflowing buttons wouldn't put themselves inside the "more" dropdown This was because the studio client action also reacts to change in the menu service, so the technical flow was: - laodState (webClient) - setMenu (MENU-CHANGED on the bus), then because of it: - studio client action > render (1) - studio navbar > render (with adapt right after that render!) (2) - studio navbar > render (because of 1) which cancels the render in 2 without cancelling the promise, that is adapt is still called. To remedy this, the standard use of useEffect and useBus are is put into place. After this commit, the studio navbar has its overflowing menu items in the dropdown. The adapt algorithm now uses getBoundingClientRect to get the not rounded width of elements that should be adapted, otherwise, slight differences in browser's computation and rounding of offsetWidth may influence test results. closes odoo/odoo#80353 X-original-commit: 231902738287a897f50a1711f991bc55928b77d9 Related: odoo/enterprise#22498 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com> Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||
import { useEffect, useService, onDestroyed } from "@web/core/utils/hooks";
|
||||
import { useEffect, useService, onDestroyed, useBus } from "@web/core/utils/hooks";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { debounce } from "@web/core/utils/timing";
|
||||
import { ErrorHandler, NotUpdatable } from "@web/core/utils/components";
|
||||
@@ -11,6 +11,8 @@ const { Component, hooks } = owl;
|
||||
const { useExternalListener, useRef } = hooks;
|
||||
const systrayRegistry = registry.category("systray");
|
||||
|
||||
const getBoundingClientRect = Element.prototype.getBoundingClientRect;
|
||||
|
||||
export class MenuDropdown extends Dropdown {
|
||||
setup() {
|
||||
super.setup();
|
||||
@@ -55,21 +57,18 @@ export class NavBar extends Component {
|
||||
const debouncedAdapt = debounce(this.adapt.bind(this), 250);
|
||||
onDestroyed(() => debouncedAdapt.cancel());
|
||||
useExternalListener(window, "resize", debouncedAdapt);
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.adapt();
|
||||
const renderAndAdapt = async () => {
|
||||
await this.render();
|
||||
await this.adapt();
|
||||
let adaptCounter = 0;
|
||||
const renderAndAdapt = () => {
|
||||
adaptCounter++;
|
||||
this.render();
|
||||
};
|
||||
systrayRegistry.on("UPDATE", this, renderAndAdapt);
|
||||
this.env.bus.on("MENUS:APP-CHANGED", this, renderAndAdapt);
|
||||
}
|
||||
|
||||
willUnmount() {
|
||||
systrayRegistry.off("UPDATE", this);
|
||||
this.env.bus.off("MENUS:APP-CHANGED", this);
|
||||
useBus(systrayRegistry, "UPDATE", renderAndAdapt);
|
||||
useBus(this.env.bus, "MENUS:APP-CHANGED", renderAndAdapt);
|
||||
// We don't want to adapt every time we are patched
|
||||
// rather, we adapt only when menus or systrays have changed.
|
||||
useEffect(() => {this.adapt();}, () => [adaptCounter]);
|
||||
}
|
||||
|
||||
handleItemError(error, item) {
|
||||
@@ -138,8 +137,10 @@ export class NavBar extends Component {
|
||||
this.currentAppSectionsExtra = [];
|
||||
|
||||
// ------- Check overflowing sections -------
|
||||
const sectionsAvailableWidth = sectionsMenu.offsetWidth;
|
||||
const sectionsTotalWidth = sections.reduce((sum, s) => sum + s.offsetWidth, 0);
|
||||
// use getBoundingClientRect to get unrounded values for width in order to avoid rounding problem
|
||||
// with offsetWidth.
|
||||
const sectionsAvailableWidth = getBoundingClientRect.call(sectionsMenu).width;
|
||||
const sectionsTotalWidth = sections.reduce((sum, s) => sum + getBoundingClientRect.call(s).width, 0);
|
||||
if (sectionsAvailableWidth < sectionsTotalWidth) {
|
||||
// Sections are overflowing
|
||||
// Initial width is harcoded to the width the more menu dropdown will take
|
||||
|
||||
Reference in New Issue
Block a user