[FIX] web: prevent command palette to lose focus
The command palette has the priority when useAutoFocus is call. Like that, the command palette will not lose focus when clicking on an app on the home menu and then directly opening the command palette before the app mounting TASK ID: 3338117 closes odoo/odoo#139124 X-original-commit: 660d27ac38c225559ea3697a24a34ac70ede8ec1 Signed-off-by: Florent Dardenne (dafl) <dafl@odoo.com>
This commit is contained in:
@@ -29,7 +29,7 @@ import { status, useComponent, useEffect, useRef, onWillUnmount } from "@odoo/ow
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Focus an element referenced by a t-ref="autofocus" in the current component
|
||||
* Focus an element referenced by a t-ref="autofocus" in the active component
|
||||
* as soon as it appears in the DOM and if it was not displayed before.
|
||||
* If it is an input/textarea, set the selection at the end.
|
||||
* @param {Object} [params]
|
||||
@@ -41,6 +41,8 @@ import { status, useComponent, useEffect, useRef, onWillUnmount } from "@odoo/ow
|
||||
export function useAutofocus({ refName, selectAll, mobile } = {}) {
|
||||
const comp = useComponent();
|
||||
const ref = useRef(refName || "autofocus");
|
||||
const uiService = useService("ui");
|
||||
|
||||
// Prevent autofocus in mobile
|
||||
if (!mobile && comp.env.isSmall) {
|
||||
return ref;
|
||||
@@ -52,7 +54,7 @@ export function useAutofocus({ refName, selectAll, mobile } = {}) {
|
||||
// LEGACY
|
||||
useEffect(
|
||||
(el) => {
|
||||
if (el) {
|
||||
if (el && (!uiService.activeElement || uiService.activeElement.contains(el))) {
|
||||
el.focus();
|
||||
if (["INPUT", "TEXTAREA"].includes(el.tagName) && el.type !== "number") {
|
||||
el.selectionEnd = el.value.length;
|
||||
|
||||
@@ -14,6 +14,9 @@ import { makeTestEnv } from "@web/../tests/helpers/mock_env";
|
||||
import { destroy, getFixture, makeDeferred, mount, nextTick } from "@web/../tests/helpers/utils";
|
||||
|
||||
import { Component, onMounted, useState, xml } from "@odoo/owl";
|
||||
import { dialogService } from "@web/core/dialog/dialog_service";
|
||||
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
|
||||
import { CommandPalette } from "@web/core/commands/command_palette";
|
||||
const serviceRegistry = registry.category("services");
|
||||
|
||||
QUnit.module("utils", () => {
|
||||
@@ -273,6 +276,45 @@ QUnit.module("utils", () => {
|
||||
assert.strictEqual(comp.inputRef.el.selectionEnd, 10);
|
||||
});
|
||||
|
||||
QUnit.test("useAutofocus: autofocus outside of active element doesn't work (CommandPalette)", async function (assert) {
|
||||
class MyComponent extends Component {
|
||||
setup() {
|
||||
this.inputRef = useAutofocus();
|
||||
}
|
||||
get OverlayContainer() {
|
||||
return registry.category("main_components").get("OverlayContainer");
|
||||
}
|
||||
}
|
||||
MyComponent.template = xml`
|
||||
<div>
|
||||
<input type="text" t-ref="autofocus" />
|
||||
<div class="o_dialog_container"/>
|
||||
<t t-component="OverlayContainer.Component" t-props="OverlayContainer.props" />
|
||||
</div>
|
||||
`;
|
||||
|
||||
registry.category("services").add("ui", uiService);
|
||||
registry.category("services").add("dialog", dialogService);
|
||||
registry.category("services").add("hotkey", hotkeyService);
|
||||
|
||||
const config = { providers: [] };
|
||||
const env = await makeTestEnv();
|
||||
const target = getFixture();
|
||||
const comp = await mount(MyComponent, target , { env });
|
||||
await nextTick();
|
||||
|
||||
assert.strictEqual(document.activeElement, comp.inputRef.el);
|
||||
|
||||
env.services.dialog.add(CommandPalette, { config });
|
||||
await nextTick();
|
||||
assert.containsOnce(target, ".o_command_palette");
|
||||
assert.notStrictEqual(document.activeElement, comp.inputRef.el);
|
||||
|
||||
comp.render();
|
||||
await nextTick();
|
||||
assert.notStrictEqual(document.activeElement, comp.inputRef.el);
|
||||
});
|
||||
|
||||
QUnit.module("useBus");
|
||||
|
||||
QUnit.test("useBus hook: simple usecase", async function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user