From 3911a69bbbf372052683b711f1f8dcca1490d2aa Mon Sep 17 00:00:00 2001 From: jash-odoo Date: Tue, 8 Aug 2023 17:00:16 +0530 Subject: [PATCH] [IMP] spreadsheet_edition: field matching for extend filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - When a new pivot is added, and if the user has already defined field matching in a previous pivot, the new pivot will inherit the field matching from the previous pivot as default values. - If multiple pivots are added from different models, will check the model of the new pivot against previous pivots. If the model matches, the field matching from the matching previous pivot will be used. If no matching model is found, the field matching will be left empty. - Same will also done in case of list and odoo chart. closes odoo/odoo#135841 Taskid: 3373163 Related: odoo/enterprise#47570 Signed-off-by: Lucas Lefèvre (lul) --- .../chart/plugins/odoo_chart_core_plugin.js | 8 ++- .../plugins/global_filters_core_plugin.js | 32 ++++++++++ .../src/list/plugins/list_core_plugin.js | 8 ++- .../src/pivot/plugins/pivot_core_plugin.js | 8 ++- .../global_filters_chart_test.js | 4 +- .../global_filters_model_test.js | 64 ++++++++++++++++++- 6 files changed, 114 insertions(+), 10 deletions(-) diff --git a/addons/spreadsheet/static/src/chart/plugins/odoo_chart_core_plugin.js b/addons/spreadsheet/static/src/chart/plugins/odoo_chart_core_plugin.js index 9417805556f..2d7732e100c 100644 --- a/addons/spreadsheet/static/src/chart/plugins/odoo_chart_core_plugin.js +++ b/addons/spreadsheet/static/src/chart/plugins/odoo_chart_core_plugin.js @@ -21,7 +21,7 @@ export default class OdooChartCorePlugin extends CorePlugin { this.charts = {}; globalFiltersFieldMatchers["chart"] = { - geIds: () => this.getters.getOdooChartIds(), + getIds: () => this.getters.getOdooChartIds(), getDisplayName: (chartId) => this.getters.getOdooChartDisplayName(chartId), getFieldMatching: (chartId, filterId) => this.getOdooChartFieldMatching(chartId, filterId), @@ -184,8 +184,12 @@ export default class OdooChartCorePlugin extends CorePlugin { * @param {string} chartId * @param {Object} fieldMatching */ - _addOdooChart(chartId, fieldMatching = {}) { + _addOdooChart(chartId, fieldMatching = undefined) { const charts = { ...this.charts }; + if (!fieldMatching) { + const model = this.getters.getChartDefinition(chartId).metaData.resModel; + fieldMatching = this.getters.getFieldMatchingForModel(model); + } charts[chartId] = { fieldMatching, }; diff --git a/addons/spreadsheet/static/src/global_filters/plugins/global_filters_core_plugin.js b/addons/spreadsheet/static/src/global_filters/plugins/global_filters_core_plugin.js index 3918d294f1b..4088c555f9c 100644 --- a/addons/spreadsheet/static/src/global_filters/plugins/global_filters_core_plugin.js +++ b/addons/spreadsheet/static/src/global_filters/plugins/global_filters_core_plugin.js @@ -128,6 +128,37 @@ export class GlobalFiltersCorePlugin extends spreadsheet.CorePlugin { return this.getGlobalFilter(id).defaultValue; } + /** + * Returns the field matching for a given model by copying the matchings of another DataSource that + * share the same model, including only the chain and type. + */ + getFieldMatchingForModel(newModel) { + const globalFilters = this.getGlobalFilters(); + if (globalFilters.length === 0) { + return {}; + } + + for (const matcher of Object.values(globalFiltersFieldMatchers)) { + for (const dataSourceId of matcher.getIds()) { + const model = matcher.getModel(dataSourceId); + if (model === newModel) { + const fieldMatching = {}; + for (const filter of globalFilters) { + const matchedField = matcher.getFieldMatching(dataSourceId, filter.id); + if (matchedField) { + fieldMatching[filter.id] = { + chain: matchedField.chain, + type: matchedField.type, + }; + } + } + return fieldMatching; + } + } + } + return {}; + } + // --------------------------------------------------------------------- // Handlers // --------------------------------------------------------------------- @@ -231,4 +262,5 @@ GlobalFiltersCorePlugin.getters = [ "getGlobalFilters", "getGlobalFilterDefaultValue", "getGlobalFilterLabel", + "getFieldMatchingForModel", ]; 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 e423961d69f..39050c69df0 100644 --- a/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js +++ b/addons/spreadsheet/static/src/list/plugins/list_core_plugin.js @@ -39,7 +39,7 @@ export default class ListCorePlugin extends CorePlugin { this.lists = {}; globalFiltersFieldMatchers["list"] = { - geIds: () => this.getters.getListIds(), + getIds: () => this.getters.getListIds(), getDisplayName: (listId) => this.getters.getListName(listId), getTag: (listId) => sprintf(_t("List #%s"), listId), getFieldMatching: (listId, filterId) => this.getListFieldMatching(listId, filterId), @@ -241,8 +241,12 @@ export default class ListCorePlugin extends CorePlugin { } } - _addList(id, definition, fieldMatching = {}) { + _addList(id, definition, fieldMatching = undefined) { const lists = { ...this.lists }; + if (!fieldMatching) { + const model = definition.metaData.resModel; + fieldMatching = this.getters.getFieldMatchingForModel(model); + } lists[id] = { id, definition, diff --git a/addons/spreadsheet/static/src/pivot/plugins/pivot_core_plugin.js b/addons/spreadsheet/static/src/pivot/plugins/pivot_core_plugin.js index c03bcd4a317..b895e3a92ae 100644 --- a/addons/spreadsheet/static/src/pivot/plugins/pivot_core_plugin.js +++ b/addons/spreadsheet/static/src/pivot/plugins/pivot_core_plugin.js @@ -42,7 +42,7 @@ export default class PivotCorePlugin extends CorePlugin { /** @type {Object.} */ this.pivots = {}; globalFiltersFieldMatchers["pivot"] = { - geIds: () => this.getters.getPivotIds(), + getIds: () => this.getters.getPivotIds(), getDisplayName: (pivotId) => this.getters.getPivotName(pivotId), getTag: (pivotId) => sprintf(_t("Pivot #%s"), pivotId), getFieldMatching: (pivotId, filterId) => this.getPivotFieldMatching(pivotId, filterId), @@ -255,8 +255,12 @@ export default class PivotCorePlugin extends CorePlugin { * @param {PivotDefinition} definition * @param {string} dataSourceId */ - _addPivot(id, definition, fieldMatching = {}) { + _addPivot(id, definition, fieldMatching = undefined) { const pivots = { ...this.pivots }; + if (!fieldMatching) { + const model = definition.metaData.resModel; + fieldMatching = this.getters.getFieldMatchingForModel(model); + } pivots[id] = { id, definition, diff --git a/addons/spreadsheet/static/tests/global_filters/global_filters_chart_test.js b/addons/spreadsheet/static/tests/global_filters/global_filters_chart_test.js index c72d2c7f540..ce73b232da5 100644 --- a/addons/spreadsheet/static/tests/global_filters/global_filters_chart_test.js +++ b/addons/spreadsheet/static/tests/global_filters/global_filters_chart_test.js @@ -88,14 +88,14 @@ QUnit.module("spreadsheet > Global filters chart", {}, () => { id: chartId, }); assert.deepEqual( - globalFiltersFieldMatchers["chart"].geIds(), + globalFiltersFieldMatchers["chart"].getIds(), [], "it should have removed the chart and its fieldMatching and datasource altogether" ); model.dispatch("REQUEST_UNDO"); assert.deepEqual(model.getters.getChartFieldMatch(chartId)[filter.id], matching); model.dispatch("REQUEST_REDO"); - assert.deepEqual(globalFiltersFieldMatchers["chart"].geIds(), []); + assert.deepEqual(globalFiltersFieldMatchers["chart"].getIds(), []); }); QUnit.test("field matching is removed when filter is deleted", async function (assert) { diff --git a/addons/spreadsheet/static/tests/global_filters/global_filters_model_test.js b/addons/spreadsheet/static/tests/global_filters/global_filters_model_test.js index 0f6b019549f..bc63eb79085 100644 --- a/addons/spreadsheet/static/tests/global_filters/global_filters_model_test.js +++ b/addons/spreadsheet/static/tests/global_filters/global_filters_model_test.js @@ -7,6 +7,7 @@ import { createModelWithDataSource, waitForDataSourcesLoaded, } from "@spreadsheet/../tests/utils/model"; +import { getBasicPivotArch } from "@spreadsheet/../tests/utils/data"; import { createSpreadsheetWithPivotAndList } from "@spreadsheet/../tests/utils/pivot_list"; import { THIS_YEAR_GLOBAL_FILTER } from "@spreadsheet/../tests/utils/global_filter"; @@ -18,12 +19,18 @@ import { setCellContent, setGlobalFilterValue, } from "@spreadsheet/../tests/utils/commands"; -import { createSpreadsheetWithPivot } from "@spreadsheet/../tests/utils/pivot"; +import { + createSpreadsheetWithPivot, + insertPivotInSpreadsheet, +} from "@spreadsheet/../tests/utils/pivot"; import { createSpreadsheetWithChart, insertChartInSpreadsheet, } from "@spreadsheet/../tests/utils/chart"; -import { createSpreadsheetWithList } from "@spreadsheet/../tests/utils/list"; +import { + createSpreadsheetWithList, + insertListInSpreadsheet, +} from "@spreadsheet/../tests/utils/list"; import { FILTER_DATE_OPTION } from "@spreadsheet/assets_backend/constants"; import { RELATIVE_DATE_RANGE_TYPES } from "@spreadsheet/helpers/constants"; import { @@ -195,6 +202,59 @@ QUnit.module("spreadsheet > Global filters model", {}, () => { assert.deepEqual(result, DispatchResult.Success); }); + QUnit.test( + "Adding new DataSource will set its fieldMatching according to other ones with the same model", + async function (assert) { + const { model } = await createSpreadsheetWithPivot(); + await addGlobalFilter(model, THIS_YEAR_GLOBAL_FILTER, { + pivot: { + 1: { chain: "created_on", type: "date", offset: 1 }, + }, + }); + const filterId = THIS_YEAR_GLOBAL_FILTER.filter.id; + + let fieldMatching = model.getters.getPivotFieldMatching("1", filterId); + assert.equal(fieldMatching.chain, "created_on"); + assert.equal(fieldMatching.type, "date"); + assert.equal(fieldMatching.offset, 1); + + await insertPivotInSpreadsheet(model, { arch: getBasicPivotArch() }); + fieldMatching = model.getters.getPivotFieldMatching("2", filterId); + assert.equal(fieldMatching.chain, "created_on"); + assert.equal(fieldMatching.type, "date"); + assert.equal(fieldMatching.offset, undefined); + + insertListInSpreadsheet(model, { model: "partner", columns: ["foo"] }); + fieldMatching = model.getters.getListFieldMatching("1", filterId); + assert.equal(fieldMatching.chain, "created_on"); + assert.equal(fieldMatching.type, "date"); + assert.equal(fieldMatching.offset, undefined); + + insertChartInSpreadsheet(model); + const chartId = model.getters.getOdooChartIds()[0]; + fieldMatching = model.getters.getOdooChartFieldMatching(chartId, filterId); + assert.equal(fieldMatching.chain, "created_on"); + assert.equal(fieldMatching.type, "date"); + assert.equal(fieldMatching.offset, undefined); + } + ); + + QUnit.test( + "Adding new DataSource with a different model won't set up its field matching", + async function (assert) { + const { model } = await createSpreadsheetWithPivot(); + await addGlobalFilter(model, THIS_YEAR_GLOBAL_FILTER, { + pivot: { + 1: { chain: "created_on", type: "date", offset: 1 }, + }, + }); + const filterId = THIS_YEAR_GLOBAL_FILTER.filter.id; + + insertListInSpreadsheet(model, { model: "product", columns: ["name"] }); + const fieldMatching = model.getters.getListFieldMatching("1", filterId); + assert.deepEqual(fieldMatching, undefined); + } + ); QUnit.test("Can save a value to an existing global filter", async function (assert) { assert.expect(8);