diff --git a/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js b/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js index cb2ceb5b906..812fd6216a2 100644 --- a/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js +++ b/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js @@ -3,13 +3,11 @@ import * as spreadsheet from "@odoo/o-spreadsheet"; import CommandResult from "../../o_spreadsheet/cancelled_reason"; import { getMaxObjectId } from "../../helpers/helpers"; -import ListDataSource from "../list_data_source"; import { TOP_LEVEL_STYLE } from "../../helpers/constants"; import { _t } from "@web/core/l10n/translation"; import { globalFiltersFieldMatchers } from "@spreadsheet/global_filters/plugins/global_filters_core_plugin"; import { sprintf } from "@web/core/utils/strings"; import { checkFilterFieldMatching } from "@spreadsheet/global_filters/helpers"; -import { getFirstListFunction, getNumberOfListFormulas } from "../list_helpers"; /** * @typedef {Object} ListDefinition @@ -35,7 +33,6 @@ const { CorePlugin } = spreadsheet; export default class ListCorePlugin extends CorePlugin { constructor(config) { super(config); - this.dataSources = config.custom.dataSources; this.nextId = 1; /** @type {Object.} */ @@ -46,9 +43,7 @@ export default class ListCorePlugin extends CorePlugin { getDisplayName: (listId) => this.getters.getListName(listId), getTag: (listId) => sprintf(_t("List #%s"), listId), getFieldMatching: (listId, filterId) => this.getListFieldMatching(listId, filterId), - waitForReady: () => this.getListsWaitForReady(), getModel: (listId) => this.getListDefinition(listId).model, - getFields: (listId) => this.getListDataSource(listId).getFields(), }; } @@ -87,10 +82,9 @@ export default class ListCorePlugin extends CorePlugin { handle(cmd) { switch (cmd.type) { case "INSERT_ODOO_LIST": { - const { sheetId, col, row, id, definition, dataSourceId, linesNumber, columns } = - cmd; + const { sheetId, col, row, id, definition, linesNumber, columns } = cmd; const anchor = [col, row]; - this._addList(id, definition, dataSourceId, linesNumber); + this._addList(id, definition); this._insertList(sheetId, anchor, id, linesNumber, columns); this.history.update("nextId", parseInt(id, 10) + 1); break; @@ -120,19 +114,6 @@ export default class ListCorePlugin extends CorePlugin { "domain", cmd.domain ); - const list = this.lists[cmd.listId]; - this.dataSources.add(list.dataSourceId, ListDataSource, list.definition); - break; - } - case "UNDO": - case "REDO": { - const domainEditionCommands = cmd.commands.filter( - (cmd) => cmd.type === "UPDATE_ODOO_LIST_DOMAIN" - ); - for (const cmd of domainEditionCommands) { - const list = this.lists[cmd.listId]; - this.dataSources.add(list.dataSourceId, ListDataSource, list.definition); - } break; } case "ADD_GLOBAL_FILTER": @@ -144,64 +125,13 @@ export default class ListCorePlugin extends CorePlugin { case "REMOVE_GLOBAL_FILTER": this._onFilterDeletion(cmd.id); break; - - case "START": - for (const sheetId of this.getters.getSheetIds()) { - const cells = this.getters.getCells(sheetId); - for (const cell of Object.values(cells)) { - if (cell.isFormula) { - this._addListPositionToDataSource(cell.content); - } - } - } - break; - case "UPDATE_CELL": - if (cmd.content) { - this._addListPositionToDataSource(cmd.content); - } - break; } } - /** - * Extract the position of the records asked in the given formula and - * increase the max position of the corresponding data source. - * - * @param {string} content Odoo list formula - */ - _addListPositionToDataSource(content) { - if (getNumberOfListFormulas(content) !== 1) { - return; - } - const { functionName, args } = getFirstListFunction(content); - if (functionName !== "ODOO.LIST") { - return; - } - const [listId, positionArg] = args.map((arg) => arg.value.toString()); - if (!(listId in this.lists)) { - return; - } - const position = parseInt(positionArg, 10); - if (isNaN(position)) { - return; - } - const dataSourceId = this.lists[listId].dataSourceId; - this.dataSources.get(dataSourceId).increaseMaxPosition(position); - } - // ------------------------------------------------------------------------- // Getters // ------------------------------------------------------------------------- - /** - * @param {string} id - * @returns {import("@spreadsheet/list/list_data_source").default|undefined} - */ - getListDataSource(id) { - const dataSourceId = this.lists[id].dataSourceId; - return this.dataSources.get(dataSourceId); - } - /** * @param {string} id * @returns {string} @@ -226,16 +156,6 @@ export default class ListCorePlugin extends CorePlugin { return this.lists[id].fieldMatching; } - /** - * @param {string} id - * @returns {Promise} - */ - async getAsyncListDataSource(id) { - const dataSourceId = this.lists[id].dataSourceId; - await this.dataSources.load(dataSourceId); - return this.getListDataSource(id); - } - /** * Retrieve all the list ids * @@ -271,6 +191,10 @@ export default class ListCorePlugin extends CorePlugin { }; } + getListModelDefinition(id) { + return this.lists[id].definition; + } + /** * Check if an id is an id of an existing list * @@ -286,14 +210,6 @@ export default class ListCorePlugin extends CorePlugin { // Private // --------------------------------------------------------------------- - /** - * - * @return {Promise[]} - */ - getListsWaitForReady() { - return this.getListIds().map((ListId) => this.getListDataSource(ListId).loadMetadata()); - } - /** * Get the current FieldMatching on a list * @@ -325,21 +241,14 @@ export default class ListCorePlugin extends CorePlugin { } } - _addList(id, definition, dataSourceId, limit, fieldMatching = {}) { + _addList(id, definition, fieldMatching = {}) { const lists = { ...this.lists }; lists[id] = { id, definition, - dataSourceId, fieldMatching, }; - if (!this.dataSources.contains(dataSourceId)) { - this.dataSources.add(dataSourceId, ListDataSource, { - ...definition, - limit, - }); - } this.history.update("lists", lists); } @@ -471,7 +380,7 @@ export default class ListCorePlugin extends CorePlugin { }, name: list.name, }; - this._addList(id, definition, this.uuidGenerator.uuidv4(), 0, list.fieldMatching); + this._addList(id, definition, list.fieldMatching); } } this.nextId = data.listNextId || getMaxObjectId(this.lists) + 1; @@ -492,10 +401,9 @@ export default class ListCorePlugin extends CorePlugin { } ListCorePlugin.getters = [ - "getListDataSource", "getListDisplayName", - "getAsyncListDataSource", "getListDefinition", + "getListModelDefinition", "getListIds", "getListName", "getNextListId", diff --git a/addons/spreadsheet/static/src/list/plugins/list_ui_plugin.js b/addons/spreadsheet/static/src/list/plugins/list_ui_plugin.js index 067ee51e38a..94937b11fae 100644 --- a/addons/spreadsheet/static/src/list/plugins/list_ui_plugin.js +++ b/addons/spreadsheet/static/src/list/plugins/list_ui_plugin.js @@ -1,8 +1,10 @@ /** @odoo-module */ import * as spreadsheet from "@odoo/o-spreadsheet"; -import { getFirstListFunction } from "../list_helpers"; +import { getFirstListFunction, getNumberOfListFormulas } from "../list_helpers"; import { Domain } from "@web/core/domain"; +import ListDataSource from "../list_data_source"; +import { globalFiltersFieldMatchers } from "@spreadsheet/global_filters/plugins/global_filters_core_plugin"; const { astToFormula } = spreadsheet; @@ -16,11 +18,23 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { /** @type {string} */ this.selectedListId = undefined; this.env = config.custom.env; + + this.dataSources = config.custom.dataSources; + + globalFiltersFieldMatchers["list"] = { + ...globalFiltersFieldMatchers["list"], + getFields: (listId) => this.getListDataSource(listId).getFields(), + waitForReady: () => this.getListsWaitForReady(), + }; } beforeHandle(cmd) { switch (cmd.type) { case "START": + for (const listId of this.getters.getListIds()) { + this._setupListDataSource(listId, 0); + } + // make sure the domains are correctly set before // any evaluation this._addDomains(); @@ -34,6 +48,21 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { */ handle(cmd) { switch (cmd.type) { + case "START": + for (const sheetId of this.getters.getSheetIds()) { + const cells = this.getters.getCells(sheetId); + for (const cell of Object.values(cells)) { + if (cell.isFormula) { + this._addListPositionToDataSource(cell.content); + } + } + } + break; + case "INSERT_ODOO_LIST": { + const { id, linesNumber } = cmd; + this._setupListDataSource(id, linesNumber); + break; + } case "SELECT_ODOO_LIST": this._selectList(cmd.listId); break; @@ -50,8 +79,19 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { case "CLEAR_GLOBAL_FILTER_VALUE": this._addDomains(); break; + case "UPDATE_ODOO_LIST_DOMAIN": { + const listDefinition = this.getters.getListModelDefinition(cmd.listId); + const dataSourceId = this._getListDataSourceId(cmd.listId); + this.dataSources.add(dataSourceId, ListDataSource, listDefinition); + break; + } + case "UPDATE_CELL": + if (cmd.content) { + this._addListPositionToDataSource(cmd.content); + } + break; case "UNDO": - case "REDO": + case "REDO": { if ( cmd.commands.find((command) => [ @@ -63,7 +103,22 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { ) { this._addDomains(); } + + const domainEditionCommands = cmd.commands.filter( + (cmd) => + cmd.type === "UPDATE_ODOO_LIST_DOMAIN" || cmd.type === "INSERT_ODOO_LIST" + ); + for (const cmd of domainEditionCommands) { + if (!this.getters.isExistingList(cmd.listId)) { + continue; + } + + const listDefinition = this.getters.getListModelDefinition(cmd.listId); + const dataSourceId = this._getListDataSourceId(cmd.listId); + this.dataSources.add(dataSourceId, ListDataSource, listDefinition); + } break; + } } } @@ -71,6 +126,17 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { // Handlers // ------------------------------------------------------------------------- + _setupListDataSource(listId, limit, definition) { + const dataSourceId = this._getListDataSourceId(listId); + definition = definition || this.getters.getListModelDefinition(listId); + if (!this.dataSources.contains(dataSourceId)) { + this.dataSources.add(dataSourceId, ListDataSource, { + ...definition, + limit, + }); + } + } + /** * Add an additional domain to a list * @@ -128,6 +194,40 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { this.selectedListId = listId; } + _getListDataSourceId(listId) { + return `list-${listId}`; + } + + /** + * Extract the position of the records asked in the given formula and + * increase the max position of the corresponding data source. + * + * @param {string} content Odoo list formula + */ + _addListPositionToDataSource(content) { + if (getNumberOfListFormulas(content) !== 1) { + return; + } + const { functionName, args } = getFirstListFunction(content); + if (functionName !== "ODOO.LIST") { + return; + } + const [listId, positionArg] = args.map((arg) => arg.value.toString()); + + if (!this.getters.getListIds().includes(listId)) { + return; + } + const position = parseInt(positionArg, 10); + if (isNaN(position)) { + return; + } + const dataSourceId = this._getListDataSourceId(listId); + if (!this.dataSources.get(dataSourceId)) { + this._setupListDataSource(listId, 0); + } + this.dataSources.get(dataSourceId).increaseMaxPosition(position); + } + // ------------------------------------------------------------------------- // Getters // ------------------------------------------------------------------------- @@ -191,6 +291,35 @@ export default class ListUIPlugin extends spreadsheet.UIPlugin { getSelectedListId() { return this.selectedListId; } + + /** + * @param {string} id + * @returns {import("@spreadsheet/list/list_data_source").default|undefined} + */ + getListDataSource(id) { + const dataSourceId = this._getListDataSourceId(id); + return this.dataSources.get(dataSourceId); + } + + /** + * @param {string} id + * @returns {Promise} + */ + async getAsyncListDataSource(id) { + const dataSourceId = this._getListDataSourceId(id); + await this.dataSources.load(dataSourceId); + return this.getListDataSource(id); + } + + /** + * + * @return {Promise[]} + */ + getListsWaitForReady() { + return this.getters + .getListIds() + .map((listId) => this.getListDataSource(listId).loadMetadata()); + } } ListUIPlugin.getters = [ @@ -199,4 +328,6 @@ ListUIPlugin.getters = [ "getListIdFromPosition", "getListCellValue", "getSelectedListId", + "getListDataSource", + "getAsyncListDataSource", ]; diff --git a/addons/spreadsheet/static/tests/utils/list.js b/addons/spreadsheet/static/tests/utils/list.js index 6edecf16cef..bc8a039b45f 100644 --- a/addons/spreadsheet/static/tests/utils/list.js +++ b/addons/spreadsheet/static/tests/utils/list.js @@ -1,11 +1,8 @@ /** @odoo-module */ -import * as spreadsheet from "@odoo/o-spreadsheet"; import { generateListDefinition } from "./data"; import { createModelWithDataSource, waitForDataSourcesLoaded } from "./model"; -const uuidGenerator = new spreadsheet.helpers.UuidGenerator(); - /** @typedef {import("@spreadsheet/o_spreadsheet/o_spreadsheet").Model} Model */ /** @@ -31,7 +28,6 @@ export function insertListInSpreadsheet(model, params) { id: model.getters.getNextListId(), col, row, - dataSourceId: uuidGenerator.uuidv4(), }); }