diff --git a/addons/web/static/src/model/relational_model/dynamic_group_list.js b/addons/web/static/src/model/relational_model/dynamic_group_list.js index 34ba5cda159..7176ebbb461 100644 --- a/addons/web/static/src/model/relational_model/dynamic_group_list.js +++ b/addons/web/static/src/model/relational_model/dynamic_group_list.js @@ -14,6 +14,10 @@ export class DynamicGroupList extends DynamicList { setup(config, data) { super.setup(...arguments); this.isGrouped = true; + this._setData(data); + } + + _setData(data) { /** @type {import("./group").Group[]} */ this.groups = data.groups.map((g) => this._createGroupDatapoint(g)); this.count = data.length; @@ -239,9 +243,11 @@ export class DynamicGroupList extends DynamicList { for (const group of groups) { delete configGroups[group.value]; } - const response = await this.model._updateConfig(this.config, { groups: configGroups }); - this.groups = response.groups.map((group) => this._createGroupDatapoint(group)); - this.count = response.length; + await this.model._updateConfig( + this.config, + { groups: configGroups }, + { commit: this._setData.bind(this) } + ); } else { for (const group of groups) { this._removeGroup(group); @@ -258,14 +264,11 @@ export class DynamicGroupList extends DynamicList { } async _load(offset, limit, orderBy, domain) { - const response = await this.model._updateConfig(this.config, { - offset, - limit, - orderBy, - domain, - }); - this.groups = response.groups.map((group) => this._createGroupDatapoint(group)); - this.count = response.length; + await this.model._updateConfig( + this.config, + { offset, limit, orderBy, domain }, + { commit: this._setData.bind(this) } + ); } _removeGroup(group) { diff --git a/addons/web/static/src/model/relational_model/dynamic_record_list.js b/addons/web/static/src/model/relational_model/dynamic_record_list.js index a23111bdbb0..7543896e552 100644 --- a/addons/web/static/src/model/relational_model/dynamic_record_list.js +++ b/addons/web/static/src/model/relational_model/dynamic_record_list.js @@ -11,6 +11,10 @@ export class DynamicRecordList extends DynamicList { */ setup(config, data) { super.setup(config); + this._setData(data); + } + + _setData(data) { /** @type {import("./record").Record[]} */ this.records = data.records.map((r) => this._createRecordDatapoint(r)); this._updateCount(data); @@ -141,14 +145,11 @@ export class DynamicRecordList extends DynamicList { } async _load(offset, limit, orderBy, domain) { - const response = await this.model._updateConfig(this.config, { - offset, - limit, - orderBy, - domain, - }); - this.records = response.records.map((r) => this._createRecordDatapoint(r)); - this._updateCount(response); + await this.model._updateConfig( + this.config, + { offset, limit, orderBy, domain }, + { commit: this._setData.bind(this) } + ); } _removeRecords(recordIds) { diff --git a/addons/web/static/src/model/relational_model/record.js b/addons/web/static/src/model/relational_model/record.js index 67541910f71..cab21674422 100644 --- a/addons/web/static/src/model/relational_model/record.js +++ b/addons/web/static/src/model/relational_model/record.js @@ -49,28 +49,35 @@ export class Record extends DataPoint { } const missingFields = this.fieldNames.filter((fieldName) => !(fieldName in data)); data = { ...this._getDefaultValues(missingFields), ...data }; - const vals = this._parseServerValues(data); - if (this.resId) { - this._values = markRaw(vals); - this._changes = markRaw({}); - } else { - this._values = markRaw({}); - this._changes = markRaw(vals); - } - this.data = { ...this._values, ...this._changes }; // In db, char, text and html fields can be not set (NULL) and set to the empty string. In // the UI, there's no difference, but in the eval context, it's not the same. The next // structure keeps track of the server values we received for those fields (which can thus // be false or a string). This allows us to properly build the eval context, and to always // expose string values (false fallbacks on the empty string) in this.data. this._textValues = markRaw({}); - this._setTextValues(data); + this._setData(data); + } + + _setData(data) { + if (this.resId) { + this._values = this._parseServerValues(data); + this._changes = markRaw({}); + this._setTextValues(data); + } else { + this._values = markRaw({}); + const allVals = { ...this._getDefaultValues(), ...data }; + this._changes = this._parseServerValues(allVals); + this._setTextValues(allVals); + } + this.dirty = false; + this.data = { ...this._values, ...this._changes }; this._setEvalContext(); this._savePoint = markRaw({ dirty: false, changes: { ...this._changes }, textValues: { ...this._textValues }, }); + this._invalidFields.clear(); } // ------------------------------------------------------------------------- @@ -535,27 +542,14 @@ export class Record extends DataPoint { async _load(nextConfig = {}) { // FIXME: do not allow to change resId? maybe add a new method on model to re-generate a // new root for the new resId - const values = await this.model._updateConfig(this.config, nextConfig); - if (this.resId) { - this.model._updateSimilarRecords(this, values); - this._values = this._parseServerValues(values); - this._changes = markRaw({}); - this._setTextValues(values); - } else { - this._values = markRaw({}); - const allVals = { ...this._getDefaultValues(), ...values }; - this._changes = this._parseServerValues(allVals); - this._setTextValues(allVals); - } - this.dirty = false; - this.data = { ...this._values, ...this._changes }; - this._setEvalContext(); - this._savePoint = markRaw({ - dirty: false, - changes: { ...this._changes }, - textValues: { ...this._textValues }, + await this.model._updateConfig(this.config, nextConfig, { + commit: (values) => { + if (this.resId) { + this.model._updateSimilarRecords(this, values); + } + this._setData(values); + }, }); - this._invalidFields.clear(); } _parseServerValues(serverValues, currentValues = {}) { diff --git a/addons/web/static/src/model/relational_model/relational_model.js b/addons/web/static/src/model/relational_model/relational_model.js index 27dfa6a4646..bd0bda31369 100644 --- a/addons/web/static/src/model/relational_model/relational_model.js +++ b/addons/web/static/src/model/relational_model/relational_model.js @@ -603,15 +603,18 @@ export class RelationalModel extends Model { * @param {Partial} patch * @param {Object} [options] * @param {boolean} [options.noReload=false] + * @param {Function} [options.commit] Function to call once the data has been loaded */ async _updateConfig(config, patch, options = {}) { const tmpConfig = { ...config, ...patch }; - let response; + let data; if (!options.noReload) { - response = await this._loadData(tmpConfig); + data = await this._loadData(tmpConfig); } Object.assign(config, tmpConfig); - return response; + if (data && options.commit) { + options.commit(data); + } } /**