Daily updates from Odoo
Tuesday, August 18, 2026
2 changes
Code cleanup and technical improvements
The Point of Sale enterprise code was updated to use the newer supported framework behavior, replacing a deprecated internal mechanism. This keeps the module aligned with the latest platform standards and reduces future maintenance risk without introducing intended user-facing changes.
Original PR description
Replaced `useLayoutEffect` in `useDelayedValueChange` with native OWL3 `useEffect` because `useLayoutEffect` is deprecated in OWL3. The hook has no DOM/ref access — it arms a `setTimeout` to snapshot a reactive value after a delay. This is a pure side-effect-on-dep-change, making native `useEffect` the correct fit. A `void getCurrentValue()` call at the top of the effect restores the tracking the old dependency array provided, ensuring the timer resets whenever the tracked value changes. When commenting out the useLayoutEffect there was no error, the code we refactored had NO TEST coverage. The only build failure when commented was a lint error (unused-var from the comment pattern) — no functional tests failed. see runbot build with useLayoutEffect commented out: https://runbot.odoo.com/runbot/batch/2622063/build/116410184
This change updates several Enterprise screens to use newer internal lifecycle hooks while keeping the same visible behavior. It reduces reliance on compatibility code, making future maintenance easier without changing how users interact with reports, data cleaning, marketing automation, planning, navigation, or maps.
Original PR description
Enterprise half of odoo/odoo#282760 — same mechanical change, same reasoning. 7 call-sites called the owl2-compat `useLayoutEffect` **with no dependency array**, which makes it an alias for "run on…
Enterprise half of odoo/odoo#282760 — same mechanical change, same reasoning. 7 call-sites called the owl2-compat `useLayoutEffect` **with no dependency array**, which makes it an alias for "run on mount, re-run on every patch". They are translated to `onMounted` + `onPatched`. | site | effect | | --- | --- | | `account_reports/account_return_check_kanban_controller.js` | restore the renderer scroll position | | `data_cleaning/data_cleaning_list_view.js` | toggle control-panel buttons from the selection | | `data_cleaning/data_merge_list_view.js` | idem | | `marketing_automation/marketing_automation_one2many.js` | `applyTabPanelVisibility()` | | `planning/planning_gantt_renderer.js` | add `o_planning_gantt` on the grid | | `web_enterprise/navbar.js` | `_updateMenuAppsIcon()` | | `web_map/map_renderer.js` | `updateMap()` + deferred marker popover | ### Why this is behaviour-preserving Called without a dependency array, the compat `useLayoutEffect` defaults `computeDependencies` to `() => [NaN]`. `NaN !== NaN`, so the diff in its `onPatched` always succeeds and the effect already re-ran on **every** patch. `onMounted` + `onPatched` is therefore an exact translation. Two incidental parts of the shim fall away, both no-ops here: `onWillRender(() => computeDependencies())` reads nothing when there is no dependency array, and `onWillUnmount(() => cleanup && cleanup())` never fires because none of these 7 effects return a cleanup function. Note this argument is specific to the no-dependency-array sites and does *not* generalise to `useLayoutEffect` calls that pass real dependencies. ### One judgement call `account_return_check_kanban_controller` keeps `onPatched`. Its `rendererScrollPositions = null` latch reads like a run-once guard, but it sits inside `if (renderer)`: when the scroll container is not in the DOM yet at mount, the latch stays set and a later patch retries the restore. Keeping both hooks preserves that. ### Conflicts with `web_map/map_renderer.js` is also touched by odoo/enterprise#127921, which converts the *empty*-dependency-array site (`() => []`) in the same `setup()` and deliberately leaves this one alone. The two changes are disjoint but adjacent, so whichever lands second needs a trivial rebase — and once both are in, `useLayoutEffect` is no longer used in that file and its import should go. ### Not in this PR - The no-dependency-array sites whose effect **does** return a cleanup function need the full `onMounted`/`onPatched`/`onWillUnmount` triple and are handled separately (`sale_commission` by the `useChart` hook in odoo/enterprise#128100). - `spreadsheet_edition` is owned by another team and is left alone. - `web_gantt/static/tests/gantt_view_other.test.js` has one more, kept out of a production-code PR. ### Testing Static only: every remaining `useLayoutEffect` call in the tree was re-parsed with balanced-paren argument splitting to confirm no no-dependency-array site is left outside the exclusions above, and every touched file was checked for a missing or newly-unused `useLayoutEffect`/`onMounted`/`onPatched` import. No behaviour change is intended, so no test was added or updated. Part of the `useLayoutEffect` -> OWL3 migration.