From d5ed1069f055a3e81e21effbfc264fd2fd0ce97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Fri, 1 Jul 2022 09:42:07 +0000 Subject: [PATCH] [IMP] mail: introduce ComposerSuggestable model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow to remove AND/OR mix in identifying fields of composer suggestion view. Part of task-2741982 closes odoo/odoo#94999 Signed-off-by: Alexandre Kühn (aku) --- .../composer_suggestion.xml | 24 +++--- .../mail/static/src/models/canned_response.js | 10 ++- .../mail/static/src/models/channel_command.js | 10 ++- .../static/src/models/composer_suggestable.js | 31 ++++++++ .../static/src/models/composer_suggestion.js | 75 ++++++------------- .../mail/static/src/models/composer_view.js | 34 +++------ addons/mail/static/src/models/partner.js | 7 ++ .../src/models/persona_im_status_icon_view.js | 2 +- addons/mail/static/src/models/thread.js | 7 ++ 9 files changed, 109 insertions(+), 91 deletions(-) create mode 100644 addons/mail/static/src/models/composer_suggestable.js diff --git a/addons/mail/static/src/components/composer_suggestion/composer_suggestion.xml b/addons/mail/static/src/components/composer_suggestion/composer_suggestion.xml index 93729bf7cec..8ae506869c4 100644 --- a/addons/mail/static/src/components/composer_suggestion/composer_suggestion.xml +++ b/addons/mail/static/src/components/composer_suggestion/composer_suggestion.xml @@ -4,27 +4,27 @@ - - - + + + - - + + - - - + + + - + - - - () + + + () diff --git a/addons/mail/static/src/models/canned_response.js b/addons/mail/static/src/models/canned_response.js index cf9a146c05e..f0d3103288e 100644 --- a/addons/mail/static/src/models/canned_response.js +++ b/addons/mail/static/src/models/canned_response.js @@ -1,7 +1,8 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; +import { insertAndReplace } from '@mail/model/model_field_command'; import { cleanSearchTerm } from '@mail/utils/utils'; registerModel({ @@ -82,5 +83,12 @@ registerModel({ * entered. */ substitution: attr(), + suggestable: one('ComposerSuggestable', { + default: insertAndReplace(), + inverse: 'cannedResponse', + isCausal: true, + readonly: true, + required: true, + }), }, }); diff --git a/addons/mail/static/src/models/channel_command.js b/addons/mail/static/src/models/channel_command.js index 5cb777a94f6..e37cc8ffe1d 100644 --- a/addons/mail/static/src/models/channel_command.js +++ b/addons/mail/static/src/models/channel_command.js @@ -1,7 +1,8 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; +import { insertAndReplace } from '@mail/model/model_field_command'; import { cleanSearchTerm } from '@mail/utils/utils'; registerModel({ @@ -130,5 +131,12 @@ registerModel({ readonly: true, required: true, }), + suggestable: one('ComposerSuggestable', { + default: insertAndReplace(), + inverse: 'channelCommand', + isCausal: true, + readonly: true, + required: true, + }), }, }); diff --git a/addons/mail/static/src/models/composer_suggestable.js b/addons/mail/static/src/models/composer_suggestable.js new file mode 100644 index 00000000000..50fbb3bd6a3 --- /dev/null +++ b/addons/mail/static/src/models/composer_suggestable.js @@ -0,0 +1,31 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { many, one } from '@mail/model/model_field'; + +registerModel({ + name: 'ComposerSuggestable', + identifyingFields: [['cannedResponse', 'channelCommand', 'partner', 'thread']], + fields: { + cannedResponse: one('CannedResponse', { + inverse: 'suggestable', + readonly: true, + }), + channelCommand: one('ChannelCommand', { + inverse: 'suggestable', + readonly: true, + }), + composerSuggestions: many('ComposerSuggestion', { + inverse: 'suggestable', + isCausal: true, + }), + partner: one('Partner', { + inverse: 'suggestable', + readonly: true, + }), + thread: one('Thread', { + inverse: 'suggestable', + readonly: true, + }), + }, +}); diff --git a/addons/mail/static/src/models/composer_suggestion.js b/addons/mail/static/src/models/composer_suggestion.js index 83649f5ec52..b5b4587e62c 100644 --- a/addons/mail/static/src/models/composer_suggestion.js +++ b/addons/mail/static/src/models/composer_suggestion.js @@ -13,7 +13,7 @@ import { sprintf } from '@web/core/utils/strings'; */ registerModel({ name: 'ComposerSuggestion', - identifyingFields: [['composerViewOwnerAsExtraSuggestion', 'composerViewOwnerAsMainSuggestion'], ['cannedResponse', 'channelCommand', 'partner', 'thread']], + identifyingFields: [['composerViewOwnerAsExtraSuggestion', 'composerViewOwnerAsMainSuggestion'], 'suggestable'], recordMethods: { /** * @param {Event} ev @@ -53,17 +53,17 @@ registerModel({ * @returns {string} */ _computeMentionText() { - if (this.cannedResponse) { - return this.cannedResponse.substitution; + if (this.suggestable.cannedResponse) { + return this.suggestable.cannedResponse.substitution; } - if (this.channelCommand) { - return this.channelCommand.name; + if (this.suggestable.channelCommand) { + return this.suggestable.channelCommand.name; } - if (this.partner) { - return this.partner.name; + if (this.suggestable.partner) { + return this.suggestable.partner.name; } - if (this.thread) { - return this.thread.name; + if (this.suggestable.thread) { + return this.suggestable.thread.name; } }, /** @@ -71,57 +71,32 @@ registerModel({ * @returns {FieldCommand} */ _computePersonaImStatusIconView() { - return this.partner && this.partner.isImStatusSet ? insertAndReplace() : clear(); - }, - /** - * @private - * @returns {FieldCommand} - */ - _computeRecord() { - if (this.cannedResponse) { - return replace(this.cannedResponse); - } - if (this.channelCommand) { - return replace(this.channelCommand); - } - if (this.partner) { - return replace(this.partner); - } - if (this.thread) { - return replace(this.thread); - } - return clear(); + return this.suggestable.partner && this.suggestable.partner.isImStatusSet ? insertAndReplace() : clear(); }, /** * @private * @returns {string|FieldCommand} */ _computeTitle() { - if (this.cannedResponse) { - return sprintf("%s: %s", this.record.source, this.record.substitution); + if (this.suggestable.cannedResponse) { + return sprintf("%s: %s", this.suggestable.cannedResponse.source, this.suggestable.cannedResponse.substitution); } - if (this.thread) { - return this.record.name; + if (this.suggestable.thread) { + return this.suggestable.thread.name; } - if (this.channelCommand) { - return sprintf("%s: %s", this.record.name, this.record.help); + if (this.suggestable.channelCommand) { + return sprintf("%s: %s", this.suggestable.channelCommand.name, this.suggestable.channelCommand.help); } - if (this.partner) { - if (this.record.email) { - return sprintf("%s (%s)", this.record.nameOrDisplayName, this.record.email); + if (this.suggestable.partner) { + if (this.suggestable.partner.email) { + return sprintf("%s (%s)", this.suggestable.partner.nameOrDisplayName, this.suggestable.partner.email); } - return this.record.nameOrDisplayName; + return this.suggestable.partner.nameOrDisplayName; } return clear(); }, }, fields: { - cannedResponse: one('CannedResponse', { - readonly: true, - }), - channelCommand: one('ChannelCommand', { - readonly: true, - }), composerViewOwner: one('ComposerView', { compute: '_computeComposerViewOwner', required: true, @@ -144,20 +119,16 @@ registerModel({ mentionText: attr({ compute: '_computeMentionText', }), - record: one('Record', { - compute: '_computeRecord', - }), - partner: one('Partner', { - readonly: true, - }), personaImStatusIconView: one('PersonaImStatusIconView', { compute: '_computePersonaImStatusIconView', inverse: 'composerSuggestionViewOwner', isCausal: true, readonly: true, }), - thread: one('Thread', { + suggestable: one('ComposerSuggestable', { + inverse: 'composerSuggestions', readonly: true, + required: true, }), /** * Descriptive title for this suggestion. Useful to be able to diff --git a/addons/mail/static/src/models/composer_view.js b/addons/mail/static/src/models/composer_view.js index 91875bde0d6..41b6b1687a5 100644 --- a/addons/mail/static/src/models/composer_view.js +++ b/addons/mail/static/src/models/composer_view.js @@ -143,11 +143,11 @@ registerModel({ // Specific cases for channel and partner mentions: the message with // the mention will appear in the target channel, or be notified to // the target partner. - if (this.activeSuggestion.thread) { - Object.assign(updateData, { mentionedChannels: link(this.activeSuggestion.thread) }); + if (this.activeSuggestion.suggestable.thread) { + Object.assign(updateData, { mentionedChannels: link(this.activeSuggestion.suggestable.thread) }); } - if (this.activeSuggestion.partner) { - Object.assign(updateData, { mentionedPartners: link(this.activeSuggestion.partner) }); + if (this.activeSuggestion.suggestable.partner) { + Object.assign(updateData, { mentionedPartners: link(this.activeSuggestion.suggestable.partner) }); } this.composer.update(updateData); for (const composerView of this.composer.composerViews) { @@ -1389,31 +1389,17 @@ registerModel({ this.update({ extraSuggestions: insertAndReplace( extraSuggestedRecords.map(record => { - switch (record.constructor.name) { - case 'CannedResponse': - return { cannedResponse: replace(record) }; - case 'ChannelCommand': - return { channelCommand: replace(record) }; - case 'Partner': - return { partner: replace(record) }; - case 'Thread': - return { thread: replace(record) }; - } + return { + suggestable: replace(record.suggestable), + }; }), ), hasToScrollToActiveSuggestion: true, mainSuggestions: insertAndReplace( mainSuggestedRecords.map(record => { - switch (record.constructor.name) { - case 'CannedResponse': - return { cannedResponse: replace(record) }; - case 'ChannelCommand': - return { channelCommand: replace(record) }; - case 'Partner': - return { partner: replace(record) }; - case 'Thread': - return { thread: replace(record) }; - } + return { + suggestable: replace(record.suggestable), + }; }), ), }); diff --git a/addons/mail/static/src/models/partner.js b/addons/mail/static/src/models/partner.js index 941832654db..042676fb878 100644 --- a/addons/mail/static/src/models/partner.js +++ b/addons/mail/static/src/models/partner.js @@ -451,6 +451,13 @@ registerModel({ rtcSessions: many('RtcSession', { inverse: 'partner', }), + suggestable: one('ComposerSuggestable', { + default: insertAndReplace(), + inverse: 'partner', + isCausal: true, + readonly: true, + required: true, + }), user: one('User', { inverse: 'partner', }), diff --git a/addons/mail/static/src/models/persona_im_status_icon_view.js b/addons/mail/static/src/models/persona_im_status_icon_view.js index 11657a7f9b8..41d70718fdb 100644 --- a/addons/mail/static/src/models/persona_im_status_icon_view.js +++ b/addons/mail/static/src/models/persona_im_status_icon_view.js @@ -28,7 +28,7 @@ registerModel({ return replace(this.channelMemberViewOwner.channelMember.partner.persona); } if (this.composerSuggestionViewOwner) { - return replace(this.composerSuggestionViewOwner.partner.persona); + return replace(this.composerSuggestionViewOwner.suggestable.partner.persona); } if (this.messageViewOwner) { return replace(this.messageViewOwner.message.author.persona); diff --git a/addons/mail/static/src/models/thread.js b/addons/mail/static/src/models/thread.js index 612b72f4252..ccbd04627f5 100644 --- a/addons/mail/static/src/models/thread.js +++ b/addons/mail/static/src/models/thread.js @@ -2257,6 +2257,13 @@ registerModel({ serverMessageUnreadCounter: attr({ default: 0, }), + suggestable: one('ComposerSuggestable', { + default: insertAndReplace(), + inverse: 'thread', + isCausal: true, + readonly: true, + required: true, + }), /** * Determines the `SuggestedRecipientInfo` concerning `this`. */