Currently, a user opening a spreadsheet containing pivots/lists/graphs that they don't have the rights to access (be it because of the parent model or the domain applied) will end up in an infinite loop. While starting the datasources, the fetch step will throw, potentially spamming the user with access errors. Manual forward port of https://github.com/odoo/enterprise/pull/35146 Task 3107650 closes odoo/odoo#110113 X-original-commit: 1555e79be0b52c30df43e8de50f5db56fbbda630 Signed-off-by: Rémi Rahir (rar) <rar@odoo.com> Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
/** @odoo-module */
|
|
|
|
import { ormService } from "@web/core/orm_service";
|
|
import { registry } from "@web/core/registry";
|
|
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
|
|
import { nextTick } from "@web/../tests/helpers/utils";
|
|
|
|
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
|
|
import { DataSources } from "@spreadsheet/data_sources/data_sources";
|
|
import { getBasicServerData } from "./data";
|
|
|
|
const { Model } = spreadsheet;
|
|
|
|
/**
|
|
* @typedef {import("@spreadsheet/../tests/utils/data").ServerData} ServerData
|
|
* @typedef {import("@spreadsheet/o_spreadsheet/o_spreadsheet").Model} Model
|
|
*/
|
|
|
|
export function setupDataSourceEvaluation(model) {
|
|
model.config.custom.dataSources.addEventListener("data-source-updated", () => {
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("EVALUATE_CELLS", { sheetId });
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create a spreadsheet model with a mocked server environnement
|
|
*
|
|
* @param {object} params
|
|
* @param {object} [params.spreadsheetData] Spreadsheet data to import
|
|
* @param {ServerData} [params.serverData] Data to be injected in the mock server
|
|
* @param {function} [params.mockRPC] Mock rpc function
|
|
*/
|
|
export async function createModelWithDataSource(params = {}) {
|
|
registry.category("services").add("orm", ormService, { force: true });
|
|
const env = await makeTestEnv({
|
|
serverData: params.serverData || getBasicServerData(),
|
|
mockRPC: params.mockRPC,
|
|
});
|
|
const model = new Model(params.spreadsheetData, {
|
|
custom: {
|
|
env,
|
|
dataSources: new DataSources(env.services.orm.silent),
|
|
},
|
|
});
|
|
setupDataSourceEvaluation(model);
|
|
await nextTick(); // initial async formulas loading
|
|
return model;
|
|
}
|
|
|
|
/**
|
|
* @param {Model} model
|
|
*/
|
|
export async function waitForDataSourcesLoaded(model) {
|
|
function readAllCellsValue() {
|
|
for (const sheetId of model.getters.getSheetIds()) {
|
|
const cells = model.getters.getEvaluatedCells(sheetId);
|
|
for (const cellId in cells) {
|
|
cells[cellId].value;
|
|
}
|
|
}
|
|
}
|
|
// Read a first time in order to trigger the RPC
|
|
readAllCellsValue();
|
|
//@ts-ignore
|
|
await model.config.custom.dataSources.waitForAllLoaded();
|
|
await nextTick();
|
|
// Read a second time to trigger the compute format (which could trigger a RPC for currency, in list)
|
|
readAllCellsValue();
|
|
await nextTick();
|
|
// Read a third time to trigger the RPC to get the correct currency
|
|
readAllCellsValue();
|
|
await nextTick();
|
|
}
|