From 2ac5ceb7ffc0e45ad18ab875752b15d112be7648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Tue, 4 Jul 2023 10:45:40 +0000 Subject: [PATCH] [FIX] mail: keyboard navigation in chat window dropdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit, dropdowns in chat window (chat window more menu, message actions more menu) had no keyboard navigation support. This happens because dropdown item navigation makes use of hotkey service, and hotkey service intercepts keyboard in bubble phase on window object. `ChatWindow` component had a `t-on-keydown.stop` on its root node, which prevented the hotkey service to receive keyboard navigation for the good working of dropdown keyboard navigation. This commit removes the `.stop` modifier on this `t-on-keydown` root node of `ChatWindow` template. `onKeydown` in dropdown inside chat window have precedence over `onKeydown` on chat window: For example, when dropdown is open, hotkey "Escape" closes the dropdown menu but does not close the chat window. closes odoo/odoo#127318 X-original-commit: 4b36b28bd9e426b115ffefbbc174fe2efa3dfbf3 Signed-off-by: Sébastien Theys (seb) Signed-off-by: Alexandre Kühn (aku) --- .../static/src/core/common/chat_window.js | 3 ++ .../static/src/core/common/chat_window.xml | 2 +- .../tests/chat_window/chat_window_tests.js | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/core/common/chat_window.js b/addons/mail/static/src/core/common/chat_window.js index 805cce56518..6d7c2d4bd13 100644 --- a/addons/mail/static/src/core/common/chat_window.js +++ b/addons/mail/static/src/core/common/chat_window.js @@ -78,6 +78,9 @@ export class ChatWindow extends Component { } onKeydown(ev) { + if (ev.target.closest(".o-dropdown")) { + return; + } switch (ev.key) { case "Escape": if ( diff --git a/addons/mail/static/src/core/common/chat_window.xml b/addons/mail/static/src/core/common/chat_window.xml index 661b037b394..24859b7a496 100644 --- a/addons/mail/static/src/core/common/chat_window.xml +++ b/addons/mail/static/src/core/common/chat_window.xml @@ -10,7 +10,7 @@ 'position-absolute bottom-0 overflow-hidden d-flex flex-column': !props.chatWindow.hidden, 'rounded-top-3': !props.chatWindow.hidden and !ui.isSmall, }" - t-on-keydown.stop="onKeydown" + t-on-keydown="onKeydown" tabindex="1" >
diff --git a/addons/mail/static/tests/chat_window/chat_window_tests.js b/addons/mail/static/tests/chat_window/chat_window_tests.js index d6e203d7737..a84b803f61d 100644 --- a/addons/mail/static/tests/chat_window/chat_window_tests.js +++ b/addons/mail/static/tests/chat_window/chat_window_tests.js @@ -1023,3 +1023,56 @@ QUnit.test("Open chat window of new inviter", async (assert) => { ".o_notification:contains(Newbie connected. This is their first connection. Wish them luck.)" ); }); + +QUnit.test( + "keyboard navigation ArrowUp/ArrowDown on message action dropdown in chat window", + async (assert) => { + const pyEnv = await startServer(); + const channelId = pyEnv["discuss.channel"].create({ name: "General" }); + pyEnv["mail.message"].create({ + author_id: pyEnv.currentPartnerId, + body: "not empty", + model: "discuss.channel", + res_id: channelId, + }); + await start(); + await click(".o_menu_systray i[aria-label='Messages']"); + await click(".o-mail-NotificationItem"); + await afterNextRender(() => { + $(".o-mail-Message")[0].dispatchEvent(new window.MouseEvent("mouseenter")); + }); + await click(".o-mail-Message [title='Expand']"); + $(".o-mail-Message [title='Expand']")[0].focus(); // necessary otherwise focus is in composer input + assert.containsOnce($, ".o-mail-Message-moreMenu.dropdown-menu"); + await triggerHotkey("ArrowDown"); + assert.containsOnce($, ".o-mail-Message-moreMenu .dropdown-item:eq(0).focus"); + await triggerHotkey("ArrowDown"); + assert.containsOnce($, ".o-mail-Message-moreMenu .dropdown-item:eq(1).focus"); + } +); + +QUnit.test( + "Close dropdown in chat window with ESCAPE does not also close the chat window", + async (assert) => { + const pyEnv = await startServer(); + const channelId = pyEnv["discuss.channel"].create({ name: "General" }); + pyEnv["mail.message"].create({ + author_id: pyEnv.currentPartnerId, + body: "not empty", + model: "discuss.channel", + res_id: channelId, + }); + await start(); + await click(".o_menu_systray i[aria-label='Messages']"); + await click(".o-mail-NotificationItem"); + await afterNextRender(() => { + $(".o-mail-Message")[0].dispatchEvent(new window.MouseEvent("mouseenter")); + }); + await click(".o-mail-Message [title='Expand']"); + $(".o-mail-Message [title='Expand']")[0].focus(); // necessary otherwise focus is in composer input + assert.containsOnce($, ".o-mail-Message-moreMenu.dropdown-menu"); + await triggerHotkey("Escape"); + assert.containsNone($, ".o-mail-Message-moreMenu.dropdown-menu"); + assert.containsOnce($, ".o-mail-ChatWindow"); + } +);