From 5124feae97b2bb29d08a2de1ec87da1f54481205 Mon Sep 17 00:00:00 2001 From: luvi Date: Mon, 31 Jul 2023 21:20:21 +0200 Subject: [PATCH] [IMP] web, *: improve UX of custom group by menu *: board, website This commit simplifies the UX of the 'Custom Group by' menu. Before this commit, many clicks were needed to apply another filter, from an accordion menu. Now, a select element is used instead, allowing a better user experience, by enabling such group by directly, when an option is selected. Some tests have been adapted to the new selectors and behaviors, and the applyGroup and toggleAddCustomGroup has been removed, since groups are applied when selected, and the value can be modified directly with selectGroup. task-3458519 closes odoo/odoo#132006 Signed-off-by: Mathieu Duckerts-Antoine (dam) --- .../static/tests/add_to_dashboard_tests.js | 6 +- .../src/core/select_menu/select_menu.scss | 4 +- .../custom_group_by_item.js | 18 +-- .../custom_group_by_item.scss | 4 + .../custom_group_by_item.xml | 26 ++-- .../search/custom_group_by_item_tests.js | 88 +++++--------- addons/web/static/tests/search/helpers.js | 15 +-- .../static/tests/views/pivot_view_tests.js | 113 +++--------------- .../static/tests/tours/page_manager.js | 8 +- 9 files changed, 78 insertions(+), 204 deletions(-) create mode 100644 addons/web/static/src/search/custom_group_by_item/custom_group_by_item.scss diff --git a/addons/board/static/tests/add_to_dashboard_tests.js b/addons/board/static/tests/add_to_dashboard_tests.js index 95dbcdc4827..d0e77fa3046 100644 --- a/addons/board/static/tests/add_to_dashboard_tests.js +++ b/addons/board/static/tests/add_to_dashboard_tests.js @@ -10,14 +10,13 @@ import { triggerEvent, } from "@web/../tests/helpers/utils"; import { - applyGroup, openAddCustomFilterDialog, removeFacet, switchView, - toggleAddCustomGroup, toggleSearchBarMenu, toggleMenuItem, toggleMenuItemOption, + selectGroup, } from "@web/../tests/search/helpers"; import { createWebClient, doAction } from "@web/../tests/webclient/helpers"; import { browser } from "@web/core/browser/browser"; @@ -140,8 +139,7 @@ QUnit.module("Board", (hooks) => { // Group It await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "foo"); // add this action to dashboard await testUtils.dom.triggerEvent($(".o_add_to_board button.dropdown-toggle"), "mouseenter"); diff --git a/addons/web/static/src/core/select_menu/select_menu.scss b/addons/web/static/src/core/select_menu/select_menu.scss index e88fb227452..edff948688b 100644 --- a/addons/web/static/src/core/select_menu/select_menu.scss +++ b/addons/web/static/src/core/select_menu/select_menu.scss @@ -66,10 +66,8 @@ .dropup .o_select_menu_menu { box-shadow: 0 -7px 10px rgba(8, 8, 8, 0.319); - border-bottom: none; } .dropdown .o_select_menu_menu { box-shadow: 0 7px 10px rgba(8, 8, 8, 0.319); - border-top: none; -} \ No newline at end of file +} diff --git a/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.js b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.js index 0e328ba4927..1c2244207fa 100644 --- a/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.js +++ b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.js @@ -1,20 +1,22 @@ /** @odoo-module **/ -import { AccordionItem } from "@web/core/dropdown/accordion_item"; - -import { Component, useState } from "@odoo/owl"; +import { Component } from "@odoo/owl"; export class CustomGroupByItem extends Component { - setup() { - this.state = useState({}); - if (this.props.fields.length) { - this.state.fieldName = this.props.fields[0].name; + get choices() { + return this.props.fields.map((f) => ({ label: f.string, value: f.name })); + } + + onSelected(ev) { + if (ev.target.value) { + this.props.onAddCustomGroup(ev.target.value); + // reset the placeholder + ev.target.value = ""; } } } CustomGroupByItem.template = "web.CustomGroupByItem"; -CustomGroupByItem.components = { AccordionItem }; CustomGroupByItem.props = { fields: Array, onAddCustomGroup: Function, diff --git a/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.scss b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.scss new file mode 100644 index 00000000000..42419f31b04 --- /dev/null +++ b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.scss @@ -0,0 +1,4 @@ +.o_add_custom_group_menu { + background-position-x: calc(100% - 0.6em); + border: 0 !important; +} diff --git a/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.xml b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.xml index 313b7d74374..577c976df2b 100644 --- a/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.xml +++ b/addons/web/static/src/search/custom_group_by_item/custom_group_by_item.xml @@ -1,24 +1,14 @@ - -
- -
-
- -
-
+
diff --git a/addons/web/static/tests/search/custom_group_by_item_tests.js b/addons/web/static/tests/search/custom_group_by_item_tests.js index fd1b70a04f5..bae61915631 100644 --- a/addons/web/static/tests/search/custom_group_by_item_tests.js +++ b/addons/web/static/tests/search/custom_group_by_item_tests.js @@ -1,15 +1,14 @@ /** @odoo-module **/ import { browser } from "@web/core/browser/browser"; -import { getFixture, patchWithCleanup } from "../helpers/utils"; +import { getFixture, getNodesTextContent, patchWithCleanup } from "../helpers/utils"; import { - applyGroup, getFacetTexts, isItemSelected, isOptionSelected, makeWithSearch, + selectGroup, setupControlPanelServiceRegistry, - toggleAddCustomGroup, toggleMenuItem, toggleSearchBarMenu, } from "./helpers"; @@ -47,7 +46,7 @@ QUnit.module("Search", (hooks) => { QUnit.module("CustomGroupByItem"); QUnit.test("simple rendering", async function (assert) { - assert.expect(5); + assert.expect(2); await makeWithSearch({ serverData, @@ -61,23 +60,13 @@ QUnit.module("Search", (hooks) => { const groupByMenu = target.querySelector(".o_group_by_menu"); assert.strictEqual( - groupByMenu.querySelector(".o_accordion").innerText.trim(), + groupByMenu.querySelector(".o_group_by_menu option[disabled]").innerText.trim(), "Add Custom Group" ); - - assert.containsOnce(groupByMenu, "button"); - assert.containsNone(groupByMenu, ".o_accordion_values"); - - await toggleAddCustomGroup(target); - - assert.containsOnce(groupByMenu, ".o_accordion_values"); - assert.deepEqual( - [ - ...target.querySelectorAll( - ".o_add_custom_group_menu + .o_accordion_values select option" - ), - ].map((el) => el.innerText), + getNodesTextContent( + target.querySelectorAll(".o_add_custom_group_menu option:not([disabled])") + ), ["Birthday", "Date", "Foo"] ); }); @@ -100,16 +89,10 @@ QUnit.module("Search", (hooks) => { }); await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - - assert.deepEqual( - [ - ...target.querySelectorAll( - ".o_add_custom_group_menu + .o_accordion_values select option" - ), - ].map((el) => el.innerText), - ["Foo"] - ); + const optionDescriptions = [ + ...target.querySelectorAll(".o_add_custom_group_menu option:not([disabled])"), + ].map((option) => option.innerText.trim()); + assert.deepEqual(optionDescriptions, ["Foo"]); } ); @@ -136,16 +119,10 @@ QUnit.module("Search", (hooks) => { }); await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - - assert.deepEqual( - [ - ...target.querySelectorAll( - ".o_add_custom_group_menu + .o_accordion_values select option" - ), - ].map((el) => el.innerText), - ["Char A", "M2M Stored"] - ); + const optionDescriptions = [ + ...target.querySelectorAll(".o_add_custom_group_menu option:not([disabled])"), + ].map((option) => option.innerText.trim()); + assert.deepEqual(optionDescriptions, ["Char A", "M2M Stored"]); } ); @@ -168,10 +145,9 @@ QUnit.module("Search", (hooks) => { await toggleSearchBarMenu(target); assert.deepEqual(controlPanel.env.searchModel.groupBy, []); - assert.containsOnce(target, ".o_menu_item"); //Add Custom Group + assert.containsOnce(target, ".o_add_custom_group_menu"); //Add Custom Group - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "date_field"); assert.deepEqual(controlPanel.env.searchModel.groupBy, ["date_field:month"]); assert.deepEqual(getFacetTexts(target), ["Date: Month"]); @@ -184,7 +160,7 @@ QUnit.module("Search", (hooks) => { ); QUnit.test("click on add custom group toggle group selector", async function (assert) { - assert.expect(4); + assert.expect(3); await makeWithSearch({ serverData, @@ -200,27 +176,23 @@ QUnit.module("Search", (hooks) => { const addCustomGroupMenu = target.querySelector(".o_add_custom_group_menu"); - assert.strictEqual(addCustomGroupMenu.innerText.trim(), "Add Custom Group"); - - await toggleAddCustomGroup(target); - - // Single select node with a single option - assert.containsOnce(target, ".o_add_custom_group_menu + .o_accordion_values select"); assert.strictEqual( - target - .querySelector(".o_add_custom_group_menu + .o_accordion_values select option") - .innerText.trim(), - "Super Date" + addCustomGroupMenu.querySelector("option[disabled]").innerText.trim(), + "Add Custom Group" ); - // Button apply - assert.containsOnce(target, ".o_add_custom_group_menu + .o_accordion_values .btn"); + // Single select node with a single option + assert.containsOnce(target, ".o_add_custom_group_menu option:not([disabled])"); + assert.deepEqual( + target.querySelector(".o_add_custom_group_menu option:not([disabled])").textContent, + "Super Date" + ); }); QUnit.test( "select a field name in Add Custom Group menu properly trigger the corresponding field", async function (assert) { - assert.expect(4); + assert.expect(3); await makeWithSearch({ serverData, @@ -237,12 +209,10 @@ QUnit.module("Search", (hooks) => { }); await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "candle_light"); assert.containsN(target, ".o_group_by_menu .o_menu_item", 2); - assert.containsOnce(target, ".o_add_custom_group_menu.o_accordion_toggle"); - assert.containsOnce(target, ".o_add_custom_group_menu + .o_accordion_values"); + assert.containsOnce(target, ".o_add_custom_group_menu"); assert.deepEqual(getFacetTexts(target), ["Candlelight"]); } ); diff --git a/addons/web/static/tests/search/helpers.js b/addons/web/static/tests/search/helpers.js index d43438bd1b0..7c4d3b8d4f4 100644 --- a/addons/web/static/tests/search/helpers.js +++ b/addons/web/static/tests/search/helpers.js @@ -280,25 +280,14 @@ export async function toggleGroupByMenu(el) { await click(findItem(el, `.o_group_by_menu .dropdown-toggle`)); } -export async function toggleAddCustomGroup(el) { - await click(findItem(el, `.o_add_custom_group_menu`)); -} - export async function selectGroup(el, fieldName) { - const select = findItem(el, `.o_add_custom_group_menu + .o_accordion_values select`); - select.value = fieldName; - await triggerEvent(select, null, "change"); -} - -export async function applyGroup(el) { - await click(findItem(el, `.o_add_custom_group_menu + .o_accordion_values .btn`)); + el.querySelector(".o_add_custom_group_menu").value = fieldName; + await triggerEvent(el, ".o_add_custom_group_menu", "change"); } export async function groupByMenu(el, fieldName) { await toggleSearchBarMenu(el); - await toggleAddCustomGroup(el); await selectGroup(el, fieldName); - await applyGroup(el); } /** Favorite menu */ diff --git a/addons/web/static/tests/views/pivot_view_tests.js b/addons/web/static/tests/views/pivot_view_tests.js index e744a3fe4c9..e7d628325f0 100644 --- a/addons/web/static/tests/views/pivot_view_tests.js +++ b/addons/web/static/tests/views/pivot_view_tests.js @@ -11,12 +11,11 @@ import { nextTick, patchDate, patchWithCleanup, - triggerEvent, triggerEvents, mouseEnter, + getNodesTextContent, } from "../helpers/utils"; import { - applyGroup, editFavoriteName, getFacetTexts, removeFacet, @@ -24,7 +23,6 @@ import { selectGroup, setupControlPanelFavoriteMenuRegistry, setupControlPanelServiceRegistry, - toggleAddCustomGroup, toggleSearchBarMenu, toggleMenu, toggleMenuItem, @@ -1010,7 +1008,7 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, ".o_pivot .dropdown-menu"); assert.strictEqual( target.querySelector(".o_pivot .dropdown-menu").innerText.replace(/\s/g, ""), - "CompanyTypeCustomerDateOtherProductProductbarAddCustomGroup" + "CompanyTypeCustomerDateOtherProductProductbarAddCustomGroupCompanyTypeCustomerDateOtherProductProductbar" ); // open the Date sub dropdown @@ -1160,8 +1158,8 @@ QUnit.module("Views", (hooks) => { assert.containsN( target, ".dropdown-menu > .dropdown-item", - 3, - "should have 3 dropdown items same as searchview groupby" + 4, + "should have 4 dropdown items same as searchview groupby" ); assert.containsOnce( target, @@ -1169,15 +1167,14 @@ QUnit.module("Views", (hooks) => { "should have custom group generator same as searchview groupby" ); // check custom groupby selection has groupable fields only - await click(target, ".o_add_custom_group_menu"); assert.containsN( target, - ".o_add_custom_group_menu + .o_accordion_values option", + ".o_add_custom_group_menu option:not([disabled])", 6, "should have 6 fields in custom groupby" ); const optionDescriptions = [ - ...target.querySelectorAll(".o_add_custom_group_menu + .o_accordion_values option"), + ...target.querySelectorAll(".o_add_custom_group_menu option:not([disabled])"), ].map((option) => option.innerText.trim()); assert.deepEqual( optionDescriptions, @@ -1219,13 +1216,12 @@ QUnit.module("Views", (hooks) => { target, ".dropdown-menu .o_menu_item", 3, - "should have 2 menu items in pivot groupby" + "should have 3 menu items in pivot groupby" ); // add a custom group in searchview groupby await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "company_type"); assert.containsN( target, ".o_control_panel .o_cp_searchview .dropdown-menu .o_menu_item", @@ -1237,19 +1233,11 @@ QUnit.module("Views", (hooks) => { target, ".dropdown-menu .o_menu_item", 3, - "should still have 2 menu items in pivot groupby" + "should still have 3 menu items in pivot groupby" ); // add a custom group in pivot groupby - await click(target, ".o_add_custom_group_menu"); - target.querySelector(".o_add_custom_group_menu + .o_accordion_values select").value = - "date"; - await triggerEvent( - target, - ".o_add_custom_group_menu + .o_accordion_values select", - "change" - ); - await click(target, ".o_add_custom_group_menu + .o_accordion_values .btn"); + await selectGroup(target, "date"); // click on closed header to open groupby selection dropdown await click(target, "tbody tr:last-child .o_pivot_header_cell_closed"); assert.containsN( @@ -1296,8 +1284,7 @@ QUnit.module("Views", (hooks) => { 5, "should have 5 menu items in searchview" ); - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "company_type"); assert.containsN( target, ".o_control_panel .o_cp_searchview .dropdown-menu .o_menu_item", @@ -1307,11 +1294,8 @@ QUnit.module("Views", (hooks) => { // click on closed header to open dropdown await click(target.querySelectorAll("tbody .o_pivot_header_cell_closed")[1]); - let items = target.querySelectorAll(".o_menu_item:not(.o_accordion_toggle)"); - assert.deepEqual( - [...items].map((it) => it.innerText), - ["bar", "product"] - ); + let items = target.querySelectorAll(".o_menu_item:not(select)"); + assert.deepEqual(getNodesTextContent(items), ["bar", "product"]); assert.containsOnce( target, "tbody .dropdown-menu .dropdown-divider", @@ -1324,22 +1308,10 @@ QUnit.module("Views", (hooks) => { ); // add a custom group in pivot groupby - await click(target, ".o_add_custom_group_menu"); - target.querySelector(".o_add_custom_group_menu + .o_accordion_values select").value = - "customer"; - await triggerEvent( - target, - ".o_add_custom_group_menu + .o_accordion_values select", - "change" - ); - await click(target, ".o_add_custom_group_menu + .o_accordion_values .btn"); - + await selectGroup(target, "customer"); await click(target.querySelectorAll("tbody .o_pivot_header_cell_closed")[1]); - items = target.querySelectorAll(".o_menu_item:not(.o_accordion_toggle)"); - assert.deepEqual( - [...items].map((it) => it.innerText), - ["bar", "product", "Customer"] - ); + items = target.querySelectorAll(".o_menu_item:not(select)"); + assert.deepEqual(getNodesTextContent(items), ["bar", "product", "Customer"]); assert.containsN( target, "tbody .dropdown-menu .dropdown-divider", @@ -1392,17 +1364,9 @@ QUnit.module("Views", (hooks) => { // click on closed header to open dropdown and apply groupby on date field await click(target.querySelector("thead .o_pivot_header_cell_closed")); - await click(target.querySelector("thead .dropdown-menu .o_add_custom_group_menu ")); checkReadGroup = true; - const select = target.querySelector( - ".o_add_custom_group_menu + .o_accordion_values select" - ); - select.value = "date"; - select.dispatchEvent(new Event("change")); - await click( - target.querySelector(".o_add_custom_group_menu + .o_accordion_values .btn-primary") - ); + await selectGroup(target, "date"); } ); @@ -1518,42 +1482,6 @@ QUnit.module("Views", (hooks) => { } ); - QUnit.test( - "pivot custom groupby: adding a custom group close the pivot groupby menu", - async function (assert) { - assert.expect(3); - - await makeView({ - type: "pivot", - resModel: "partner", - serverData, - arch: ` - - - - `, - searchViewArch: ` - - - `, - }); - - // click on closed header to open dropdown - await click(target.querySelector("thead .o_pivot_header_cell_closed")); - assert.containsOnce(target, "thead .dropdown-menu .o_add_custom_group_menu"); - await click(target.querySelector("thead .dropdown-menu .o_add_custom_group_menu")); - assert.containsOnce(target, "thead .dropdown-menu .o_add_custom_group_menu"); - - // click on apply button should close dropdown - await click( - target.querySelector( - "thead .dropdown-menu .o_add_custom_group_menu + .o_accordion_values .btn-primary" - ) - ); - assert.containsNone(target, "thead .dropdown-menu"); - } - ); - QUnit.test("can toggle extra measure", async function (assert) { let rpcCount = 0; await makeView({ @@ -4477,8 +4405,7 @@ QUnit.module("Views", (hooks) => { // open group by menu and add new groupby await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); - await applyGroup(target); + await selectGroup(target, "company_type"); assert.deepEqual( [...target.querySelectorAll("thead th")].map((th) => th.innerText), @@ -4508,9 +4435,7 @@ QUnit.module("Views", (hooks) => { // open groupby menu generator and add a new groupby await toggleSearchBarMenu(target); - await toggleAddCustomGroup(target); await selectGroup(target, "bar"); - await applyGroup(target); assert.deepEqual( [...target.querySelectorAll("thead th")].map((th) => th.innerText), @@ -5449,7 +5374,7 @@ QUnit.module("Views", (hooks) => { "The row headers should be as expected" ); - await toggleMenuItem(target, "Customer"); + await toggleMenuItem(target, "customer"); assert.deepEqual( [...target.querySelectorAll("th")].slice(3).map((el) => el.innerText), diff --git a/addons/website/static/tests/tours/page_manager.js b/addons/website/static/tests/tours/page_manager.js index 12e557c89fd..7134c071fa4 100644 --- a/addons/website/static/tests/tours/page_manager.js +++ b/addons/website/static/tests/tours/page_manager.js @@ -11,11 +11,9 @@ const checkKanbanGroupBy = [{ extra_trigger: '.o_kanban_renderer', trigger: '.o_control_panel .o_searchview_dropdown_toggler', }, { - content: "Click on Add Custom Group", - trigger: '.o_add_custom_group_menu', -}, { - content: "Click on Apply", // Active is selected by default - trigger: '.o_add_custom_group_menu + .o_accordion_values .btn-primary', + content: "Select 'Active' in the select of Add Custom Group", + trigger: ".o_add_custom_group_menu", + run: "text active", }, { content: "Click on List View", extra_trigger: '.o_kanban_renderer .o_kanban_header',