From 49aa4dcf30e437633a06735715544ba2fc3632e8 Mon Sep 17 00:00:00 2001 From: Romeo Fragomeli Date: Tue, 5 Sep 2023 09:25:13 +0000 Subject: [PATCH] [IMP] web: add target=download act_url action This commit adds `target=download`, as `target=self` adds some unwanted visual effect. In other words, the "block UI" is never unblocked when some actions are triggered. This is specific for "Download" actions as the download is correctly executed, but the page is never `unload`. e.g.: ```python action = { 'type': 'ir.actions.act_url', 'url': '/web_enterprise/partner/%d/vcard' % record.id, 'target': 'self', } ``` Note: We can't use "'target': 'new'" as it creates a bug in Mobile Apps. When The Mobile Apps create a new "Tab/Page", they do it in a new sandboxed browsing environment, so the user isn't logged in and the resource isn't accessible anymore. Task ID: 3435131 closes odoo/odoo#134436 X-original-commit: 08db3deb3336f0c1ff9fe2703ebeb8ea5b5aeb3d Related: odoo/documentation#5822 Signed-off-by: Aaron Bohy (aab) --- .../src/webclient/actions/action_service.js | 4 +++- .../webclient/actions/url_action_tests.js | 23 +++++++++++++++++-- addons/web/views/partner_view.xml | 2 +- odoo/addons/base/models/ir_actions.py | 2 +- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/webclient/actions/action_service.js b/addons/web/static/src/webclient/actions/action_service.js index 6024a0fb82a..3f6998703e5 100644 --- a/addons/web/static/src/webclient/actions/action_service.js +++ b/addons/web/static/src/webclient/actions/action_service.js @@ -879,7 +879,9 @@ function makeActionManager(env) { if (url && !(url.startsWith("http") || url.startsWith("/"))) { url = "/" + url; } - if (action.target === "self") { + if (action.target === "download") { + browser.location.assign(url); + } else if (action.target === "self") { let willUnload = false; const onUnload = () => { willUnload = true; diff --git a/addons/web/static/tests/webclient/actions/url_action_tests.js b/addons/web/static/tests/webclient/actions/url_action_tests.js index 10d085ef49b..e79149da88b 100644 --- a/addons/web/static/tests/webclient/actions/url_action_tests.js +++ b/addons/web/static/tests/webclient/actions/url_action_tests.js @@ -3,14 +3,16 @@ import { registry } from "@web/core/registry"; import { makeTestEnv } from "../../helpers/mock_env"; import { setupWebClientRegistries, doAction, getActionManagerServerData } from "./../helpers"; -import { patchWithCleanup } from "@web/../tests/helpers/utils"; +import { getFixture, patchWithCleanup } from "@web/../tests/helpers/utils"; import { browser } from "@web/core/browser/browser"; +let target; let serverData; const serviceRegistry = registry.category("services"); QUnit.module("ActionManager", (hooks) => { hooks.beforeEach(() => { + target = getFixture(); serverData = getActionManagerServerData(); }); @@ -66,7 +68,7 @@ QUnit.module("ActionManager", (hooks) => { await doAction(env, { type: "ir.actions.act_url" }, options); assert.verifySteps(["browser open", "onClose"]); }); - + QUnit.test("execute an 'ir.actions.act_url' action with url javascript:", async (assert) => { assert.expect(2); patchWithCleanup(browser.location, { @@ -83,4 +85,21 @@ QUnit.module("ActionManager", (hooks) => { }); assert.verifySteps(["/javascript:alert()"]); }); + + QUnit.test("execute an 'ir.actions.act_url' action with target 'download'", async (assert) => { + patchWithCleanup(browser.location, { + assign: (url) => { + assert.step(url); + }, + }); + setupWebClientRegistries(); + const env = await makeTestEnv({ serverData }); + await doAction(env, { + type: "ir.actions.act_url", + target: "download", + url: "/my/test/url", + }); + assert.containsNone(target, ".o_blockUI", "ui should not be blocked"); + assert.verifySteps(["/my/test/url"]); + }); }); diff --git a/addons/web/views/partner_view.xml b/addons/web/views/partner_view.xml index 314960f307e..5c15aca0e87 100644 --- a/addons/web/views/partner_view.xml +++ b/addons/web/views/partner_view.xml @@ -10,7 +10,7 @@ action = { 'type': 'ir.actions.act_url', 'url': '/web/partner/%d/vcard' % record.id, - 'target': 'self', + 'target': 'download', } diff --git a/odoo/addons/base/models/ir_actions.py b/odoo/addons/base/models/ir_actions.py index a6fe1307295..388b8fa5d42 100644 --- a/odoo/addons/base/models/ir_actions.py +++ b/odoo/addons/base/models/ir_actions.py @@ -392,7 +392,7 @@ class IrActionsActUrl(models.Model): type = fields.Char(default='ir.actions.act_url') url = fields.Text(string='Action URL', required=True) - target = fields.Selection([('new', 'New Window'), ('self', 'This Window')], + target = fields.Selection([('new', 'New Window'), ('self', 'This Window'), ('download', 'Download')], string='Action Target', default='new', required=True) def _get_readable_fields(self):