diff options
| author | qsm-odoo <qsm@odoo.com> | 2017-02-28 11:48:00 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2017-04-11 19:44:38 +0200 |
| commit | 5804ed100ec790a36c5ff30a217914950cd78098 (patch) | |
| tree | a9f7ecf403cc8682c52ecce354ba082e9dee1a7c /addons/web/static/src/js/fields | |
| parent | e5740270568404d71a3bc093074a085c9c2eded8 (diff) | |
[IMP] web, *: compute contexts and domains from datapoint
This commit tries to refactore the management of contexts and domains
in the webclient.
- Get rid of CompoundDomain: use standard array manipulation to
join multiple domains or use the Domain class (to be improved)
- Get rid of data.js build_domain and build_context methods
- Link this.record to the data point from the basic model for all
fields (not only relational fields)
- Add a getContext and a getDomain function to the basic model
data point (localData element) so that AbstractField implementations
can use them thanks to their this.record element.
- Remove the autocontext binding for field RPCs (see FieldManagerMixin)
Diffstat (limited to 'addons/web/static/src/js/fields')
| -rw-r--r-- | addons/web/static/src/js/fields/abstract_field.js | 15 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/basic_fields.js | 4 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/relational_fields.js | 100 |
3 files changed, 46 insertions, 73 deletions
diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 6b914106371..ef67ba9b3c6 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -81,6 +81,9 @@ var AbstractField = Widget.extend({ // 'name' is the field name displayed by this widget this.name = name; + // the datapoint fetched from the model + this.record = record; + // the 'field' property is a description of all the various field properties, // such as the type, the comodel (relation), ... this.field = record.fields[name]; @@ -208,17 +211,6 @@ var AbstractField = Widget.extend({ this._reset(record, event); return this._render(); }, - /** - * @override performModelRPC from ServicesMixin - * Adds the dataPointID to the option parameter so that the BasicController - * (the FieldManagerMixin) knows the context to bind to the rpc call. - */ - performModelRPC: function (model, method, args, kwargs, options) { - return this._super(model, method, args, kwargs, _.extend({ - dataPointID: this.dataPointID, - fieldName: this.name, - }, options || {})); - }, //-------------------------------------------------------------------------- // Private @@ -289,6 +281,7 @@ var AbstractField = Widget.extend({ * @param {OdooEvent} event the event that triggered the change */ _reset: function (record, event) { + this.record = record; this.value = record.data[this.name]; this.recordData = record.data; }, diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 6b2cd4d6754..17e4e33f20e 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1298,9 +1298,9 @@ var FieldDomain = AbstractField.extend({ // ... then query the model to get the number of matched record if valid var self = this; return def.then(function () { - var context = {}; // FIXME ? return self.rpc(self.domainModel, "search_count") - .args([domain,context]) + .args([domain]) + .kwargs({context: self.record.getContext({fieldName: self.name})}) .exec() .then(function (data) { self._isValidForModel = true; diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index c5750c86735..51760a3c3b8 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -16,7 +16,6 @@ odoo.define('web.relational_fields', function (require) { var AbstractField = require('web.AbstractField'); var concurrency = require('web.concurrency'); var config = require('web.config'); -var Context = require('web.Context'); var ControlPanel = require('web.ControlPanel'); var dialogs = require('web.view_dialogs'); var core = require('web.core'); @@ -26,39 +25,10 @@ var field_utils = require('web.field_utils'); var KanbanRenderer = require('web.KanbanRenderer'); var ListRenderer = require('web.ListRenderer'); var Pager = require('web.Pager'); -var pyeval = require('web.pyeval'); var _t = core._t; var qweb = core.qweb; -/** - * Abstract widget to handle relational fields - */ -var AbstractRelationalField = AbstractField.extend({ - init: function (parent, name, record) { - this._super.apply(this, arguments); - // 'domain' and 'context' that should be used by the field widget. It - // can come from the attrs, and is mostly useful for rpcs - this.domain = this.attrs.domain || this.field.domain || []; - this.context = this.attrs.context || this.field.context || {}; - - // todo: remove this - this.record = record; - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @private - */ - _reset: function (record) { - this.record = record; - this._super.apply(this, arguments); - }, -}); - //------------------------------------------------------------------------------ // Many2one widgets //------------------------------------------------------------------------------ @@ -104,7 +74,7 @@ var M2ODialog = Dialog.extend({ }, }); -var FieldMany2One = AbstractRelationalField.extend({ +var FieldMany2One = AbstractField.extend({ template: 'FieldMany2One', custom_events: { 'quick_create': '_onQuickCreate', @@ -229,6 +199,7 @@ var FieldMany2One = AbstractRelationalField.extend({ if (this.nodeOptions.quick_create) { this.rpc(this.field.relation, "name_create") .args([name]) + .kwargs({context: this.record.getContext({fieldName: this.name})}) .exec() .then(function (result) { if (self.mode === "edit") { @@ -288,18 +259,20 @@ var FieldMany2One = AbstractRelationalField.extend({ var def = $.Deferred(); this.orderer.add(def); - var exclusion_domain = []; + var context = this.record.getContext({fieldName: this.name}); + var domain = this.record.getDomain({fieldName: this.name}); + var blacklisted_ids = this._getSearchBlacklist(); if (blacklisted_ids.length > 0) { - exclusion_domain.push(['id', 'not in', blacklisted_ids]); + domain.push(['id', 'not in', blacklisted_ids]); } - var domain = new data.CompoundDomain(data.build_domain(this.record, this.domain), exclusion_domain); this.performModelRPC(this.field.relation, "name_search", [], { name: search_val, - args: pyeval.eval("domain", domain), + args: domain, operator: "ilike", limit: this.limit + 1, + context: context, }).then(function (result) { // possible selections for the m2o var values = _.map(result, function (x) { @@ -320,9 +293,10 @@ var FieldMany2One = AbstractRelationalField.extend({ action: function () { self.performModelRPC(self.field.relation, "name_search", { name: search_val, - args: pyeval.eval('domain', domain), + args: domain, operator: "ilike", limit: 160, + context: context, }).then(self._searchCreatePopup.bind(self, "search")); }, classname: 'o_m2o_dropdown_option', @@ -370,8 +344,8 @@ var FieldMany2One = AbstractRelationalField.extend({ var self = this; new dialogs.SelectCreateDialog(this, _.extend({}, this.nodeOptions, { res_model: this.field.relation, - domain: data.build_domain(this.record, this.domain), - context: new Context(data.build_context(this.record, this.context), context || {}), + domain: this.record.getDomain({fieldName: this.name}), + context: _.extend({}, this.record.getContext({fieldName: this.name}), context || {}), title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, initial_ids: ids ? _.map(ids, function (x) { return x[0]; }) : undefined, initial_view: view, @@ -405,12 +379,13 @@ var FieldMany2One = AbstractRelationalField.extend({ if (this.mode === 'readonly' && !this.nodeOptions.no_open) { event.preventDefault(); event.stopPropagation(); - var context = data.build_context(this.record, this.context); - var args = [[this.value.res_id], context.eval()]; - this.performModelRPC(this.field.relation, 'get_formview_action', args) - .then(function (action) { - self.trigger_up('do_action', {action: action}); - }); + this.performModelRPC(this.field.relation, 'get_formview_action', [ + [this.value.res_id] + ], { + context: this.record.getContext({fieldName: this.name}), + }).then(function (action) { + self.trigger_up('do_action', {action: action}); + }); } }, /** @@ -422,11 +397,14 @@ var FieldMany2One = AbstractRelationalField.extend({ return; } var self = this; - var context = data.build_context(this.record, this.context); var model = this.field.relation; var method = 'get_formview_id'; - var args = [[this.value.res_id], context.eval()]; - this.performModelRPC(model, method, args).then(function (view_id) { + var context = this.record.getContext({fieldName: this.name}); + this.performModelRPC(model, method, [ + [this.value.res_id] + ], { + context: context, + }).then(function (view_id) { new dialogs.FormViewDialog(self, { res_model: self.field.relation, res_id: self.value.res_id, @@ -492,7 +470,7 @@ var ListFieldMany2One = FieldMany2One.extend({ }, }); -var KanbanFieldMany2One = AbstractRelationalField.extend({ +var KanbanFieldMany2One = AbstractField.extend({ tagName: 'span', init: function () { this._super.apply(this, arguments); @@ -515,9 +493,9 @@ var KanbanFieldMany2One = AbstractRelationalField.extend({ // X2Many widgets //------------------------------------------------------------------------------ -var FieldX2Many = AbstractRelationalField.extend({ +var FieldX2Many = AbstractField.extend({ tagName: 'div', - custom_events: _.extend({}, AbstractRelationalField.prototype.custom_events, { + custom_events: _.extend({}, AbstractField.prototype.custom_events, { field_changed: '_onFieldChanged', kanban_record_delete: '_onDeleteRecord', list_record_delete: '_onDeleteRecord', @@ -716,8 +694,8 @@ var FieldX2Many = AbstractRelationalField.extend({ */ _onOpenRecord: function (event) { _.extend(event.data, { - context: data.build_context(this.record, this.context), - domain: data.build_context(this.record, this.domain), + context: this.record.getContext({fieldName: this.name}), + domain: this.record.getDomain({fieldName: this.name}), form_view: this.field.views && this.field.views.form, readonly: this.mode === 'readonly', string: this.string, @@ -810,8 +788,8 @@ var FieldOne2Many = FieldX2Many.extend({ }); } else { this.trigger_up('add_one2many_record', { - domain: data.build_domain(this.record, this.domain), - context: data.build_context(this.record, this.context), + domain: this.record.getDomain({fieldName: this.name}), + context: this.record.getContext({fieldName: this.name}), field: this.field, on_save: function (record) { this._setValue({ @@ -872,11 +850,13 @@ var FieldMany2Many = FieldX2Many.extend({ */ _onAddRecord: function () { var self = this; - var domain = data.build_domain(this.record, this.domain); + + var domain = this.record.getDomain({fieldName: this.name}); + new dialogs.SelectCreateDialog(this, { res_model: this.field.relation, - domain: new data.CompoundDomain(domain, ["!", ["id", "in", this.value.res_ids]]), - context: data.build_context(this.record, this.context), + domain: domain.concat(["!", ["id", "in", this.value.res_ids]]), + context: this.record.getContext({fieldName: this.name}), title: _t("Add: ") + this.string, no_create: this.nodeOptions.no_create || !this.activeActions.create, on_selected: function (res_ids) { @@ -908,7 +888,7 @@ var FieldMany2Many = FieldX2Many.extend({ }, }); -var FieldMany2ManyTags = AbstractRelationalField.extend({ +var FieldMany2ManyTags = AbstractField.extend({ tag_template: "FieldMany2ManyTag", className: "o_form_field o_form_field_many2manytags", replace_element: true, @@ -1118,9 +1098,9 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({ }, }); -var FieldMany2ManyCheckBoxes = AbstractRelationalField.extend({ +var FieldMany2ManyCheckBoxes = AbstractField.extend({ template: 'FieldMany2ManyCheckBoxes', - events: _.extend({}, AbstractRelationalField.prototype.events, { + events: _.extend({}, AbstractField.prototype.events, { change: '_onChange', }), supportedFieldTypes: ['many2many'], |
