From 91111f33ef59df7550ee8b2f987fae528a307e0e Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Thu, 27 Apr 2023 11:42:01 +0000 Subject: [PATCH] [REF] web: dynamicInfo domain becomes a function In commit 2ecfed335d469459b50df5e1973d72cf2a47afcf, we made the decision to pass the domain to the field during extracProps with a getter in dynamicInfo. This strategy causes the domain to be evaluated for all fields using it in their extractProps. Very often we want to evaluate the domain on an event, for example when a m2o is clicked on. The permanent evaluation when using the widget therefore implies an unnecessary computational cost for the evaluation and prevents the use of field.domain as a default value, as it may be present in readonly views which never need the domain to be evaluated. We will therefore convert the getter domain into a function that can be called when we need the domain to be evaluated. This allows us to avoid unnecessary evaluations and we can use field.domain as the default value in the dynamic.domain. closes odoo/odoo#120061 Signed-off-by: Aaron Bohy (aab) --- .../static/src/web/fields/assign_user_command_hook.js | 4 +++- .../many2one_avatar_user_field.js | 7 ++++--- addons/web/static/src/views/fields/field.js | 11 ++++++----- .../fields/many2many_tags/many2many_tags_field.js | 6 ++++-- .../src/views/fields/many2one/many2one_field.js | 5 +++-- .../static/src/views/fields/x2many/x2many_field.js | 5 +++-- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/addons/mail/static/src/web/fields/assign_user_command_hook.js b/addons/mail/static/src/web/fields/assign_user_command_hook.js index 793efd7428f..eddc5213607 100644 --- a/addons/mail/static/src/web/fields/assign_user_command_hook.js +++ b/addons/mail/static/src/web/fields/assign_user_command_hook.js @@ -58,7 +58,9 @@ export function useAssignUserCommand() { const provide = async (env, options) => { const value = options.searchValue.trim(); let domain = - component.props.domain || component.props.record.getFieldDomain(component.props.name); + typeof component.props.domain === "function" + ? component.props.domain() + : component.props.domain; const context = component.props.context; if (type === "many2many") { const selectedUserIds = getCurrentIds(); diff --git a/addons/mail/static/src/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js b/addons/mail/static/src/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js index d79663e3766..b17aa317de4 100644 --- a/addons/mail/static/src/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js +++ b/addons/mail/static/src/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js @@ -22,9 +22,10 @@ const userChatter = { }, onClickAvatar() { - const id = this.props.record.data[this.props.name][0] ?? false - if (id !== false) + const id = this.props.record.data[this.props.name][0] ?? false; + if (id !== false) { this.openChat(id); + } }, }; @@ -33,7 +34,7 @@ export class Many2OneAvatarUserField extends Many2OneAvatarField { static props = { ...Many2OneAvatarField.props, context: { type: Object, optional: true }, - domain: { type: Array, optional: true }, + domain: { type: [Array, Function], optional: true }, withCommand: { type: Boolean, optional: true }, }; } diff --git a/addons/web/static/src/views/fields/field.js b/addons/web/static/src/views/fields/field.js index 1f90a9c040c..24c8f3fe451 100644 --- a/addons/web/static/src/views/fields/field.js +++ b/addons/web/static/src/views/fields/field.js @@ -150,14 +150,15 @@ export class Field extends Component { ...makeContext([fieldInfo.context], evalContext), }; }, - get domain() { + domain() { const evalContext = record.getEvalContext ? record.getEvalContext(true) : record.evalContext; - - return fieldInfo.domain - ? new Domain(evaluateExpr(fieldInfo.domain, evalContext)).toList() - : undefined; + if (fieldInfo.domain) { + return new Domain(evaluateExpr(fieldInfo.domain, evalContext)).toList(); + } + const { domain } = record.fields[fieldInfo.name]; + return domain ? new Domain(domain).toList(evalContext) : []; }, readonly: readonlyFromModifiers, get required() { diff --git a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js index 1d77c3980e4..a89b7f5a73d 100644 --- a/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js +++ b/addons/web/static/src/views/fields/many2many_tags/many2many_tags_field.js @@ -39,7 +39,7 @@ export class Many2ManyTagsField extends Component { canCreateEdit: { type: Boolean, optional: true }, colorField: { type: String, optional: true }, createDomain: { type: [Array, Boolean], optional: true }, - domain: { type: Array, optional: true }, + domain: { type: [Array, Function], optional: true }, context: { type: Object, optional: true }, placeholder: { type: String, optional: true }, nameCreateField: { type: String, optional: true }, @@ -148,8 +148,10 @@ export class Many2ManyTagsField extends Component { } getDomain() { + const domain = + typeof this.props.domain === "function" ? this.props.domain() : this.props.domain; return Domain.and([ - this.props.domain || this.props.record.getFieldDomain(this.props.name), + domain, Domain.not([["id", "in", this.props.record.data[this.props.name].currentIds]]), ]).toList(this.props.context); } 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 f109edd1e02..20761709f23 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.js +++ b/addons/web/static/src/views/fields/many2one/many2one_field.js @@ -54,7 +54,7 @@ export class Many2OneField extends Component { canQuickCreate: { type: Boolean, optional: true }, canCreateEdit: { type: Boolean, optional: true }, context: { type: Object, optional: true }, - domain: { type: Array, optional: true }, + domain: { type: [Array, Function], optional: true }, nameCreateField: { type: String, optional: true }, searchLimit: { type: Number, optional: true }, relation: { type: String, optional: true }, @@ -215,7 +215,8 @@ export class Many2OneField extends Component { }; } getDomain() { - return this.props.domain || this.props.record.getFieldDomain(this.props.name); + const domain = this.props.domain; + return typeof domain === "function" ? domain() : domain; } async openAction() { const action = await this.orm.call(this.relation, "get_formview_action", [[this.resId]], { diff --git a/addons/web/static/src/views/fields/x2many/x2many_field.js b/addons/web/static/src/views/fields/x2many/x2many_field.js index 29749d150d5..74025398626 100644 --- a/addons/web/static/src/views/fields/x2many/x2many_field.js +++ b/addons/web/static/src/views/fields/x2many/x2many_field.js @@ -32,7 +32,7 @@ export class X2ManyField extends Component { crudOptions: { type: Object, optional: true }, string: { type: String, optional: true }, views: { type: Object, optional: true }, - domain: { type: Array, optional: true }, + domain: { type: [Array, Function], optional: true }, context: { type: Object }, }; @@ -240,7 +240,8 @@ export class X2ManyField extends Component { } async onAdd({ context, editable } = {}) { - const domain = this.props.domain || this.props.record.getFieldDomain(this.props.name); + const domain = + typeof this.props.domain === "function" ? this.props.domain() : this.props.domain; context = makeContext([this.props.context, context]); if (this.isMany2Many) { const { string } = this.props;