diff --git a/addons/web/static/src/core/dialog/dialog_container.js b/addons/web/static/src/core/dialog/dialog_container.js index 564051f1487..daf0f96cc99 100644 --- a/addons/web/static/src/core/dialog/dialog_container.js +++ b/addons/web/static/src/core/dialog/dialog_container.js @@ -7,6 +7,9 @@ class ErrorHandler extends Component { this.props.callback(); throw error; } + shouldUpdate() { + return false; + } } ErrorHandler.template = tags.xml``; diff --git a/addons/web/static/src/core/notifications/notification.js b/addons/web/static/src/core/notifications/notification.js index 8da5dac114f..64cc6919e7c 100644 --- a/addons/web/static/src/core/notifications/notification.js +++ b/addons/web/static/src/core/notifications/notification.js @@ -9,6 +9,10 @@ export class Notification extends Component { } } + shouldUpdate() { + return false; + } + get className() { let className; switch (this.props.type) { diff --git a/addons/web/static/src/core/popover/popover_container.js b/addons/web/static/src/core/popover/popover_container.js index 2cfc2389bac..92a0ae68bc6 100644 --- a/addons/web/static/src/core/popover/popover_container.js +++ b/addons/web/static/src/core/popover/popover_container.js @@ -19,6 +19,11 @@ class PopoverController extends Component { willUnmount() { this.targetObserver.disconnect(); } + + shouldUpdate() { + return false; + } + get popoverProps() { return { target: this.target, diff --git a/addons/web/static/src/core/utils/components.js b/addons/web/static/src/core/utils/components.js new file mode 100644 index 00000000000..eb86323c1cf --- /dev/null +++ b/addons/web/static/src/core/utils/components.js @@ -0,0 +1,15 @@ +/** @odoo-module **/ + +const { Component, tags } = owl; + +export function makeNonUpdatableComponent(Comp) { + class NoUpdate extends Component { + shouldUpdate() { + return false; + } + } + NoUpdate.template = tags.xml``; + NoUpdate.components = { Comp }; + + return NoUpdate; +} diff --git a/addons/web/static/src/webclient/webclient.js b/addons/web/static/src/webclient/webclient.js index 038d78b846e..5a43cf9ff33 100644 --- a/addons/web/static/src/webclient/webclient.js +++ b/addons/web/static/src/webclient/webclient.js @@ -6,6 +6,7 @@ import { useBus } from "../core/bus_hook"; import { ActionContainer } from "./actions/action_container"; import { NavBar } from "./navbar/navbar"; import { useEffect } from "@web/core/effect_hook"; +import { makeNonUpdatableComponent } from "../core/utils/components"; const { Component, hooks } = owl; const { useExternalListener } = hooks; @@ -19,7 +20,11 @@ export class WebClient extends Component { this.router = useService("router"); this.user = useService("user"); useService("legacy_service_provider"); - this.Components = mainComponentRegistry.getEntries(); + this.Components = mainComponentRegistry.getEntries().map(([name, elem]) => { + const { Component, props } = elem; + const NonUpdatableComp = makeNonUpdatableComponent(Component); + return [name, { Component: NonUpdatableComp, props }]; + }); this.title.setParts({ zopenerp: "Odoo" }); // zopenerp is easy to grep useBus(this.env.bus, "ROUTE_CHANGE", this.loadRouterState); useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", (mode) => { diff --git a/addons/web/static/tests/core/utils/component_tests.js b/addons/web/static/tests/core/utils/component_tests.js new file mode 100644 index 00000000000..0c90101c44b --- /dev/null +++ b/addons/web/static/tests/core/utils/component_tests.js @@ -0,0 +1,34 @@ +/** @odoo-module **/ + +import { makeNonUpdatableComponent } from "@web/core/utils/components"; +import { makeTestEnv } from "../../helpers/mock_env"; +import { getFixture } from "../../helpers/utils"; + +const { Component, mount } = owl; + +QUnit.module("utils", () => { + QUnit.module("components"); + + QUnit.test("makeNonUpdatableComponent", async function (assert) { + class Child extends Component { + mounted() { + assert.step("mounted"); + } + willUpdateProps() { + assert.step("willupdateprops"); + } + } + Child.template = owl.tags.xml`
hey
`; + class Parent extends Component {} + Parent.template = owl.tags.xml`
`; + Parent.components = { Child1: Child, Child2: makeNonUpdatableComponent(Child) }; + + const target = getFixture(); + const parent = await mount(Parent, { env: makeTestEnv(), target }); + assert.verifySteps(["mounted", "mounted"]); + + await parent.render(); + assert.verifySteps(["willupdateprops"]); + parent.destroy(); + }); +});