diff --git a/addons/mail/static/src/composer/composer.js b/addons/mail/static/src/composer/composer.js
index 0cca26d5663..4e107c2d594 100644
--- a/addons/mail/static/src/composer/composer.js
+++ b/addons/mail/static/src/composer/composer.js
@@ -100,6 +100,7 @@ export class Composer extends Component {
},
});
this.suggestion = this.store.user ? useSuggestion() : undefined;
+ this.markEventHandled = markEventHandled;
if (this.props.dropzoneRef && this.allowUpload) {
useDropzone(
this.props.dropzoneRef,
diff --git a/addons/mail/static/src/composer/composer.xml b/addons/mail/static/src/composer/composer.xml
index c3707c915f1..b48e4290a4c 100644
--- a/addons/mail/static/src/composer/composer.xml
+++ b/addons/mail/static/src/composer/composer.xml
@@ -41,6 +41,7 @@
t-on-input="onInput"
t-on-focusin="onFocusin"
t-on-focusout="() => this.props.composer.isFocused = false"
+ t-on-click="(ev) => markEventHandled(ev, 'composer.onClickTextarea')"
t-on-paste="onPaste"
t-model="props.composer.textInputContent"
t-att-placeholder="placeholder"
diff --git a/addons/mail/static/src/composer/navigable_list.js b/addons/mail/static/src/composer/navigable_list.js
index d91a523a69b..178cfe320a2 100644
--- a/addons/mail/static/src/composer/navigable_list.js
+++ b/addons/mail/static/src/composer/navigable_list.js
@@ -13,7 +13,8 @@ import {
useRef,
useState,
} from "@odoo/owl";
-import { markEventHandled } from "../utils/misc";
+import { markEventHandled, isEventHandled } from "../utils/misc";
+import { onExternalClick } from "@mail/utils/hooks";
export class NavigableList extends Component {
static components = { ImStatus };
@@ -41,6 +42,17 @@ export class NavigableList extends Component {
this.hotkeysToRemove = [];
useExternalListener(window, "keydown", this.onKeydown, true);
+ onExternalClick("root", async (ev) => {
+ // Let event be handled by bubbling handlers first.
+ await new Promise(setTimeout);
+ if (
+ isEventHandled(ev, "composer.onClickTextarea") ||
+ isEventHandled(ev, "channelSelector.onClickInput")
+ ) {
+ return;
+ }
+ this.close();
+ });
// position and size
usePosition(() => this.props.anchorRef, {
popper: "root",
@@ -72,6 +84,9 @@ export class NavigableList extends Component {
}
open() {
+ if (this.state.isLoading) {
+ return;
+ }
this.load().then(() => {
this.state.open = true;
this.navigate("first");
diff --git a/addons/mail/static/src/composer/navigable_list.xml b/addons/mail/static/src/composer/navigable_list.xml
index 8a2488cc62f..2b359c18544 100644
--- a/addons/mail/static/src/composer/navigable_list.xml
+++ b/addons/mail/static/src/composer/navigable_list.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/addons/mail/static/src/discuss/channel_selector.js b/addons/mail/static/src/discuss/channel_selector.js
index 918c68481f9..dffe1083b1d 100644
--- a/addons/mail/static/src/discuss/channel_selector.js
+++ b/addons/mail/static/src/discuss/channel_selector.js
@@ -7,7 +7,7 @@ import { useService } from "@web/core/utils/hooks";
import { getActiveHotkey } from "@web/core/hotkeys/hotkey_service";
import { Component, onMounted, useRef, useState } from "@odoo/owl";
import { cleanTerm } from "@mail/utils/format";
-import { createLocalId, isEventHandled } from "@mail/utils/misc";
+import { createLocalId, isEventHandled, markEventHandled } from "@mail/utils/misc";
import { _t } from "@web/core/l10n/translation";
export class ChannelSelector extends Component {
@@ -30,10 +30,11 @@ export class ChannelSelector extends Component {
if (this.props.autofocus) {
onMounted(() => this.inputRef.el.focus());
}
+ this.markEventHandled = markEventHandled;
}
- async fetchSuggestions(term) {
- const cleanedTerm = cleanTerm(term);
+ async fetchSuggestions() {
+ const cleanedTerm = cleanTerm(this.state.value);
if (cleanedTerm) {
if (this.props.category.id === "channels") {
const domain = [
@@ -79,6 +80,13 @@ export class ChannelSelector extends Component {
partner: this.store.self,
});
}
+ if (suggestions.length === 0) {
+ suggestions.push({
+ classList: "o-mail-ChannelSelector-suggestion",
+ label: _t("No results found"),
+ unselectable: true,
+ });
+ }
return suggestions;
}
}
@@ -184,7 +192,7 @@ export class ChannelSelector extends Component {
this.props.category.id === "channels"
? "mail.ChannelSelector.channel"
: "mail.ChannelSelector.chat",
- options: this.fetchSuggestions(this.state.value),
+ options: this.fetchSuggestions(),
};
}
}
diff --git a/addons/mail/static/src/discuss/channel_selector.xml b/addons/mail/static/src/discuss/channel_selector.xml
index b5402c14dee..5fe427a168a 100644
--- a/addons/mail/static/src/discuss/channel_selector.xml
+++ b/addons/mail/static/src/discuss/channel_selector.xml
@@ -9,6 +9,7 @@
t-att-placeholder="inputPlaceholder"
t-model="state.value"
t-ref="input"
+ t-on-click="(ev) => markEventHandled(ev, 'channelSelector.onClickInput')"
t-on-keydown="onKeydownInput"
type="text"
/>
diff --git a/addons/mail/static/src/web/messaging_menu/messaging_menu.xml b/addons/mail/static/src/web/messaging_menu/messaging_menu.xml
index cbacc052b6b..7fd189f9348 100644
--- a/addons/mail/static/src/web/messaging_menu/messaging_menu.xml
+++ b/addons/mail/static/src/web/messaging_menu/messaging_menu.xml
@@ -34,7 +34,7 @@
-