[FIX] web: graph,pivot: favorite groupbys
Problem: Have a pivot view in some state. Toggle a favorite with a context in which a key "pivot_row_groupby" is defined. The pivot view should be grouped (on rows) by that pivot_row_groupby but it is not always the case. The basic problem is that the key "pivot_row_groupby" is never considered after the first load (see method load in pivot_model.js). Solution: We make the search model used by the pivot view send as groupby for the favorite its pivot_row_groupby instead of its groupBy (which can be different). We do something similar for the graph view that presents a similar problem. closes odoo/odoo#95688 Opw: 2837428 X-original-commit: ea9f66f99caaa6136912c467e5b80fe605586845 Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com> Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { SearchModel } from "@web/search/search_model";
|
||||
|
||||
export class GraphSearchModel extends SearchModel {
|
||||
_getIrFilterDescription() {
|
||||
this.preparingIrFilterDescription = true;
|
||||
const result = super._getIrFilterDescription(...arguments);
|
||||
this.preparingIrFilterDescription = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
_getSearchItemGroupBys(activeItem) {
|
||||
const { searchItemId } = activeItem;
|
||||
const { context, type } = this.searchItems[searchItemId];
|
||||
if (!this.preparingIrFilterDescription && type === "favorite" && context.graph_groupbys) {
|
||||
return context.graph_groupbys;
|
||||
}
|
||||
return super._getSearchItemGroupBys(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { GraphArchParser } from "./graph_arch_parser";
|
||||
import { GraphModel } from "./graph_model";
|
||||
import { GraphController } from "./graph_controller";
|
||||
import { GraphRenderer } from "./graph_renderer";
|
||||
import { GraphSearchModel } from "./graph_search_model";
|
||||
|
||||
const viewRegistry = registry.category("views");
|
||||
|
||||
@@ -18,6 +19,7 @@ export const graphView = {
|
||||
Renderer: GraphRenderer,
|
||||
Model: GraphModel,
|
||||
ArchParser: GraphArchParser,
|
||||
SearchModel: GraphSearchModel,
|
||||
searchMenuTypes: ["filter", "groupBy", "comparison", "favorite"],
|
||||
buttonTemplate: "web.GraphView.Buttons",
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { SearchModel } from "@web/search/search_model";
|
||||
|
||||
export class PivotSearchModel extends SearchModel {
|
||||
_getIrFilterDescription() {
|
||||
this.preparingIrFilterDescription = true;
|
||||
const result = super._getIrFilterDescription(...arguments);
|
||||
this.preparingIrFilterDescription = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
_getSearchItemGroupBys(activeItem) {
|
||||
const { searchItemId } = activeItem;
|
||||
const { context, type } = this.searchItems[searchItemId];
|
||||
if (
|
||||
!this.preparingIrFilterDescription &&
|
||||
type === "favorite" &&
|
||||
context.pivot_row_groupby
|
||||
) {
|
||||
return context.pivot_row_groupby;
|
||||
}
|
||||
return super._getSearchItemGroupBys(...arguments);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { PivotArchParser } from "@web/views/pivot/pivot_arch_parser";
|
||||
import { PivotController } from "./pivot_controller";
|
||||
import { PivotModel } from "@web/views/pivot/pivot_model";
|
||||
import { PivotRenderer } from "@web/views/pivot/pivot_renderer";
|
||||
import { PivotSearchModel } from "./pivot_search_model";
|
||||
|
||||
const viewRegistry = registry.category("views");
|
||||
|
||||
@@ -18,6 +19,7 @@ export const pivotView = {
|
||||
Renderer: PivotRenderer,
|
||||
Model: PivotModel,
|
||||
ArchParser: PivotArchParser,
|
||||
SearchModel: PivotSearchModel,
|
||||
searchMenuTypes: ["filter", "groupBy", "comparison", "favorite"],
|
||||
buttonTemplate: "web.PivotView.Buttons",
|
||||
|
||||
|
||||
@@ -3676,4 +3676,43 @@ QUnit.module("Views", (hooks) => {
|
||||
});
|
||||
checkLabels(assert, graph, ["January 2016", "March 2016", "May 2016", "April 2016"]);
|
||||
});
|
||||
|
||||
QUnit.test("graph_groupbys should be also used after first load", async function (assert) {
|
||||
const graph = await makeView({
|
||||
serverData,
|
||||
type: "graph",
|
||||
resModel: "foo",
|
||||
groupBy: ["date:quarter"],
|
||||
arch: `<graph/>`,
|
||||
irFilters: [
|
||||
{
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
name: "Favorite",
|
||||
id: 1,
|
||||
context: `{
|
||||
"group_by": [],
|
||||
"graph_measure": "revenue",
|
||||
"graph_mode": "bar",
|
||||
"graph_groupbys": ["color_id"],
|
||||
}`,
|
||||
sort: "[]",
|
||||
domain: "",
|
||||
is_default: false,
|
||||
model_id: "foo",
|
||||
action_id: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
checkModeIs(assert, graph, "bar");
|
||||
checkLabels(assert, graph, ["Q1 2016", "Q2 2016", "Undefined"]);
|
||||
checkLegend(assert, graph, "Count");
|
||||
|
||||
await toggleFavoriteMenu(target);
|
||||
await toggleMenuItem(target, "Favorite");
|
||||
|
||||
checkModeIs(assert, graph, "bar");
|
||||
checkLabels(assert, graph, ["Undefined", "red"]);
|
||||
checkLegend(assert, graph, "Revenue");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5383,4 +5383,164 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.strictEqual(getCurrentValues(target), values.join());
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("pivot_row_groupby should be also used after first load", async function (assert) {
|
||||
const ids = [1, 2];
|
||||
const expectedContexts = [
|
||||
{
|
||||
group_by: ["bar"],
|
||||
pivot_column_groupby: [],
|
||||
pivot_measures: ["__count"],
|
||||
pivot_row_groupby: ["product_id"],
|
||||
},
|
||||
{
|
||||
group_by: ["bar", "customer"],
|
||||
pivot_column_groupby: [],
|
||||
pivot_measures: ["__count"],
|
||||
pivot_row_groupby: ["customer"],
|
||||
},
|
||||
];
|
||||
|
||||
await makeView({
|
||||
type: "pivot",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `<pivot/>`,
|
||||
searchViewArch: `
|
||||
<search>
|
||||
<filter name='product_id' string="Product" context="{'group_by':'product_id'}"/>
|
||||
<filter name='customer' string="Customer" context="{'group_by':'customer'}"/>
|
||||
</search>
|
||||
`,
|
||||
groupBy: ["bar"],
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "create_or_replace") {
|
||||
assert.deepEqual(args.args[0].context, expectedContexts.shift());
|
||||
return ids.shift();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "No", "Yes"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await click(target.querySelector("tbody th")); // click on row header "Total"
|
||||
await click(target.querySelector("tbody th")); // click on row header "Total"
|
||||
await click(target.querySelector("tbody .o_group_by_menu .o_menu_item")); // select "Product"
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "xphone", "xpad"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await toggleFavoriteMenu(target);
|
||||
await toggleSaveFavorite(target);
|
||||
await editFavoriteName(target, "Favorite");
|
||||
await saveFavorite(target);
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "xphone", "xpad"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await removeFacet(target);
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "No", "Yes"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await toggleFavoriteMenu(target);
|
||||
await toggleMenuItem(target, "Favorite");
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "xphone", "xpad"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await toggleGroupByMenu(target);
|
||||
await toggleMenuItem(target, "Customer");
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "xphone", "First", "xpad", "First", "Second"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await click(target.querySelector("tbody th")); // click on row header "Total"
|
||||
await click(target.querySelector("tbody th")); // click on row header "Total"
|
||||
await click(target.querySelectorAll("tbody .o_group_by_menu .o_menu_item")[1]); // select "Customer"
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "First", "Second"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await toggleFavoriteMenu(target);
|
||||
await toggleSaveFavorite(target);
|
||||
await editFavoriteName(target, "Favorite 2");
|
||||
await saveFavorite(target);
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "First", "Second"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"pivot_row_groupby should be also used after first load (2)",
|
||||
async function (assert) {
|
||||
await makeView({
|
||||
serverData,
|
||||
type: "pivot",
|
||||
resModel: "partner",
|
||||
groupBy: ["product_id"],
|
||||
arch: `<pivot/>`,
|
||||
irFilters: [
|
||||
{
|
||||
user_id: [2, "Mitchell Admin"],
|
||||
name: "Favorite",
|
||||
id: 1,
|
||||
context: `
|
||||
{
|
||||
"group_by": [],
|
||||
"pivot_row_groupby": ["customer"],
|
||||
"pivot_col_groupby": [],
|
||||
"pivot_measures": ["foo"],
|
||||
}
|
||||
`,
|
||||
sort: "[]",
|
||||
domain: "",
|
||||
is_default: false,
|
||||
model_id: "foo",
|
||||
action_id: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "xphone", "xpad"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
|
||||
await toggleFavoriteMenu(target);
|
||||
await toggleMenuItem(target, "Favorite");
|
||||
|
||||
assert.deepEqual(
|
||||
[...target.querySelectorAll("th")].slice(3).map((el) => el.innerText),
|
||||
["Total", "First", "Second"],
|
||||
"The row headers should be as expected"
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user