[FIX] web: m2o must only use the context of the field

From commit 2ecfed335d, 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 <field> 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 <ged@odoo.com>
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
FrancoisGe
2023-07-12 16:52:54 +02:00
parent 2de114a37f
commit 42e5e247bf
4 changed files with 17 additions and 9 deletions
@@ -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);
}
/**
@@ -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;
@@ -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,
@@ -4349,7 +4349,7 @@ QUnit.module("Fields", (hooks) => {
"partner,false,search": "<search></search>",
"turtle,false,list": `
<tree readonly="1">
<field name="product_id" widget="many2one"/>
<field name="product_id" widget="many2one" context="{'field': 'Yes'}"/>
</tree>`,
"product,false,search": "<search></search>",
"product,false,form": "<form></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",