diff --git a/addons/web/static/src/views/sample_server.js b/addons/web/static/src/views/sample_server.js index f7610be125e..dc98d30501b 100644 --- a/addons/web/static/src/views/sample_server.js +++ b/addons/web/static/src/views/sample_server.js @@ -1,6 +1,12 @@ /** @odoo-module **/ -import { parseDate, serializeDate, serializeDateTime } from "@web/core/l10n/dates"; +import { + deserializeDate, + deserializeDateTime, + parseDate, + serializeDate, + serializeDateTime, +} from "@web/core/l10n/dates"; import { ORM } from "@web/core/orm_service"; import { registry } from "@web/core/registry"; import { groupBy as arrayGroupBy, sortBy as arraySortBy } from "@web/core/utils/arrays"; @@ -487,8 +493,21 @@ export class SampleServer { group[countKey] = records.length; const firstElem = records[0]; for (const gb of normalizedGroupBys) { - const { alias, fieldName } = gb; + const { alias, fieldName, type } = gb; group[alias] = this._formatValue(firstElem[fieldName], gb); + if (["date", "datetime"].includes(type)) { + group.__range = {}; + const val = firstElem[fieldName]; + if (val) { + const deserialize = type === "date" ? deserializeDate : deserializeDateTime; + const serialize = type === "date" ? serializeDate : serializeDateTime; + const from = deserialize(val).startOf(gb.interval); + const to = SampleServer.INTERVALS[gb.interval](from); + group.__range[alias] = { from: serialize(from), to: serialize(to) }; + } else { + group.__range[alias] = false; + } + } } Object.assign(group, this._aggregateFields(measures, records)); result.push(group); @@ -725,6 +744,13 @@ SampleServer.FORMATS = { quarter: "'Q'q yyyy", year: "y", }; +SampleServer.INTERVALS = { + day: (dt) => dt.plus({ days: 1 }), + week: (dt) => dt.plus({ weeks: 1 }), + month: (dt) => dt.plus({ months: 1 }), + quarter: (dt) => dt.plus({ months: 3 }), + year: (dt) => dt.plus({ years: 1 }), +}; SampleServer.DISPLAY_FORMATS = Object.assign({}, SampleServer.FORMATS, { day: "dd MMM yyyy" }); SampleServer.MAIN_RECORDSET_SIZE = 16; diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index 23903c2c110..5e93d99c72f 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -6951,6 +6951,27 @@ QUnit.module("Views", (hooks) => { assert.ok(document.activeElement.dataset.name === "foo"); }); + QUnit.test("empty list with sample data: group by date", async (assert) => { + await makeView({ + type: "list", + arch: ` + + + `, + serverData, + domain: Domain.FALSE.toList(), + resModel: "foo", + groupBy: ["date:day"], + }); + + assert.containsOnce(target, ".o_list_view .o_view_sample_data"); + const groupHeaders = [...target.querySelectorAll(".o_group_header")]; + assert.ok(groupHeaders.length); + + await click(target.querySelector(".o_group_has_content.o_group_header")); + assert.containsN(target, ".o_data_row", 4); + }); + QUnit.test("non empty list with sample data", async function (assert) { await makeView({ type: "list",