diff --git a/addons/web/static/src/views/list/list_arch_parser.js b/addons/web/static/src/views/list/list_arch_parser.js
index 218ca73c0fe..df3f7347e21 100644
--- a/addons/web/static/src/views/list/list_arch_parser.js
+++ b/addons/web/static/src/views/list/list_arch_parser.js
@@ -59,22 +59,25 @@ export class ListArchParser extends XMLParser {
buttonGroup = undefined;
}
if (node.tagName === "button") {
- const button = {
- ...processButton(node),
- defaultRank: "btn-link",
- type: "button",
- id: buttonId++,
- };
- if (buttonGroup) {
- buttonGroup.buttons.push(button);
- } else {
- buttonGroup = {
- id: `column_${nextId++}`,
- type: "button_group",
- buttons: [button],
- hasLabel: false,
+ const modifiers = JSON.parse(node.getAttribute("modifiers") || "{}");
+ if (modifiers.column_invisible !== true) {
+ const button = {
+ ...processButton(node),
+ defaultRank: "btn-link",
+ type: "button",
+ id: buttonId++,
};
- columns.push(buttonGroup);
+ if (buttonGroup) {
+ buttonGroup.buttons.push(button);
+ } else {
+ buttonGroup = {
+ id: `column_${nextId++}`,
+ type: "button_group",
+ buttons: [button],
+ hasLabel: false,
+ };
+ columns.push(buttonGroup);
+ }
}
} else if (node.tagName === "field") {
const fieldInfo = Field.parseFieldNode(node, models, modelName, "list");
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index 5bd3d430fa3..00caecbb162 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -290,7 +290,8 @@ export class MockServer {
const v = evaluateExpr(mod, context) ? true : false;
if (inTreeView && !inListHeader && attr === "invisible") {
modifiers.column_invisible = v;
- } else if (v || !(attr in modifiers) || !Array.isArray(modifiers[attr])) {
+ }
+ if (v || !(attr in modifiers) || !Array.isArray(modifiers[attr])) {
modifiers[attr] = v;
}
}
diff --git a/addons/web/static/tests/mock_server_tests.js b/addons/web/static/tests/mock_server_tests.js
index e0634083bd3..0264598b06e 100644
--- a/addons/web/static/tests/mock_server_tests.js
+++ b/addons/web/static/tests/mock_server_tests.js
@@ -922,4 +922,34 @@ QUnit.module("MockServer", (hooks) => {
mockServer.mockWrite("foo", [[2], { many2one_reference: false }]);
assert.deepEqual(mockServer.models.bar.records[0].one2many_field, []);
});
+ QUnit.test("List View: invisible on processed Arch", async function (assert) {
+ /**
+ * Note that, the server have two different responses for invisible:
+ * - if the invisible is in the arch (invisible=1), the parsed arch will contain:
+ * --"invisible=1" on the arch;
+ * -- "column_invisible: 1" on the modifiers.
+ * - if there is a group in the arch (groups=no_group), and that the user don't have access to the group, the parsed arch will contain:
+ * -- "invisible=1" on the arch;
+ * -- "column_invisible: 1" on the modifiers;
+ * -- "invisible: 1" on the modifiers.
+ * As it's possible (on the groups case) to have an invisible: 1 on the modifiers, on the mock_server we set it all the time.
+ */
+
+ data.views = {
+ "bar,10001,list": `
+
+
+
+
+ `,
+ "bar,10001,search": ``,
+ };
+ const expectedList = `
+
+
+ `;
+ const mockServer = new MockServer(data);
+ const { views } = mockServer.mockGetViews("bar", { views: [[10001, "list"]], options: {} });
+ assert.deepEqual(views.list.arch, expectedList);
+ });
});
diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js
index 6b228ea5af2..6952e390a28 100644
--- a/addons/web/static/tests/views/list_view_tests.js
+++ b/addons/web/static/tests/views/list_view_tests.js
@@ -485,29 +485,45 @@ QUnit.module("Views", (hooks) => {
assert.containsN(target.querySelector(".o_data_row:first-child"), "td.o_list_button", 2);
});
- QUnit.test("list view with adjacent buttons and invisible field", async function (assert) {
- await makeView({
- type: "list",
- resModel: "foo",
- serverData,
- arch: `
+ QUnit.test(
+ "list view with adjacent buttons and invisible field and button",
+ async function (assert) {
+ await makeView({
+ type: "list",
+ resModel: "foo",
+ serverData,
+ arch: `
+
+
`,
- });
+ });
- assert.containsN(
- target,
- "th",
- 3,
- "adjacent buttons in the arch must be grouped in a single column"
- );
- assert.containsN(target.querySelector(".o_data_row:first-child"), "td.o_list_button", 2);
- });
+ assert.containsN(
+ target,
+ "th",
+ 3,
+ "adjacent buttons in the arch must be grouped in a single column"
+ );
+ assert.containsN(
+ target,
+ "tr:first-child button",
+ 4,
+ "Only 4 buttons should be visible"
+ );
+ assert.containsN(
+ target.querySelector(".o_data_row:first-child"),
+ "td.o_list_button",
+ 2
+ );
+ }
+ );
QUnit.test(
"list view with adjacent buttons and invisible field (modifier)",