[FIX] spreadsheet: load async formulas without delay

Now the promise waiting for all async no longer relies on a setInterval.
It was a hack that can be better solved by listening to the data sources
event.

closes odoo/odoo#114348

X-original-commit: de1f42f98410bc796dfdbfd237b1e20be4496166
Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
This commit is contained in:
Lucas Lefèvre
2023-03-03 19:10:20 +01:00
parent d47b5c3fa7
commit 4217c5b3dd
@@ -4,7 +4,6 @@ import { DataSources } from "@spreadsheet/data_sources/data_sources";
import { migrate } from "@spreadsheet/o_spreadsheet/migration";
import { download } from "@web/core/network/download";
import { registry } from "@web/core/registry";
import { browser } from "@web/core/browser/browser";
import spreadsheet from "../o_spreadsheet/o_spreadsheet_extended";
import { _t } from "@web/core/l10n/translation";
@@ -14,7 +13,6 @@ async function downloadSpreadsheet(env, action) {
const { orm, name, data, stateUpdateMessages } = action.params;
const dataSources = new DataSources(orm);
const model = new Model(migrate(data), { custom: { dataSources } }, stateUpdateMessages);
await dataSources.waitForAllLoaded();
await waitForDataLoaded(model);
const { files } = model.exportXLSX();
await download({
@@ -29,27 +27,34 @@ async function downloadSpreadsheet(env, action) {
/**
* Ensure that the spreadsheet does not contains cells that are in loading state
* @param {Model} model
* @returns {Promise}
* @returns {Promise<void>}
*/
async function waitForDataLoaded(model) {
model.dispatch("EVALUATE_CELLS");
const dataSources = model.config.custom.dataSources;
return new Promise((resolve, reject) => {
let interval = undefined;
interval = browser.setInterval(() => {
for (const sheetId of model.getters.getSheetIds()) {
for (const cell of Object.values(model.getters.getEvaluatedCells(sheetId))) {
if (cell.type === "error" && cell.error.message === _t("Data is loading")) {
model.dispatch("EVALUATE_CELLS");
return;
}
}
function check() {
model.dispatch("EVALUATE_CELLS");
if (isLoaded(model)) {
dataSources.removeEventListener("data-source-updated", check);
resolve();
}
browser.clearInterval(interval);
resolve();
}, 50);
}
dataSources.addEventListener("data-source-updated", check);
check();
});
}
function isLoaded(model) {
for (const sheetId of model.getters.getSheetIds()) {
for (const cell of Object.values(model.getters.getEvaluatedCells(sheetId))) {
if (cell.type === "error" && cell.error.message === _t("Data is loading")) {
return false;
}
}
}
return true;
}
registry
.category("actions")
.add("action_download_spreadsheet", downloadSpreadsheet, { force: true });