[IMP] spreadsheet_edition: field matching for extend filters

- 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) <lul@odoo.com>
This commit is contained in:
jash-odoo
2023-09-21 23:54:23 +00:00
committed by Lucas Lefèvre (lul)
parent 20710a6850
commit 3911a69bbb
6 changed files with 114 additions and 10 deletions
@@ -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,
};
@@ -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",
];
@@ -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,
@@ -42,7 +42,7 @@ export default class PivotCorePlugin extends CorePlugin {
/** @type {Object.<string, Pivot>} */
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,
@@ -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) {
@@ -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);