[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.
pull/2301/head
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
* 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 {useAutofocus, useBus, useService} from "@web/core/utils/hooks";
import {useHotkey} from "@web/core/hotkeys/hotkey_hook";
@ -20,11 +19,9 @@ const {useState, useRef} = owl.hooks;
patch(WebClient.prototype, "web_responsive.DefaultAppsMenu", {
setup() {
this._super();
useBus(Dropdown.bus, "state-changed", (payload) => {
if (payload.emitter.el.classList.contains("o_navbar_apps_menu")) {
this.el.classList.toggle("o_apps_menu_opened", payload.newState.open);
this.el.classList.toggle("o_first_app", false);
}
useBus(this.env.bus, "APPS_MENU:STATE_CHANGED", (payload) => {
this.el.classList.toggle("o_apps_menu_opened", payload);
this.el.classList.toggle("o_first_app", false);
});
},
_loadDefaultApp() {
@ -41,11 +38,20 @@ patch(WebClient.prototype, "web_responsive.DefaultAppsMenu", {
/**
* @extends Dropdown
*/
export class AppsMenu extends Dropdown {
export class AppsMenu extends Component {
setup() {
super.setup();
useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => this.close());
useBus(this.env.bus, "APPS_MENU:CLOSE", () => this.close());
this.state = useState({open: false});
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({
results: [],
offset: 0,
hasResults: false,
});
useAutofocus({selector: "input"});
this.searchBarInput = useRef("SearchBarInput");
@ -152,10 +159,10 @@ export class AppsMenuSearchBar extends Component {
*/
_searchMenus() {
const query = this.searchBarInput.el.value;
this.state.results =
query === ""
? []
: fuzzyLookup(query, _.keys(this._searchableMenus), (k) => k);
this.state.hasResults = query !== "";
this.state.results = this.state.hasResults
? fuzzyLookup(query, _.keys(this._searchableMenus), (k) => k)
: [];
}
/**
@ -222,11 +229,14 @@ export class AppsMenuSearchBar extends Component {
const query = this.searchBarInput.el.value;
if (query) {
this.searchBarInput.el.value = "";
this.state.results = [];
this.state.hasResults = false;
} 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";
Object.assign(NavBar.components, {AppsMenu, AppsMenuSearchBar});

View File

@ -6,47 +6,59 @@
<t t-inherit="web.NavBar.AppsMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//Dropdown" position="replace">
<!-- Same hotkey as in EE -->
<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">
<AppsMenu>
<AppsMenuSearchBar />
<MenuItem
t-foreach="apps"
t-as="app"
t-key="app.id"
class="o_app"
t-att-class="{ o_dropdown_active: menuService.getCurrentApp() === app }"
payload="app"
>
<a t-att-href="getMenuItemHref(app)">
<img
class="o-app-icon"
draggable="false"
t-attf-src="data:image/png;base64,{{app.webIconData}}"
/>
<div t-esc="app.name" />
</a>
t-foreach="apps"
t-as="app"
t-key="app.id"
class="o_app"
t-att-class="{ o_dropdown_active: menuService.getCurrentApp() === app }"
payload="app"
>
<a t-att-href="getMenuItemHref(app)">
<img
class="o-app-icon"
draggable="false"
t-attf-src="data:image/png;base64,{{app.webIconData}}"
/>
<div t-esc="app.name" />
</a>
</MenuItem>
</t>
</AppsMenu>
</xpath>
</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 -->
<t t-name="web_responsive.AppsMenuSearchResults" owl="1">
<div
class="search-container"
t-att-class="state.results.length ? 'has-results' : ''"
t-att-class="state.hasResults ? 'has-results' : ''"
>
<div class="search-input">
<span class="fa fa-search search-icon" />
<input
<span class="fa fa-search search-icon" />
<input
type="search"
t-ref="SearchBarInput"
t-on-input="_searchMenus"
@ -54,6 +66,7 @@
autocomplete="off"
placeholder="Search menus..."
class="form-control"
data-allow-hotkeys="true"
/>
</div>
<div t-if="state.results.length" class="search-results">
@ -72,9 +85,4 @@
</div>
</div>
</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>