[IMP] web: add ctrl+enter shortcut to dialogs
This commit adds the ctrl+enter shortcut to dialogs which will trigger a click on the first visible button in the dialog's footer. Task-3369676 closes odoo/odoo#125330 Signed-off-by: Mathieu Duckerts-Antoine (dam) <dam@odoo.com>
This commit is contained in:
@@ -37,6 +37,22 @@ export class Dialog extends Component {
|
||||
useActiveElement("modalRef");
|
||||
this.data = useState(this.env.dialogData);
|
||||
useHotkey("escape", () => this.onEscape());
|
||||
useHotkey(
|
||||
"control+enter",
|
||||
() => {
|
||||
const btns = document.querySelectorAll(
|
||||
".o_dialog:not(.o_inactive_modal) .modal-footer button"
|
||||
);
|
||||
const firstVisibleBtn = Array.from(btns).find((btn) => {
|
||||
const styles = getComputedStyle(btn);
|
||||
return styles.display !== "none";
|
||||
});
|
||||
if (firstVisibleBtn) {
|
||||
firstVisibleBtn.click();
|
||||
}
|
||||
},
|
||||
{ bypassEditableProtection: true }
|
||||
);
|
||||
this.id = `dialog_${this.data.id}`;
|
||||
useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: () => this.data.close() });
|
||||
this.position = useState({ left: 0, top: 0 });
|
||||
@@ -84,7 +100,11 @@ Dialog.props = {
|
||||
fullscreen: { type: Boolean, optional: true },
|
||||
footer: { type: Boolean, optional: true },
|
||||
header: { type: Boolean, optional: true },
|
||||
size: { type: String, optional: true, validate: (s) => ["sm", "md", "lg", "xl", "fs"].includes(s) },
|
||||
size: {
|
||||
type: String,
|
||||
optional: true,
|
||||
validate: (s) => ["sm", "md", "lg", "xl", "fs"].includes(s),
|
||||
},
|
||||
technical: { type: Boolean, optional: true },
|
||||
title: { type: String, optional: true },
|
||||
modalRef: { type: Function, optional: true },
|
||||
|
||||
@@ -6,7 +6,15 @@ import { uiService } from "@web/core/ui/ui_service";
|
||||
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
import { makeTestEnv } from "../helpers/mock_env";
|
||||
import { click, destroy, getFixture, mount, triggerEvent, dragAndDrop } from "../helpers/utils";
|
||||
import {
|
||||
click,
|
||||
destroy,
|
||||
getFixture,
|
||||
mount,
|
||||
triggerEvent,
|
||||
triggerHotkey,
|
||||
dragAndDrop,
|
||||
} from "../helpers/utils";
|
||||
import { makeFakeDialogService } from "../helpers/mock_services";
|
||||
|
||||
import { Component, useState, onMounted, xml } from "@odoo/owl";
|
||||
@@ -71,6 +79,31 @@ QUnit.module("Components", (hooks) => {
|
||||
assert.strictEqual(target.querySelector("footer button").textContent, "Ok");
|
||||
});
|
||||
|
||||
QUnit.test("hotkeys work on dialogs", async function (assert) {
|
||||
class Parent extends Component {}
|
||||
Parent.components = { Dialog };
|
||||
Parent.template = xml`
|
||||
<Dialog title="'Wow(l) Effect'">
|
||||
Hello!
|
||||
</Dialog>
|
||||
`;
|
||||
|
||||
const env = await makeDialogTestEnv();
|
||||
env.dialogData.close = () => assert.step("close");
|
||||
parent = await mount(Parent, target, { env });
|
||||
assert.strictEqual(
|
||||
target.querySelector("header .modal-title").textContent,
|
||||
"Wow(l) Effect"
|
||||
);
|
||||
assert.strictEqual(target.querySelector("footer button").textContent, "Ok");
|
||||
// Same effect as clicking on the x button
|
||||
triggerHotkey("escape");
|
||||
assert.verifySteps(["close"]);
|
||||
// Same effect as clicking on the Ok button
|
||||
triggerHotkey("control+enter");
|
||||
assert.verifySteps(["close"]);
|
||||
});
|
||||
|
||||
QUnit.test("simple rendering with two dialogs", async function (assert) {
|
||||
assert.expect(3);
|
||||
class Parent extends Component {}
|
||||
|
||||
Reference in New Issue
Block a user