diff --git a/addons/hr_expense/__manifest__.py b/addons/hr_expense/__manifest__.py
index 9abed1f3607..1790889bc4e 100644
--- a/addons/hr_expense/__manifest__.py
+++ b/addons/hr_expense/__manifest__.py
@@ -71,6 +71,10 @@ This module also uses analytic accounting and is compatible with the invoice on
],
'web.qunit_suite_tests': [
'hr_expense/static/tests/**/*.js',
+ ('remove', 'hr_expense/static/tests/mobile/**/*.js'),
+ ],
+ 'web.qunit_mobile_suite_tests': [
+ 'hr_expense/static/tests/mobile/**/*.js',
],
},
'license': 'LGPL-3',
diff --git a/addons/hr_expense/static/src/scss/hr_expense.scss b/addons/hr_expense/static/src/scss/hr_expense.scss
index 5f7e36d72e4..8997dcead30 100644
--- a/addons/hr_expense/static/src/scss/hr_expense.scss
+++ b/addons/hr_expense/static/src/scss/hr_expense.scss
@@ -28,6 +28,13 @@
max-height: 100%;
}
}
+
+.o_expense_container {
+ @include media-breakpoint-down(sm) {
+ overflow: auto visible;
+ }
+}
+
.o_dropzone {
width: 100%;
height: 100%;
diff --git a/addons/hr_expense/static/tests/mobile/expense_mobile_tests.js b/addons/hr_expense/static/tests/mobile/expense_mobile_tests.js
new file mode 100644
index 00000000000..00c83c61bfb
--- /dev/null
+++ b/addons/hr_expense/static/tests/mobile/expense_mobile_tests.js
@@ -0,0 +1,84 @@
+/** @odoo-module **/
+
+import { registerCleanup } from "@web/../tests/helpers/cleanup";
+import { getFixture, nextTick } from "@web/../tests/helpers/utils";
+import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
+
+import { registry } from "@web/core/registry";
+import { makeFakeHTTPService } from "@web/../tests/helpers/mock_services";
+
+const serviceRegistry = registry.category("services");
+
+let target;
+let serverData;
+
+QUnit.module("Expense", (hooks) => {
+ hooks.beforeEach(() => {
+ serviceRegistry.add("http", makeFakeHTTPService());
+ target = getFixture();
+ serverData = {
+ models: {
+ partner: {
+ fields: {
+ display_name: { string: "Displayed name", type: "char" },
+ },
+ },
+ },
+ };
+ });
+
+ QUnit.test("expense dashboard can horizontally scroll", async function (assert) {
+ // for this test, we need the elements to be visible in the viewport
+ target = document.body;
+ target.classList.add("debug");
+ registerCleanup(() => target.classList.remove("debug"));
+
+ serverData.views = {
+ "partner,false,search": ``,
+ "partner,false,list": `
+
+
+
+ `,
+ };
+
+ const webclient = await createWebClient({
+ serverData,
+ target,
+ async mockRPC(_, { method }) {
+ if (method === "get_expense_dashboard") {
+ return {
+ draft: {
+ description: "to report",
+ amount: 1000000000.00,
+ currency: 2,
+ },
+ reported: {
+ description: "under validation",
+ amount: 1000000000.00,
+ currency: 2,
+ },
+ approved: {
+ description: "to be reimbursed",
+ amount: 1000000000.00,
+ currency: 2,
+ },
+ };
+ }
+ },
+ });
+ await doAction(webclient, {
+ res_model: "partner",
+ type: "ir.actions.act_window",
+ views: [[false, "list"]],
+ });
+ const statusBar = target.querySelector(".o_expense_container");
+ statusBar.scrollLeft = 20;
+ await nextTick();
+ assert.strictEqual(
+ statusBar.scrollLeft,
+ 20,
+ "the o_content should be 20 due to the overflow auto"
+ );
+ });
+});