diff --git a/README.md b/README.md index f4c20b338046..bf99b1b8ebc2 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ addon | version | maintainers | summary [web_help](web_help/) | 18.0.1.0.0 | | Help Framework [web_ir_actions_act_multi](web_ir_actions_act_multi/) | 18.0.1.0.0 | | Enables triggering of more than one action on ActionManager [web_ir_actions_act_window_message](web_ir_actions_act_window_message/) | 18.0.1.0.1 | | Show a message box to users +[web_loading_block_ui](web_loading_block_ui/) | 18.0.1.0.0 | | Block the screen with a centered loading overlay while requests are pending [web_m2x_options](web_m2x_options/) | 18.0.1.0.3 | | web_m2x_options [web_m2x_options_manager](web_m2x_options_manager/) | 18.0.1.0.0 | | Adds an interface to manage the "Create" and "Create and Edit" options for specific models and fields. [web_no_bubble](web_no_bubble/) | 18.0.1.0.0 | | Remove the bubbles from the web interface @@ -65,7 +66,7 @@ addon | version | maintainers | summary [web_systray_button_init_action](web_systray_button_init_action/) | 18.0.1.0.2 | | Add a button to go to the user init action. [web_theme_classic](web_theme_classic/) | 18.0.1.2.1 | legalsylvain | Contrasted style on fields to improve the UI. [web_time_range_menu_custom](web_time_range_menu_custom/) | 18.0.1.0.0 | | Web Time Range Menu Custom -[web_timeline](web_timeline/) | 18.0.1.0.3 | | Interactive visualization chart to show events in time +[web_timeline](web_timeline/) | 18.0.1.0.4 | | Interactive visualization chart to show events in time [web_toggle_chatter](web_toggle_chatter/) | 18.0.1.0.0 | | Toggle chatter in backend form views [web_touchscreen](web_touchscreen/) | 18.0.1.0.0 | yajo rafaelbn | UX improvements for touch screens [web_tree_column_keyboard_resize](web_tree_column_keyboard_resize/) | 18.0.1.0.0 | | Allow resizing tree view columns using keyboard shortcuts diff --git a/setup/_metapackage/pyproject.toml b/setup/_metapackage/pyproject.toml index 59d5c504385b..437ecff88179 100644 --- a/setup/_metapackage/pyproject.toml +++ b/setup/_metapackage/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "odoo-addons-oca-web" -version = "18.0.20260914.0" +version = "18.0.20261005.0" dependencies = [ "odoo-addon-web_action_conditionable==18.0.*", "odoo-addon-web_calendar_slot_duration==18.0.*", @@ -23,6 +23,7 @@ dependencies = [ "odoo-addon-web_help==18.0.*", "odoo-addon-web_ir_actions_act_multi==18.0.*", "odoo-addon-web_ir_actions_act_window_message==18.0.*", + "odoo-addon-web_loading_block_ui==18.0.*", "odoo-addon-web_m2x_options==18.0.*", "odoo-addon-web_m2x_options_manager==18.0.*", "odoo-addon-web_no_bubble==18.0.*", diff --git a/web_copy_confirm/i18n/es.po b/web_copy_confirm/i18n/es.po new file mode 100644 index 000000000000..266c9f6d4305 --- /dev/null +++ b/web_copy_confirm/i18n/es.po @@ -0,0 +1,33 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_copy_confirm +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: web_copy_confirm +#. odoo-javascript +#: code:addons/web_copy_confirm/static/src/js/web_copy_confirm.esm.js:0 +msgid "Are you sure that you would like to copy this record?" +msgstr "" + +#. module: web_copy_confirm +#. odoo-javascript +#: code:addons/web_copy_confirm/static/src/js/web_copy_confirm.esm.js:0 +msgid "Are you sure that you would like to duplicate the selected records?" +msgstr "" + +#. module: web_copy_confirm +#. odoo-javascript +#: code:addons/web_copy_confirm/static/src/js/web_copy_confirm.esm.js:0 +msgid "Duplicate" +msgstr "" diff --git a/web_loading_block_ui/README.rst b/web_loading_block_ui/README.rst new file mode 100644 index 000000000000..82bfeb775963 --- /dev/null +++ b/web_loading_block_ui/README.rst @@ -0,0 +1,110 @@ +==================== +Web Loading Block UI +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:68b714c85edf983690119636c79f95be1709ed62f4291605430ee21fff7781b2 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/18.0/web_loading_block_ui + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_loading_block_ui + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Since Odoo 17.0 the loading indicator is a small badge in the bottom +right corner of the screen and the user interface keeps accepting input +while a request is still running. Odoo 16.0 and earlier blocked the +whole screen with a blurred overlay and a centered spinner when a +request took longer than a few seconds. + +This module restores that behaviour on top of the current loading +indicator: when a request stays pending for longer than a configurable +delay, the screen is blocked with the standard Odoo overlay (blurred +background and centered "Loading..." spinner) until every pending +request has been answered. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +The delay before the screen is blocked is stored in the system parameter +``web_loading_block_ui.delay``, expressed in milliseconds and counted +from the moment the first request starts. The default value is ``3000``, +which matches the behaviour of Odoo 16.0 and earlier. + +To change it, enable developer mode and go to *Settings > Technical > +System Parameters*. Set the value to ``0`` to block the screen as soon +as a request starts. Users need to reload the page for a new value to be +applied. + +Usage +===== + +Trigger any action that takes longer than the configured delay, for +example opening a heavy report or saving a large record. The screen is +blurred and a centered "Loading..." spinner is shown until the action +finishes. Requests marked as silent by Odoo (background polling, +notifications) never block the screen. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ForgeFlow + +Contributors +------------ + +- `ForgeFlow `__: + + - David Jiménez + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_loading_block_ui/__init__.py b/web_loading_block_ui/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/web_loading_block_ui/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/web_loading_block_ui/__manifest__.py b/web_loading_block_ui/__manifest__.py new file mode 100644 index 000000000000..13700e41ac31 --- /dev/null +++ b/web_loading_block_ui/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2026 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +{ + "name": "Web Loading Block UI", + "summary": "Block the screen with a centered loading overlay " + "while requests are pending", + "version": "18.0.1.0.0", + "category": "Web", + "website": "https://github.com/OCA/web", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "license": "LGPL-3", + "depends": ["web"], + "data": [ + "data/ir_config_parameter.xml", + ], + "assets": { + "web.assets_backend": [ + "web_loading_block_ui/static/src/loading_indicator.esm.js", + ], + "web.assets_unit_tests": [ + "web_loading_block_ui/static/tests/**/*", + ], + }, + "installable": True, +} diff --git a/web_loading_block_ui/data/ir_config_parameter.xml b/web_loading_block_ui/data/ir_config_parameter.xml new file mode 100644 index 000000000000..7ff7903b8605 --- /dev/null +++ b/web_loading_block_ui/data/ir_config_parameter.xml @@ -0,0 +1,9 @@ + + + + + web_loading_block_ui.delay + 3000 + + diff --git a/web_loading_block_ui/i18n/it.po b/web_loading_block_ui/i18n/it.po new file mode 100644 index 000000000000..1cccd7791011 --- /dev/null +++ b/web_loading_block_ui/i18n/it.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_loading_block_ui +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-10-07 08:46+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.15.2\n" + +#. module: web_loading_block_ui +#: model:ir.model,name:web_loading_block_ui.model_ir_http +msgid "HTTP Routing" +msgstr "Instradamento HTTP" diff --git a/web_loading_block_ui/i18n/web_loading_block_ui.pot b/web_loading_block_ui/i18n/web_loading_block_ui.pot new file mode 100644 index 000000000000..461b45f1b321 --- /dev/null +++ b/web_loading_block_ui/i18n/web_loading_block_ui.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_loading_block_ui +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_loading_block_ui +#: model:ir.model,name:web_loading_block_ui.model_ir_http +msgid "HTTP Routing" +msgstr "" diff --git a/web_loading_block_ui/models/__init__.py b/web_loading_block_ui/models/__init__.py new file mode 100644 index 000000000000..9a5eb71871d4 --- /dev/null +++ b/web_loading_block_ui/models/__init__.py @@ -0,0 +1 @@ +from . import ir_http diff --git a/web_loading_block_ui/models/ir_http.py b/web_loading_block_ui/models/ir_http.py new file mode 100644 index 000000000000..c6359d79f896 --- /dev/null +++ b/web_loading_block_ui/models/ir_http.py @@ -0,0 +1,18 @@ +# Copyright 2026 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +from odoo import models + +DEFAULT_BLOCK_DELAY = "3000" + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + def session_info(self): + session_info = super().session_info() + session_info["web_loading_block_ui_delay"] = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("web_loading_block_ui.delay", DEFAULT_BLOCK_DELAY) + ) + return session_info diff --git a/web_loading_block_ui/pyproject.toml b/web_loading_block_ui/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/web_loading_block_ui/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_loading_block_ui/readme/CONFIGURE.md b/web_loading_block_ui/readme/CONFIGURE.md new file mode 100644 index 000000000000..0baa51eec819 --- /dev/null +++ b/web_loading_block_ui/readme/CONFIGURE.md @@ -0,0 +1,8 @@ +The delay before the screen is blocked is stored in the system parameter +`web_loading_block_ui.delay`, expressed in milliseconds and counted from the +moment the first request starts. The default value is `3000`, which matches +the behaviour of Odoo 16.0 and earlier. + +To change it, enable developer mode and go to *Settings > Technical > System +Parameters*. Set the value to `0` to block the screen as soon as a request +starts. Users need to reload the page for a new value to be applied. diff --git a/web_loading_block_ui/readme/CONTRIBUTORS.md b/web_loading_block_ui/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..a22f651a4a55 --- /dev/null +++ b/web_loading_block_ui/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [ForgeFlow](https://www.forgeflow.com): + - David Jiménez \<\> diff --git a/web_loading_block_ui/readme/DESCRIPTION.md b/web_loading_block_ui/readme/DESCRIPTION.md new file mode 100644 index 000000000000..349dc5db228e --- /dev/null +++ b/web_loading_block_ui/readme/DESCRIPTION.md @@ -0,0 +1,10 @@ +Since Odoo 17.0 the loading indicator is a small badge in the bottom right +corner of the screen and the user interface keeps accepting input while a +request is still running. Odoo 16.0 and earlier blocked the whole screen with +a blurred overlay and a centered spinner when a request took longer than a few +seconds. + +This module restores that behaviour on top of the current loading indicator: +when a request stays pending for longer than a configurable delay, the screen +is blocked with the standard Odoo overlay (blurred background and centered +"Loading..." spinner) until every pending request has been answered. diff --git a/web_loading_block_ui/readme/USAGE.md b/web_loading_block_ui/readme/USAGE.md new file mode 100644 index 000000000000..b675cb4dac67 --- /dev/null +++ b/web_loading_block_ui/readme/USAGE.md @@ -0,0 +1,5 @@ +Trigger any action that takes longer than the configured delay, for example +opening a heavy report or saving a large record. The screen is blurred and a +centered "Loading..." spinner is shown until the action finishes. Requests +marked as silent by Odoo (background polling, notifications) never block the +screen. diff --git a/web_loading_block_ui/static/description/icon.png b/web_loading_block_ui/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/web_loading_block_ui/static/description/icon.png differ diff --git a/web_loading_block_ui/static/description/index.html b/web_loading_block_ui/static/description/index.html new file mode 100644 index 000000000000..5cd893991343 --- /dev/null +++ b/web_loading_block_ui/static/description/index.html @@ -0,0 +1,456 @@ + + + + + +Web Loading Block UI + + + +
+

Web Loading Block UI

+ + +

Beta License: LGPL-3 OCA/web Translate me on Weblate Try me on Runboat

+

Since Odoo 17.0 the loading indicator is a small badge in the bottom +right corner of the screen and the user interface keeps accepting input +while a request is still running. Odoo 16.0 and earlier blocked the +whole screen with a blurred overlay and a centered spinner when a +request took longer than a few seconds.

+

This module restores that behaviour on top of the current loading +indicator: when a request stays pending for longer than a configurable +delay, the screen is blocked with the standard Odoo overlay (blurred +background and centered “Loading…” spinner) until every pending +request has been answered.

+

Table of contents

+ +
+

Configuration

+

The delay before the screen is blocked is stored in the system parameter +web_loading_block_ui.delay, expressed in milliseconds and counted +from the moment the first request starts. The default value is 3000, +which matches the behaviour of Odoo 16.0 and earlier.

+

To change it, enable developer mode and go to Settings > Technical > +System Parameters. Set the value to 0 to block the screen as soon +as a request starts. Users need to reload the page for a new value to be +applied.

+
+
+

Usage

+

Trigger any action that takes longer than the configured delay, for +example opening a heavy report or saving a large record. The screen is +blurred and a centered “Loading…” spinner is shown until the action +finishes. Requests marked as silent by Odoo (background polling, +notifications) never block the screen.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_loading_block_ui/static/src/loading_indicator.esm.js b/web_loading_block_ui/static/src/loading_indicator.esm.js new file mode 100644 index 000000000000..95b776d05c2b --- /dev/null +++ b/web_loading_block_ui/static/src/loading_indicator.esm.js @@ -0,0 +1,58 @@ +/* Copyright 2026 ForgeFlow S.L. (https://www.forgeflow.com) + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). */ +import {LoadingIndicator} from "@web/webclient/loading_indicator/loading_indicator"; +import {browser} from "@web/core/browser/browser"; +import {onWillDestroy} from "@odoo/owl"; +import {patch} from "@web/core/utils/patch"; +import {session} from "@web/session"; +import {useService} from "@web/core/utils/hooks"; + +export const DEFAULT_BLOCK_DELAY = 3000; + +/** + * Restore the pre-17.0 behaviour of the loading indicator: when a request + * stays pending for longer than the configured delay, the whole UI is blocked + * with the standard blurred overlay and centered spinner until every pending + * request has been answered. + */ +patch(LoadingIndicator.prototype, { + setup() { + super.setup(); + this.uiService = useService("ui"); + this.blockUITimer = null; + this.shouldUnblock = false; + onWillDestroy(() => this.unblockUI()); + }, + get blockUIDelay() { + const delay = parseInt(session.web_loading_block_ui_delay, 10); + return Number.isNaN(delay) ? DEFAULT_BLOCK_DELAY : Math.max(delay, 0); + }, + requestCall({detail}) { + const wasIdle = this.state.count === 0; + super.requestCall(...arguments); + if (detail.settings.silent || !wasIdle) { + return; + } + browser.clearTimeout(this.blockUITimer); + this.blockUITimer = browser.setTimeout(() => { + if (this.state.count) { + this.shouldUnblock = true; + this.uiService.block(); + } + }, this.blockUIDelay); + }, + responseCall() { + super.responseCall(...arguments); + if (this.state.count === 0) { + this.unblockUI(); + } + }, + unblockUI() { + browser.clearTimeout(this.blockUITimer); + this.blockUITimer = null; + if (this.shouldUnblock) { + this.uiService.unblock(); + this.shouldUnblock = false; + } + }, +}); diff --git a/web_loading_block_ui/static/tests/web_loading_block_ui.test.js b/web_loading_block_ui/static/tests/web_loading_block_ui.test.js new file mode 100644 index 000000000000..3ce3dc335932 --- /dev/null +++ b/web_loading_block_ui/static/tests/web_loading_block_ui.test.js @@ -0,0 +1,105 @@ +/* Copyright 2026 ForgeFlow S.L. (https://www.forgeflow.com) + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). */ +import {advanceTime, animationFrame} from "@odoo/hoot-mock"; +import {beforeEach, describe, expect, test} from "@odoo/hoot"; +import { + getService, + mountWithCleanup, + patchWithCleanup, +} from "@web/../tests/web_test_helpers"; +import {LoadingIndicator} from "@web/webclient/loading_indicator/loading_indicator"; +import {rpcBus} from "@web/core/network/rpc"; +import {session} from "@web/session"; +import {config as transitionConfig} from "@web/core/transition"; + +describe.current.tags("desktop"); + +const BLOCK_DELAY = 1000; + +const payload = (id, settings = {}) => ({ + data: {id, params: {model: "", method: ""}}, + settings, +}); + +async function mountLoadingIndicator() { + await mountWithCleanup(LoadingIndicator, {noMainContainer: true}); + const ui = getService("ui"); + ui.bus.addEventListener("BLOCK", () => expect.step("block")); + ui.bus.addEventListener("UNBLOCK", () => expect.step("unblock")); + return ui; +} + +describe("WebLoadingBlockUI", () => { + beforeEach(() => { + patchWithCleanup(transitionConfig, {disabled: true}); + patchWithCleanup(session, {web_loading_block_ui_delay: String(BLOCK_DELAY)}); + }); + + test("blocks the UI when a request outlives the configured delay", async () => { + const ui = await mountLoadingIndicator(); + rpcBus.trigger("RPC:REQUEST", payload(1)); + await advanceTime(BLOCK_DELAY - 1); + expect.verifySteps([]); + expect(ui.isBlocked).toBe(false); + await advanceTime(1); + await animationFrame(); + expect.verifySteps(["block"]); + expect(ui.isBlocked).toBe(true); + rpcBus.trigger("RPC:RESPONSE", payload(1)); + await animationFrame(); + expect.verifySteps(["unblock"]); + expect(ui.isBlocked).toBe(false); + expect(".o_loading_indicator").toHaveCount(0); + }); + + test("does not block the UI when the request finishes in time", async () => { + const ui = await mountLoadingIndicator(); + rpcBus.trigger("RPC:REQUEST", payload(1)); + await advanceTime(BLOCK_DELAY / 2); + rpcBus.trigger("RPC:RESPONSE", payload(1)); + await advanceTime(BLOCK_DELAY); + expect.verifySteps([]); + expect(ui.isBlocked).toBe(false); + }); + + test("stays blocked until the last pending request is answered", async () => { + const ui = await mountLoadingIndicator(); + rpcBus.trigger("RPC:REQUEST", payload(1)); + rpcBus.trigger("RPC:REQUEST", payload(2)); + await advanceTime(BLOCK_DELAY); + expect.verifySteps(["block"]); + rpcBus.trigger("RPC:RESPONSE", payload(1)); + await animationFrame(); + expect.verifySteps([]); + expect(ui.isBlocked).toBe(true); + rpcBus.trigger("RPC:RESPONSE", payload(2)); + await animationFrame(); + expect.verifySteps(["unblock"]); + expect(ui.isBlocked).toBe(false); + }); + + test("ignores silent requests", async () => { + const ui = await mountLoadingIndicator(); + rpcBus.trigger("RPC:REQUEST", payload(1, {silent: true})); + await advanceTime(BLOCK_DELAY * 2); + expect.verifySteps([]); + expect(ui.isBlocked).toBe(false); + rpcBus.trigger("RPC:RESPONSE", payload(1, {silent: true})); + await animationFrame(); + expect.verifySteps([]); + }); + + test("falls back to the default delay on an invalid parameter", async () => { + patchWithCleanup(session, {web_loading_block_ui_delay: "not-a-number"}); + const ui = await mountLoadingIndicator(); + rpcBus.trigger("RPC:REQUEST", payload(1)); + await advanceTime(BLOCK_DELAY); + expect.verifySteps([]); + await advanceTime(3000 - BLOCK_DELAY); + expect.verifySteps(["block"]); + expect(ui.isBlocked).toBe(true); + rpcBus.trigger("RPC:RESPONSE", payload(1)); + await animationFrame(); + expect.verifySteps(["unblock"]); + }); +}); diff --git a/web_loading_block_ui/tests/__init__.py b/web_loading_block_ui/tests/__init__.py new file mode 100644 index 000000000000..08db6d3496b4 --- /dev/null +++ b/web_loading_block_ui/tests/__init__.py @@ -0,0 +1 @@ +from . import test_web_loading_block_ui diff --git a/web_loading_block_ui/tests/test_web_loading_block_ui.py b/web_loading_block_ui/tests/test_web_loading_block_ui.py new file mode 100644 index 000000000000..c9277122c3cc --- /dev/null +++ b/web_loading_block_ui/tests/test_web_loading_block_ui.py @@ -0,0 +1,37 @@ +# Copyright 2026 ForgeFlow S.L. (https://www.forgeflow.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +import json + +from odoo.tests.common import HttpCase, tagged + + +@tagged("post_install", "-at_install") +class TestWebLoadingBlockUI(HttpCase): + def _get_session_info(self): + response = self.url_open( + "/web/session/get_session_info", + data=json.dumps({"jsonrpc": "2.0", "method": "call", "params": {}}), + headers={"Content-Type": "application/json"}, + ) + return response.json()["result"] + + def test_session_info_default_delay(self): + self.authenticate("admin", "admin") + self.assertEqual(self._get_session_info()["web_loading_block_ui_delay"], "3000") + + def test_session_info_custom_delay(self): + self.env["ir.config_parameter"].sudo().set_param( + "web_loading_block_ui.delay", "0" + ) + self.authenticate("admin", "admin") + self.assertEqual(self._get_session_info()["web_loading_block_ui_delay"], "0") + + def test_js(self): + self.browser_js( + "/web/tests?headless&loglevel=2&preset=desktop&filter=WebLoadingBlockUI", + "", + "", + login="admin", + success_signal="[HOOT] Test suite succeeded", + error_checker=lambda x: "[HOOT]" not in x, + ) diff --git a/web_timeline/README.rst b/web_timeline/README.rst index 3a24e9d781cd..c857f41fe001 100644 --- a/web_timeline/README.rst +++ b/web_timeline/README.rst @@ -11,7 +11,7 @@ Web timeline !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8633bbe9e07663ef50a7093c48c70557768324805e053637d2794ba7fb2fc7f1 + !! source digest: sha256:5874e622bf12886226567685f82ea5505266ff2acce2a3c8a1574b51ff497720 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png diff --git a/web_timeline/__manifest__.py b/web_timeline/__manifest__.py index 7b454771ed73..58c4ceb84b7c 100644 --- a/web_timeline/__manifest__.py +++ b/web_timeline/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Web timeline", "summary": "Interactive visualization chart to show events in time", - "version": "18.0.1.0.3", + "version": "18.0.1.0.4", "development_status": "Production/Stable", "author": "ACSONE SA/NV, " "Tecnativa, " diff --git a/web_timeline/static/description/index.html b/web_timeline/static/description/index.html index 26b73f9a92a7..0f1005c1d8fb 100644 --- a/web_timeline/static/description/index.html +++ b/web_timeline/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Web timeline