diff --git a/addons/stock/static/src/js/lazy_column_list.js b/addons/stock/static/src/js/lazy_column_list.js
index e8a22e27def..cb51b60b9c1 100644
--- a/addons/stock/static/src/js/lazy_column_list.js
+++ b/addons/stock/static/src/js/lazy_column_list.js
@@ -16,9 +16,14 @@ function _findRecordsInState(entrypoint, result = []) {
return result;
}
-function _bindLazyColumnToState(entrypoint, lazyColumns, values) {
+function _bindLazyColumnToState(entrypoint, lazyColumns, values, startRequestTime) {
let records = _findRecordsInState(entrypoint);
for (const recordData of records.values()) {
+ // keep track of request start time (in _fetchRecord) when we fetch a particular record (can happens we
+ // modify the priority field) to avoids to erase the old data if the lazy loaded finished after.
+ if (startRequestTime && recordData.specialData && recordData.specialData.lastUpdateLazy && startRequestTime <= recordData.specialData.lastUpdateLazy){
+ continue
+ }
for (const lazyCol of lazyColumns) {
recordData.data[lazyCol] =
(values && values[recordData.data.id] && values[recordData.data.id][lazyCol]) ||
@@ -29,6 +34,9 @@ function _bindLazyColumnToState(entrypoint, lazyColumns, values) {
function _getLazyColumns(fieldsInfo) {
const lazyColumns = [];
+ if (!fieldsInfo) {
+ return lazyColumns;
+ }
for (const [key, value] of Object.entries(fieldsInfo)) {
if (value.options && value.options.lazy) {
lazyColumns.push(key);
@@ -50,6 +58,10 @@ const LazyColumnListModel = ListModel.extend({
*/
_getFieldNames: function (element, options) {
const res = this._super.apply(this, arguments);
+ if (element.type !== "list") {
+ // lazy is only for list type element
+ return res;
+ }
const fieldsInfo = element.fieldsInfo;
const viewType = (options && options.viewType) || element.viewType;
const lazyColumns = _getLazyColumns(fieldsInfo[viewType]);
@@ -66,6 +78,11 @@ const LazyColumnListModel = ListModel.extend({
}
return dataPoint;
},
+
+ _fetchRecord: function(record, options) {
+ record.specialData.lastUpdateLazy = Date.now();
+ return this._super.apply(this, arguments);
+ }
});
const LazyColumnListRenderer = ListRenderer.extend({
@@ -75,6 +92,7 @@ const LazyColumnListRenderer = ListRenderer.extend({
},
_lazyLoad: async function (state, lazyColumns) {
+ const startRequestTime = Date.now()
const res = await this._rpc(
{
model: state.model,
@@ -90,9 +108,9 @@ const LazyColumnListRenderer = ListRenderer.extend({
resById[element.id][lazyCol] = element[lazyCol];
}
}
- _bindLazyColumnToState(this.state, lazyColumns, resById);
+ _bindLazyColumnToState(this.state, lazyColumns, resById, startRequestTime);
this.currentNbLazyRpc -= 1;
- // Render only thr
+ // Render only the lazy columns
for (const lazyCol of lazyColumns) {
const node = this.columns.find((colAttribute) => colAttribute.attrs.name === lazyCol);
if (!node) {
diff --git a/addons/stock/static/tests/lazy_column_list_tests.js b/addons/stock/static/tests/lazy_column_list_tests.js
index 6844a787451..41449f39b98 100644
--- a/addons/stock/static/tests/lazy_column_list_tests.js
+++ b/addons/stock/static/tests/lazy_column_list_tests.js
@@ -14,11 +14,12 @@ QUnit.module(
person: {
fields: {
name: { string: "Name", type: "char" },
+ priority: { string: "Priority", type: "selection", selection: [['0', 'normal'],['1', 'important']]},
slowField: { string: "Hard to Compute", type: "char" },
},
records: [
- { id: 1, name: "Daniel Fortesque" },
- { id: 2, name: "Samuel Oak" },
+ { id: 1, priority: '0', name: "Daniel Fortesque" },
+ { id: 2, priority: '0', name: "Samuel Oak" },
],
},
};
@@ -40,23 +41,21 @@ QUnit.module(
'' +
"",
mockRPC: async function (route, args) {
- console.log(route);
if (route === "/web/dataset/call_kw/person/read") {
+ const record_ids = args.args[0];
const fields = args.args[1];
- const records = [];
+ const recs = [];
for (const d of this.data.person.records) {
- let reco = { id: d.id };
- for (const f of fields) {
- if (f === "slowField") {
- reco[f] = `${d.name} ${d.id}`;
- } else {
- reco[f] = d[f];
- }
+ if (record_ids.includes(d.id)) {
+ d["slowField"] = `${d.name} ${d.id}`;
+ recs.push(d);
}
- records.push(reco);
}
- await promiseRead;
- return Promise.resolve(records);
+ // Don't wait if it read only one record
+ if (fields.includes("slowField") && record_ids.length > 1) {
+ await promiseRead;
+ }
+ return Promise.resolve(recs);
}
return this._super.apply(this, arguments);
},
@@ -87,5 +86,81 @@ QUnit.module(
list.destroy();
});
+
+ QUnit.test("With the priority widget", async function (assert) {
+ assert.expect(19);
+ const promiseRead = makeDeferred();
+ const list = await createView({
+ View: LazyColumnList,
+ model: "person",
+ data: this.data,
+ arch:
+ '' +
+ '' +
+ '' +
+ '' +
+ "",
+ mockRPC: async function (route, args) {
+ if (route === "/web/dataset/call_kw/person/read") {
+ const record_ids = args.args[0];
+ const fields = args.args[1];
+ const recs = [];
+ for (const d of this.data.person.records) {
+ if (record_ids.includes(d.id)) {
+ d["slowField"] = `${d.name} ${d.id} ${d.priority}`;
+ recs.push(d);
+ }
+ }
+ // Don't wait if it read only one record
+ if (fields.includes("slowField") && record_ids.length > 1) {
+ await promiseRead;
+ }
+ return Promise.resolve(recs);
+ }
+ return this._super.apply(this, arguments);
+ },
+ });
+ // Checks we have initially 2 records
+ assert.containsN(list, ".o_data_row", 2, "should have 2 records");
+
+ let $spin = list.$el.find("th[data-name='slowField'] .fa.fa-spin");
+ let $results = list.$el.find("td[name='slowField']");
+ assert.equal($spin.length, 1);
+ assert.equal($spin.hasClass("invisible"), false);
+ assert.equal($results.length, 2);
+ assert.equal($results.first().text(), "");
+ assert.equal($results.last().text(), "");
+
+ assert.strictEqual(list.$('.o_data_row').first().find('.o_priority a.fa-star').length, 0,
+ "widget shouldn't be considered set");
+ await testUtils.dom.click(list.$('.o_data_row').first().find('.o_priority a.fa-star-o').first());
+
+ assert.strictEqual(list.$('.o_data_row').first().find('.o_priority a.fa-star').length, 1,
+ "widget should be considered set");
+ $spin = list.$el.find("th[data-name='slowField'] .fa.fa-spin");
+ $results = list.$el.find("td[name='slowField']");
+ assert.equal($spin.length, 1);
+ assert.equal($spin.hasClass("invisible"), false);
+ assert.equal($results.length, 2);
+ assert.equal($results.first().text(), "Daniel Fortesque 1 1",
+ "It should be read by the click on priority");
+ assert.equal($results.last().text(), "");
+
+ promiseRead.resolve();
+ await nextTick();
+
+ $spin = list.$el.find("th[data-name='slowField'] .fa.fa-spin");
+ $results = list.$el.find("td[name='slowField']");
+ assert.equal($spin.length, 1);
+ assert.equal($spin.hasClass("invisible"), true);
+ assert.equal($results.length, 2);
+ assert.equal($results.first().text(), "Daniel Fortesque 1 1",
+ "It shouldn't be erase the data from priority click because this data is newer");
+ assert.equal($results.last().text(), "Samuel Oak 2 0");
+
+ assert.containsN(list, ".o_data_row", 2, "should have 2 records");
+
+ list.destroy();
+ });
}
);