[FIX] web_responsive: make keyboard navigation in Apps menu Search results works again.

Due to changes in javascript framework keyboard navigation was broken.
This commit makes it work again.
This commit is contained in:
Sergey Shebanin
2022-09-25 23:18:36 +03:00
parent 06e6adad58
commit e656cea8ca
2 changed files with 66 additions and 48 deletions

View File

@@ -3,7 +3,6 @@
* Copyright 2021 ITerra - Sergey Shebanin * Copyright 2021 ITerra - Sergey Shebanin
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
import {Dropdown} from "@web/core/dropdown/dropdown";
import {NavBar} from "@web/webclient/navbar/navbar"; import {NavBar} from "@web/webclient/navbar/navbar";
import {useAutofocus, useBus, useService} from "@web/core/utils/hooks"; import {useAutofocus, useBus, useService} from "@web/core/utils/hooks";
import {useHotkey} from "@web/core/hotkeys/hotkey_hook"; import {useHotkey} from "@web/core/hotkeys/hotkey_hook";
@@ -20,11 +19,9 @@ const {useState, useRef} = owl.hooks;
patch(WebClient.prototype, "web_responsive.DefaultAppsMenu", { patch(WebClient.prototype, "web_responsive.DefaultAppsMenu", {
setup() { setup() {
this._super(); this._super();
useBus(Dropdown.bus, "state-changed", (payload) => { useBus(this.env.bus, "APPS_MENU:STATE_CHANGED", (payload) => {
if (payload.emitter.el.classList.contains("o_navbar_apps_menu")) { this.el.classList.toggle("o_apps_menu_opened", payload);
this.el.classList.toggle("o_apps_menu_opened", payload.newState.open);
this.el.classList.toggle("o_first_app", false); this.el.classList.toggle("o_first_app", false);
}
}); });
}, },
_loadDefaultApp() { _loadDefaultApp() {
@@ -41,11 +38,20 @@ patch(WebClient.prototype, "web_responsive.DefaultAppsMenu", {
/** /**
* @extends Dropdown * @extends Dropdown
*/ */
export class AppsMenu extends Dropdown { export class AppsMenu extends Component {
setup() { setup() {
super.setup(); super.setup();
useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => this.close()); this.state = useState({open: false});
useBus(this.env.bus, "APPS_MENU:CLOSE", () => this.close()); useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => {
this.setState(false);
});
useBus(this.env.bus, "APPS_MENU:CLOSE", () => {
this.setState(false);
});
}
setState(state) {
this.state.open = state;
this.env.bus.trigger("APPS_MENU:STATE_CHANGED", state);
} }
} }
@@ -110,6 +116,7 @@ export class AppsMenuSearchBar extends Component {
this.state = useState({ this.state = useState({
results: [], results: [],
offset: 0, offset: 0,
hasResults: false,
}); });
useAutofocus({selector: "input"}); useAutofocus({selector: "input"});
this.searchBarInput = useRef("SearchBarInput"); this.searchBarInput = useRef("SearchBarInput");
@@ -152,10 +159,10 @@ export class AppsMenuSearchBar extends Component {
*/ */
_searchMenus() { _searchMenus() {
const query = this.searchBarInput.el.value; const query = this.searchBarInput.el.value;
this.state.results = this.state.hasResults = query !== "";
query === "" this.state.results = this.state.hasResults
? [] ? fuzzyLookup(query, _.keys(this._searchableMenus), (k) => k)
: fuzzyLookup(query, _.keys(this._searchableMenus), (k) => k); : [];
} }
/** /**
@@ -222,11 +229,14 @@ export class AppsMenuSearchBar extends Component {
const query = this.searchBarInput.el.value; const query = this.searchBarInput.el.value;
if (query) { if (query) {
this.searchBarInput.el.value = ""; this.searchBarInput.el.value = "";
this.state.results = [];
this.state.hasResults = false;
} else { } else {
this.env.bus.trigger("APPS_MENU:CLOSE"); this.env.bus.trigger("ACTION_MANAGER:UI-UPDATED");
} }
} }
} }
} }
AppsMenu.template = "web_responsive.AppsMenu";
AppsMenuSearchBar.template = "web_responsive.AppsMenuSearchResults"; AppsMenuSearchBar.template = "web_responsive.AppsMenuSearchResults";
Object.assign(NavBar.components, {AppsMenu, AppsMenuSearchBar}); Object.assign(NavBar.components, {AppsMenu, AppsMenuSearchBar});

View File

@@ -6,16 +6,7 @@
<t t-inherit="web.NavBar.AppsMenu" t-inherit-mode="extension" owl="1"> <t t-inherit="web.NavBar.AppsMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//Dropdown" position="replace"> <xpath expr="//Dropdown" position="replace">
<!-- Same hotkey as in EE --> <!-- Same hotkey as in EE -->
<AppsMenu <AppsMenu>
hotkey="'a'"
title="'Home Menu'"
manualOnly="true"
class="o_navbar_apps_menu"
>
<t t-set-slot="toggler">
<i class="fa fa-th-large" />
</t>
<t t-transition="o_notification_fade">
<AppsMenuSearchBar /> <AppsMenuSearchBar />
<MenuItem <MenuItem
t-foreach="apps" t-foreach="apps"
@@ -34,15 +25,36 @@
<div t-esc="app.name" /> <div t-esc="app.name" />
</a> </a>
</MenuItem> </MenuItem>
</t>
</AppsMenu> </AppsMenu>
</xpath> </xpath>
</t> </t>
<!-- Apps menu -->
<t t-name="web_responsive.AppsMenu" owl="1">
<div class="o-dropdown dropdown o-dropdown--no-caret o_navbar_apps_menu">
<button
class="dropdown-toggle"
title="Home Menu"
data-hotkey="a"
t-on-click.stop="setState(!state.open)"
>
<i class="fa fa-th-large" />
</button>
<div
t-if="state.open"
class="dropdown-menu"
style="top: 46px; left: 0px;"
t-transition="fade"
>
<t t-slot="default" />
</div>
</div>
</t>
<!-- Search bar --> <!-- Search bar -->
<t t-name="web_responsive.AppsMenuSearchResults" owl="1"> <t t-name="web_responsive.AppsMenuSearchResults" owl="1">
<div <div
class="search-container" class="search-container"
t-att-class="state.results.length ? 'has-results' : ''" t-att-class="state.hasResults ? 'has-results' : ''"
> >
<div class="search-input"> <div class="search-input">
<span class="fa fa-search search-icon" /> <span class="fa fa-search search-icon" />
@@ -54,6 +66,7 @@
autocomplete="off" autocomplete="off"
placeholder="Search menus..." placeholder="Search menus..."
class="form-control" class="form-control"
data-allow-hotkeys="true"
/> />
</div> </div>
<div t-if="state.results.length" class="search-results"> <div t-if="state.results.length" class="search-results">
@@ -72,9 +85,4 @@
</div> </div>
</div> </div>
</t> </t>
<t t-inherit="web.Dropdown" t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('dropdown-menu')]" position="attributes">
<attribute name="t-transition">fade</attribute>
</xpath>
</t>
</templates> </templates>