From 42e5e247bfd9142ad5d69db00eec73c9a5aeccbf Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Wed, 5 Jul 2023 17:43:14 +0000 Subject: [PATCH] [FIX] web: m2o must only use the context of the field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From commit 2ecfed335d46, clicking on the arrow of a m2o opens the record in form view and passes it the context of the current view. After this commit, only the context defined on the is passed. Problem: An example of a problem, is the use of an incorrect active_id in the second view that is passed through the first form view to the second. Previously, the active_id of a form view was always the id of the record and not that of the previous view. This behaviour is debatable, but it leads to major changes. We therefore prefer to revert to the old behaviour and no longer pass the entire context in order to avoid this problem. How to reproduce: - Go to a form view with a m2o - Click on the arrow of the m2o Before this commit: The view context contains all the context from the first form view and the second. After this commit: The view context contains the context of the m2o field and the second view. closes odoo/odoo#127538 Taskid: 3394945 X-original-commit: a9bec1fec3ff08461732ef2717457524339eb716 Signed-off-by: Géry Debongnie Signed-off-by: Xavier Bol (xbo) --- .../components/task_with_hours/task_with_hours.js | 4 ++-- .../many2one_avatar_user_field.js | 4 ++-- .../src/views/fields/many2one/many2one_field.js | 13 +++++++++---- .../tests/views/fields/many2one_field_tests.js | 5 ++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/addons/hr_timesheet/static/src/components/task_with_hours/task_with_hours.js b/addons/hr_timesheet/static/src/components/task_with_hours/task_with_hours.js index 306eec71d59..5ad96dc7b96 100644 --- a/addons/hr_timesheet/static/src/components/task_with_hours/task_with_hours.js +++ b/addons/hr_timesheet/static/src/components/task_with_hours/task_with_hours.js @@ -6,8 +6,8 @@ import { Many2OneField, many2OneField } from "@web/views/fields/many2one/many2on class TaskWithHours extends Many2OneField { - canCreate(props = this.props) { - return Boolean(props.context.default_project_id); + canCreate() { + return Boolean(this.context.default_project_id); } /** diff --git a/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js b/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js index 3d9f5ab62f3..0a66779e86c 100644 --- a/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js +++ b/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js @@ -34,7 +34,7 @@ export class Many2OneAvatarUserField extends Many2OneAvatarField { static template = "mail.Many2OneAvatarUserField"; static props = { ...Many2OneAvatarField.props, - context: { type: Object, optional: true }, + context: { type: String, optional: true }, domain: { type: [Array, Function], optional: true }, withCommand: { type: Boolean, optional: true }, }; @@ -47,7 +47,7 @@ export const many2OneAvatarUserField = { additionalClasses: ["o_field_many2one_avatar"], extractProps(fieldInfo, dynamicInfo) { const props = many2OneAvatarField.extractProps(...arguments); - props.context = dynamicInfo.context; + props.context = fieldInfo.context; props.domain = dynamicInfo.domain; props.withCommand = fieldInfo.viewType === "form"; return props; diff --git a/addons/web/static/src/views/fields/many2one/many2one_field.js b/addons/web/static/src/views/fields/many2one/many2one_field.js index 20761709f23..d737d8a9464 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.js +++ b/addons/web/static/src/views/fields/many2one/many2one_field.js @@ -2,6 +2,7 @@ import { browser } from "@web/core/browser/browser"; import { isMobileOS } from "@web/core/browser/feature_detection"; +import { makeContext } from "@web/core/context"; import { Dialog } from "@web/core/dialog/dialog"; import { _lt } from "@web/core/l10n/translation"; import { evaluateExpr } from "@web/core/py_js/py"; @@ -53,7 +54,7 @@ export class Many2OneField extends Component { canWrite: { type: Boolean, optional: true }, canQuickCreate: { type: Boolean, optional: true }, canCreateEdit: { type: Boolean, optional: true }, - context: { type: Object, optional: true }, + context: { type: String, optional: true }, domain: { type: [Array, Function], optional: true }, nameCreateField: { type: String, optional: true }, searchLimit: { type: Number, optional: true }, @@ -161,7 +162,11 @@ export class Many2OneField extends Component { return this.props.canOpen && !!this.value && !this.state.isFloating; } get context() { - return this.props.context; + const { context, record } = this.props; + const evalContext = record.getEvalContext + ? record.getEvalContext(false) + : record.evalContext; + return makeContext([context], evalContext); } get classFromDecoration() { const evalContext = this.props.record.evalContext; @@ -334,7 +339,7 @@ export const many2OneField = { }, ], supportedTypes: ["many2one"], - extractProps({ attrs, decorations, options, string }, dynamicInfo) { + extractProps({ attrs, context, decorations, options, string }, dynamicInfo) { const canCreate = attrs.can_create && Boolean(JSON.parse(attrs.can_create)) && !options.no_create; return { @@ -344,7 +349,7 @@ export const many2OneField = { canWrite: attrs.can_write && Boolean(JSON.parse(attrs.can_write)), canQuickCreate: canCreate && !options.no_quick_create, canCreateEdit: canCreate && !options.no_create_edit, - context: dynamicInfo.context, + context: context, decorations, domain: dynamicInfo.domain, nameCreateField: options.create_name_field, diff --git a/addons/web/static/tests/views/fields/many2one_field_tests.js b/addons/web/static/tests/views/fields/many2one_field_tests.js index 51c77c60e08..c69e6fce3b8 100644 --- a/addons/web/static/tests/views/fields/many2one_field_tests.js +++ b/addons/web/static/tests/views/fields/many2one_field_tests.js @@ -4349,7 +4349,7 @@ QUnit.module("Fields", (hooks) => { "partner,false,search": "", "turtle,false,list": ` - + `, "product,false,search": "", "product,false,form": "
", @@ -4361,6 +4361,7 @@ QUnit.module("Fields", (hooks) => { res_id: 1, type: "ir.actions.act_window", views: [[false, "form"]], + context: { global: "No" }, }, }; const webClient = await createWebClient({ @@ -4369,6 +4370,8 @@ QUnit.module("Fields", (hooks) => { mockRPC: function (route, args) { if (args.method === "get_formview_action") { assert.step("get_formview_action"); + assert.strictEqual(args.kwargs.context.field, "Yes"); + assert.notOk("global" in args.kwargs.context); return { type: "ir.actions.act_window", res_model: "product",