mirror of
https://github.com/OCA/web.git
synced 2025-02-22 13:21:25 +02:00
124 lines
3.6 KiB
JavaScript
124 lines
3.6 KiB
JavaScript
/** @odoo-module **/
|
|
/* Copyright 2018 Tecnativa - Jairo Llopis
|
|
* Copyright 2021 ITerra - Sergey Shebanin
|
|
* Copyright 2023 Onestein - Anjeel Haria
|
|
* Copyright 2023 Taras Shabaranskyi
|
|
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
|
|
|
|
import {Component, useState} from "@odoo/owl";
|
|
import {session} from "@web/session";
|
|
import {useBus, useService} from "@web/core/utils/hooks";
|
|
import {AppMenuItem} from "@web_responsive/components/apps_menu_item/apps_menu_item.esm";
|
|
import {AppsMenuSearchBar} from "@web_responsive/components/menu_searchbar/searchbar.esm";
|
|
import {NavBar} from "@web/webclient/navbar/navbar";
|
|
import {WebClient} from "@web/webclient/webclient";
|
|
import {patch} from "@web/core/utils/patch";
|
|
import {useHotkey} from "@web/core/hotkeys/hotkey_hook";
|
|
|
|
// Patch WebClient to show AppsMenu instead of default app
|
|
patch(WebClient.prototype, {
|
|
setup() {
|
|
super.setup();
|
|
useBus(this.env.bus, "APPS_MENU:STATE_CHANGED", ({detail: state}) => {
|
|
document.body.classList.toggle("o_apps_menu_opened", state);
|
|
});
|
|
},
|
|
});
|
|
|
|
export class AppsMenu extends Component {
|
|
setup() {
|
|
super.setup();
|
|
this.state = useState({open: false});
|
|
this.theme = session.apps_menu.theme || "milk";
|
|
this.menuService = useService("menu");
|
|
useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => {
|
|
this.setOpenState(false);
|
|
});
|
|
this._setupKeyNavigation();
|
|
}
|
|
|
|
setOpenState(open_state) {
|
|
this.state.open = open_state;
|
|
this.env.bus.trigger("APPS_MENU:STATE_CHANGED", open_state);
|
|
}
|
|
|
|
/**
|
|
* Setup navigation among app menus
|
|
*/
|
|
_setupKeyNavigation() {
|
|
const repeatable = {
|
|
allowRepeat: true,
|
|
};
|
|
useHotkey(
|
|
"ArrowRight",
|
|
() => {
|
|
this._onWindowKeydown("next");
|
|
},
|
|
repeatable
|
|
);
|
|
useHotkey(
|
|
"ArrowLeft",
|
|
() => {
|
|
this._onWindowKeydown("prev");
|
|
},
|
|
repeatable
|
|
);
|
|
useHotkey(
|
|
"ArrowDown",
|
|
() => {
|
|
this._onWindowKeydown("next");
|
|
},
|
|
repeatable
|
|
);
|
|
useHotkey(
|
|
"ArrowUp",
|
|
() => {
|
|
this._onWindowKeydown("prev");
|
|
},
|
|
repeatable
|
|
);
|
|
useHotkey("Escape", () => {
|
|
this.env.bus.trigger("ACTION_MANAGER:UI-UPDATED");
|
|
});
|
|
}
|
|
|
|
_onWindowKeydown(direction) {
|
|
const focusableInputElements = document.querySelectorAll(".o-app-menu-item");
|
|
if (focusableInputElements.length) {
|
|
const focusable = [...focusableInputElements];
|
|
const index = focusable.indexOf(document.activeElement);
|
|
let nextIndex = 0;
|
|
if (direction === "prev" && index >= 0) {
|
|
if (index > 0) {
|
|
nextIndex = index - 1;
|
|
} else {
|
|
nextIndex = focusable.length - 1;
|
|
}
|
|
} else if (direction === "next") {
|
|
if (index + 1 < focusable.length) {
|
|
nextIndex = index + 1;
|
|
} else {
|
|
nextIndex = 0;
|
|
}
|
|
}
|
|
focusableInputElements[nextIndex].focus();
|
|
}
|
|
}
|
|
|
|
onMenuClick() {
|
|
this.setOpenState(!this.state.open);
|
|
}
|
|
}
|
|
|
|
Object.assign(AppsMenu, {
|
|
template: "web_responsive.AppsMenu",
|
|
props: {
|
|
slots: {
|
|
type: Object,
|
|
optional: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
Object.assign(NavBar.components, {AppsMenu, AppMenuItem, AppsMenuSearchBar});
|