summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/models/channel_command/channel_command.js
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/models/channel_command/channel_command.js
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/models/channel_command/channel_command.js')
-rw-r--r--addons/mail/static/src/models/channel_command/channel_command.js96
1 files changed, 95 insertions, 1 deletions
diff --git a/addons/mail/static/src/models/channel_command/channel_command.js b/addons/mail/static/src/models/channel_command/channel_command.js
index 12054c1a35b..728acdb9eab 100644
--- a/addons/mail/static/src/models/channel_command/channel_command.js
+++ b/addons/mail/static/src/models/channel_command/channel_command.js
@@ -3,10 +3,104 @@ odoo.define('mail/static/src/models/channel_command/channel_command.js', functio
const { registerNewModel } = require('mail/static/src/model/model_core.js');
const { attr } = require('mail/static/src/model/model_field.js');
+const { cleanSearchTerm } = require('mail/static/src/utils/utils.js');
function factory(dependencies) {
- class ChannelCommand extends dependencies['mail.model'] {}
+ class ChannelCommand extends dependencies['mail.model'] {
+
+ /**
+ * Fetches channel commands matching the given search term to extend the
+ * JS knowledge and to update the suggestion list accordingly.
+ *
+ * In practice all channel commands are already fetched at init so this
+ * method does nothing.
+ *
+ * @static
+ * @param {string} searchTerm
+ * @param {Object} [options={}]
+ * @param {mail.thread} [options.thread] prioritize and/or restrict
+ * result in the context of given thread
+ */
+ static fetchSuggestions(searchTerm, { thread } = {}) {}
+
+ /**
+ * Returns a sort function to determine the order of display of channel
+ * commands in the suggestion list.
+ *
+ * @static
+ * @param {string} searchTerm
+ * @param {Object} [options={}]
+ * @param {mail.thread} [options.thread] prioritize result in the
+ * context of given thread
+ * @returns {function}
+ */
+ static getSuggestionSortFunction(searchTerm, { thread } = {}) {
+ const cleanedSearchTerm = cleanSearchTerm(searchTerm);
+ return (a, b) => {
+ const isATypeSpecific = a.channel_types;
+ const isBTypeSpecific = b.channel_types;
+ if (isATypeSpecific && !isBTypeSpecific) {
+ return -1;
+ }
+ if (!isATypeSpecific && isBTypeSpecific) {
+ return 1;
+ }
+ const cleanedAName = cleanSearchTerm(a.name || '');
+ const cleanedBName = cleanSearchTerm(b.name || '');
+ if (cleanedAName.startsWith(cleanedSearchTerm) && !cleanedBName.startsWith(cleanedSearchTerm)) {
+ return -1;
+ }
+ if (!cleanedAName.startsWith(cleanedSearchTerm) && cleanedBName.startsWith(cleanedSearchTerm)) {
+ return 1;
+ }
+ if (cleanedAName < cleanedBName) {
+ return -1;
+ }
+ if (cleanedAName > cleanedBName) {
+ return 1;
+ }
+ return a.id - b.id;
+ };
+ }
+
+ /**
+ * Returns channel commands that match the given search term.
+ *
+ * @static
+ * @param {string} searchTerm
+ * @param {Object} [options={}]
+ * @param {mail.thread} [options.thread] prioritize and/or restrict
+ * result in the context of given thread
+ * @returns {[mail.channel_command[], mail.channel_command[]]}
+ */
+ static searchSuggestions(searchTerm, { thread } = {}) {
+ if (thread.model !== 'mail.channel') {
+ // channel commands are channel specific
+ return [[]];
+ }
+ const cleanedSearchTerm = cleanSearchTerm(searchTerm);
+ return [this.env.messaging.commands.filter(command => {
+ if (!cleanSearchTerm(command.name).includes(cleanedSearchTerm)) {
+ return false;
+ }
+ if (command.channel_types) {
+ return command.channel_types.includes(thread.channel_type);
+ }
+ return true;
+ })];
+ }
+
+ /**
+ * Returns the text that identifies this channel command in a mention.
+ *
+ * @returns {string}
+ */
+ getMentionText() {
+ return this.name;
+ }
+
+ }
ChannelCommand.fields = {
/**