[FIX] spreadsheet: load data in background

When the data takes longer to load, the UI is blocked with the loading
overlay.

Now the data is loaded in the background and we can still navigate
in the spreadsheet.

Note: I moved the `.silent` upper in the call chain. Lower level structures
such as ServerData, DataSources, MetadataRepository don't need to know.

closes odoo/odoo#110387

X-original-commit: 8b09c7347ebeffa7059ed0ccc63f73e3559b7712
Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
This commit is contained in:
Lucas Lefèvre
2023-01-19 17:49:06 +01:00
parent d84cfbf9a8
commit 22d4a260ec
5 changed files with 32 additions and 45 deletions
@@ -17,7 +17,7 @@ const { EventBus } = owl;
export class DataSources extends EventBus {
constructor(orm) {
super();
this._orm = orm;
this._orm = orm.silent;
this._metadataRepository = new MetadataRepository(orm);
this._metadataRepository.addEventListener("labels-fetched", () => this.notify());
/** @type {Object.<string, any>} */
@@ -39,7 +39,7 @@ const { EventBus } = owl;
export class MetadataRepository extends EventBus {
constructor(orm) {
super();
this.orm = orm.silent;
this.orm = orm;
this.serverData = new ServerData(this.orm, {
whenDataIsFetched: () => this.trigger("labels-fetched"),
@@ -36,7 +36,6 @@ export default class ListDataSource extends OdooViewsDataSource {
constructor(services, params) {
super(services, params);
this.limit = params.limit;
this._orm = services.orm;
this.data = [];
}
@@ -8,11 +8,9 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
assert.expect(6);
const orm = {
silent: {
call: async (model, method) => {
assert.step(`${method}-${model}`);
return model;
},
call: async (model, method) => {
assert.step(`${method}-${model}`);
return model;
},
};
@@ -33,14 +31,12 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
assert.expect(6);
const orm = {
silent: {
call: async (model, method, args) => {
if (method === "display_name_for" && model === "ir.model") {
const [modelName] = args[0];
assert.step(`${modelName}`);
return [{ display_name: modelName, model: modelName }];
}
},
call: async (model, method, args) => {
if (method === "display_name_for" && model === "ir.model") {
const [modelName] = args[0];
assert.step(`${modelName}`);
return [{ display_name: modelName, model: modelName }];
}
},
};
@@ -60,7 +56,7 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
QUnit.test("Register label correctly memorize labels", function (assert) {
assert.expect(2);
const metadataRepository = new MetadataRepository({ silent: {} });
const metadataRepository = new MetadataRepository({});
assert.strictEqual(metadataRepository.getLabel("model", "field", "value"), undefined);
const label = "label";
@@ -70,12 +66,10 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
QUnit.test("Name_get are collected and executed once by clock", async function (assert) {
const orm = {
silent: {
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
};
@@ -105,12 +99,10 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
QUnit.test("Name_get to fetch are cleared after being fetched", async function (assert) {
const orm = {
silent: {
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
};
@@ -131,12 +123,10 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
"Assigning a result after triggering the request should not crash",
async function (assert) {
const orm = {
silent: {
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
return ids.map((id) => [id, id.toString()]);
},
};
@@ -157,15 +147,13 @@ QUnit.module("spreadsheet > Metadata Repository", {}, () => {
"Name_get will retry with one id by request in case of failure",
async function (assert) {
const orm = {
silent: {
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
if (model === "B" && ids.includes(1)) {
throw new Error("Missing");
}
return ids.map((id) => [id, id.toString()]);
},
call: async (model, method, args) => {
const ids = args[0];
assert.step(`${method}-${model}-[${ids.join(",")}]`);
if (model === "B" && ids.includes(1)) {
throw new Error("Missing");
}
return ids.map((id) => [id, id.toString()]);
},
};
@@ -40,7 +40,7 @@ export async function createModelWithDataSource(params = {}) {
const model = new Model(params.spreadsheetData, {
custom: {
env,
dataSources: new DataSources(env.services.orm.silent),
dataSources: new DataSources(env.services.orm),
},
});
setupDataSourceEvaluation(model);