summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/components
diff options
context:
space:
mode:
authorXavier Dubuc <xdu@odoo.com>2021-03-10 16:45:49 +0000
committerSébastien Theys <seb@odoo.com>2021-03-10 16:48:19 +0000
commitfbdec5fe29827b88ec0d1421f68716e1febefd89 (patch)
treeafbbc6fd6da16ace2af4c2992678657b814d0197 /addons/mail/static/src/components
parentf326ba2d14e4fdd811426c6381b7e5bc3c1d657b (diff)
[FIX] mail; hr: restore faster and more accurate mention suggestions
The code from v13 used to look for partners in JS before making the RPC, which was much faster, and also gave better results by returning partners that were already known and therefore more likely to be selected. The same logic is reintroduced here, and further improved to take into account all known partners and sort them according to the likeliness they will be selected based on various criteria. task-2413776 closes odoo/odoo#64161 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com> Co-authored-by: Sébastien Theys <seb@odoo.com>
Diffstat (limited to 'addons/mail/static/src/components')
-rw-r--r--addons/mail/static/src/components/composer/composer_tests.js79
-rw-r--r--addons/mail/static/src/components/composer_suggestion/composer_suggestion.js4
-rw-r--r--addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.js16
-rw-r--r--addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.xml6
-rw-r--r--addons/mail/static/src/components/composer_text_input/composer_text_input.js9
-rw-r--r--addons/mail/static/src/components/composer_text_input/composer_text_input.xml2
-rw-r--r--addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml2
-rw-r--r--addons/mail/static/src/components/thread_view/thread_view_tests.js1
8 files changed, 26 insertions, 93 deletions
diff --git a/addons/mail/static/src/components/composer/composer_tests.js b/addons/mail/static/src/components/composer/composer_tests.js
index 98f969438eb..77a4f2adb4c 100644
--- a/addons/mail/static/src/components/composer/composer_tests.js
+++ b/addons/mail/static/src/components/composer/composer_tests.js
@@ -333,8 +333,6 @@ QUnit.test('use a canned response', async function (assert) {
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, ":");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -387,10 +385,8 @@ QUnit.test('use a canned response some text', async function (assert) {
"bluhbluh ",
"text content of composer should have content"
);
- await afterNextRender(() =>
- document.execCommand('insertText', false, ":")
- );
await afterNextRender(() => {
+ document.execCommand('insertText', false, ":");
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -437,8 +433,6 @@ QUnit.test('add an emoji after a canned response', async function (assert) {
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, ":");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -531,8 +525,6 @@ QUnit.test('mention a channel', async function (assert) {
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, "#");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -584,10 +576,8 @@ QUnit.test('mention a channel after some text', async function (assert) {
"bluhbluh ",
"text content of composer should have content"
);
- await afterNextRender(() =>
- document.execCommand('insertText', false, "#")
- );
await afterNextRender(() => {
+ document.execCommand('insertText', false, "#");
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -633,8 +623,6 @@ QUnit.test('add an emoji after a channel mention', async function (assert) {
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, "#");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -739,8 +727,6 @@ QUnit.test('use a command for a specific channel type', async function (assert)
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, "/");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -828,10 +814,8 @@ QUnit.test('use a command after some text', async function (assert) {
"bluhbluh ",
"text content of composer should have content"
);
- await afterNextRender(() =>
- document.execCommand('insertText', false, "/")
- );
await afterNextRender(() => {
+ document.execCommand('insertText', false, "/");
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -883,8 +867,6 @@ QUnit.test('add an emoji after a command', async function (assert) {
await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`).focus();
document.execCommand('insertText', false, "/");
- });
- await afterNextRender(() => {
document.querySelector(`.o_ComposerTextInput_textarea`)
.dispatchEvent(new window.KeyboardEvent('keydown'));
document.querySelector(`.o_ComposerTextInput_textarea`)
@@ -2041,61 +2023,6 @@ QUnit.test('send message only once when enter is pressed twice quickly', async f
);
});
-QUnit.test("mentioned partners should not be notified if they are not member of current channel", async function (assert) {
- assert.expect(4);
-
- this.data['res.partner'].records.push({
- email: "testpartner@example.com",
- name: "TestPartner",
- });
- this.data['mail.channel'].records.push({
- id: 10,
- members: [this.data.currentPartnerId],
- });
- await this.start({
- async mockRPC(route, args) {
- if (args.model === 'mail.channel' && args.method === 'message_post') {
- assert.step('message_post');
- assert.strictEqual(
- args.kwargs.partner_ids.length,
- 0,
- "message_post should not contain mentioned partners that are not members of channel"
- );
- }
- return this._super(...arguments);
- },
- });
- const thread = this.env.models['mail.thread'].findFromIdentifyingData({
- id: 10,
- model: 'mail.channel',
- });
- await this.createComposerComponent(thread.composer);
- await afterNextRender(() => {
- document.querySelector(`.o_ComposerTextInput_textarea`).focus();
- document.execCommand('insertText', false, "@");
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown'));
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keyup'));
- });
- await afterNextRender(() => {
- document.querySelector(`.o_ComposerTextInput_textarea`).focus();
- document.execCommand('insertText', false, "Test");
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown'));
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keyup'));
- });
- await afterNextRender(() => document.querySelector('.o_ComposerSuggestion').click());
- assert.strictEqual(
- document.querySelector(`.o_ComposerTextInput_textarea`).value.replace(/\s/, " "),
- "@TestPartner ",
- "text content of composer should have mentioned partner + additional whitespace afterwards"
- );
- await afterNextRender(() => document.querySelector('.o_Composer_buttonSend').click());
- assert.verifySteps(['message_post'], "the message should be posted");
-});
-
QUnit.test('[technical] does not crash when an attachment is removed before its upload starts', async function (assert) {
// Uploading multiple files uploads attachments one at a time, this test
// ensures that there is no crash when an attachment is destroyed before its
diff --git a/addons/mail/static/src/components/composer_suggestion/composer_suggestion.js b/addons/mail/static/src/components/composer_suggestion/composer_suggestion.js
index 4ae48db623b..da54ab54311 100644
--- a/addons/mail/static/src/components/composer_suggestion/composer_suggestion.js
+++ b/addons/mail/static/src/components/composer_suggestion/composer_suggestion.js
@@ -116,9 +116,7 @@ class ComposerSuggestion extends Component {
*/
_onClick(ev) {
ev.preventDefault();
- this.composer.update({
- [this.composer.activeSuggestedRecordName]: [['link', this.record]],
- });
+ this.composer.update({ activeSuggestedRecord: [['link', this.record]] });
this.composer.insertSuggestion();
this.composer.closeSuggestions();
this.trigger('o-composer-suggestion-clicked');
diff --git a/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.js b/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.js
index ea2153dbf6f..23f08399594 100644
--- a/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.js
+++ b/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.js
@@ -22,23 +22,23 @@ class ComposerSuggestionList extends Component {
const activeSuggestedRecord = composer
? composer.activeSuggestedRecord
: undefined;
- const extraSuggestedRecordsList = composer
- ? composer.extraSuggestedRecordsList
+ const extraSuggestedRecords = composer
+ ? composer.extraSuggestedRecords
: [];
- const mainSuggestedRecordsList = composer
- ? composer.mainSuggestedRecordsList
+ const mainSuggestedRecords = composer
+ ? composer.mainSuggestedRecords
: [];
return {
activeSuggestedRecord,
composer,
composerSuggestionModelName: composer && composer.suggestionModelName,
- extraSuggestedRecordsList: extraSuggestedRecordsList,
- mainSuggestedRecordsList: mainSuggestedRecordsList,
+ extraSuggestedRecords,
+ mainSuggestedRecords,
};
}, {
compareDepth: {
- extraSuggestedRecordsList: 1,
- mainSuggestedRecordsList: 1,
+ extraSuggestedRecords: 1,
+ mainSuggestedRecords: 1,
},
});
}
diff --git a/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.xml b/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.xml
index 8bcd87c2d07..9747109a994 100644
--- a/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.xml
+++ b/addons/mail/static/src/components/composer_suggestion_list/composer_suggestion_list.xml
@@ -5,7 +5,7 @@
<div class="o_ComposerSuggestionList" t-att-class="{ 'o-lowPosition': props.isBelow }">
<div class="o_ComposerSuggestionList_drop" t-att-class="{ 'dropdown': props.isBelow, 'dropup': !props.isBelow }">
<div class="o_ComposerSuggestionList_list dropdown-menu show">
- <t t-foreach="composer.mainSuggestedRecordsList" t-as="record" t-key="record.localId">
+ <t t-foreach="composer.mainSuggestedRecords" t-as="record" t-key="record.localId">
<ComposerSuggestion
composerLocalId="props.composerLocalId"
isActive="record === composer.activeSuggestedRecord"
@@ -13,10 +13,10 @@
recordLocalId="record.localId"
/>
</t>
- <t t-if="composer.mainSuggestedRecordsList.length > 0 and composer.extraSuggestedRecordsList.length > 0">
+ <t t-if="composer.mainSuggestedRecords.length > 0 and composer.extraSuggestedRecords.length > 0">
<div role="separator" class="dropdown-divider"/>
</t>
- <t t-foreach="composer.extraSuggestedRecordsList" t-as="record" t-key="record.localId">
+ <t t-foreach="composer.extraSuggestedRecords" t-as="record" t-key="record.localId">
<ComposerSuggestion
composerLocalId="props.composerLocalId"
isActive="record === composer.activeSuggestedRecord"
diff --git a/addons/mail/static/src/components/composer_text_input/composer_text_input.js b/addons/mail/static/src/components/composer_text_input/composer_text_input.js
index 6c0705ee40a..7c11c7f5790 100644
--- a/addons/mail/static/src/components/composer_text_input/composer_text_input.js
+++ b/addons/mail/static/src/components/composer_text_input/composer_text_input.js
@@ -195,6 +195,14 @@ class ComposerTextInput extends Component {
/**
* @private
*/
+ _onClickTextarea() {
+ // clicking might change the cursor position
+ this.saveStateInStore();
+ }
+
+ /**
+ * @private
+ */
_onFocusinTextarea() {
this.composer.focus();
this.trigger('o-focusin-composer');
@@ -372,7 +380,6 @@ class ComposerTextInput extends Component {
// Otherwise, check if a mention is typed
default:
this.saveStateInStore();
- this.composer.detectSuggestionDelimiter();
}
}
diff --git a/addons/mail/static/src/components/composer_text_input/composer_text_input.xml b/addons/mail/static/src/components/composer_text_input/composer_text_input.xml
index 5b120fabd90..a14fdee8712 100644
--- a/addons/mail/static/src/components/composer_text_input/composer_text_input.xml
+++ b/addons/mail/static/src/components/composer_text_input/composer_text_input.xml
@@ -10,7 +10,7 @@
isBelow="props.hasMentionSuggestionsBelowPosition"
/>
</t>
- <textarea class="o_ComposerTextInput_textarea o_ComposerTextInput_textareaStyle" t-att-class="{ 'o-composer-is-compact': props.isCompact }" t-esc="composer.textInputContent" t-att-placeholder="textareaPlaceholder" t-on-focusin="_onFocusinTextarea" t-on-focusout="_onFocusoutTextarea" t-on-keydown="_onKeydownTextarea" t-on-keyup="_onKeyupTextarea" t-on-input="_onInputTextarea" t-ref="textarea"/>
+ <textarea class="o_ComposerTextInput_textarea o_ComposerTextInput_textareaStyle" t-att-class="{ 'o-composer-is-compact': props.isCompact }" t-esc="composer.textInputContent" t-att-placeholder="textareaPlaceholder" t-on-click="_onClickTextarea" t-on-focusin="_onFocusinTextarea" t-on-focusout="_onFocusoutTextarea" t-on-keydown="_onKeydownTextarea" t-on-keyup="_onKeyupTextarea" t-on-input="_onInputTextarea" t-ref="textarea"/>
<!--
This is an invisible textarea used to compute the composer
height based on the text content. We need it to downsize
diff --git a/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml
index 9b52651f0c6..74aace2181b 100644
--- a/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml
+++ b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml
@@ -16,7 +16,7 @@
<div class="o_DiscussSidebarItem_item o_DiscussSidebarItem_name o-editable">
<EditableText
class="o_DiscussSidebarItem_nameInput"
- placeholder="thread.correspondent.name"
+ placeholder="thread.correspondent ? thread.correspondent.name : thread.name"
value="thread.displayName"
t-on-o-cancel="_onCancelRenaming"
t-on-o-clicked="_onClickedEditableText"
diff --git a/addons/mail/static/src/components/thread_view/thread_view_tests.js b/addons/mail/static/src/components/thread_view/thread_view_tests.js
index f436ddf582d..58a059890e3 100644
--- a/addons/mail/static/src/components/thread_view/thread_view_tests.js
+++ b/addons/mail/static/src/components/thread_view/thread_view_tests.js
@@ -1463,6 +1463,7 @@ QUnit.test('mention 2 different channels that have the same name', async functio
{
id: 11,
name: "my channel",
+ public: 'public', // mentioning another channel is possible only from a public channel
},
{
id: 12,