diff --git a/addons/im_livechat/static/src/models/composer_view.js b/addons/im_livechat/static/src/models/composer_view.js index f3e3b5d95b4..1fe09e83541 100644 --- a/addons/im_livechat/static/src/models/composer_view.js +++ b/addons/im_livechat/static/src/models/composer_view.js @@ -9,7 +9,7 @@ patchRecordMethods('ComposerView', { * @override */ _computeDropZoneView() { - if (this.composer.thread && this.composer.thread.channel && this.composer.thread.channel.channel_type === 'livechat') { + if (this.composer && this.composer.thread && this.composer.thread.channel && this.composer.thread.channel.channel_type === 'livechat') { return clear(); } return this._super(); diff --git a/addons/mail/static/src/components/composer/composer.xml b/addons/mail/static/src/components/composer/composer.xml index 3599ad1d9e6..113a689edce 100644 --- a/addons/mail/static/src/components/composer/composer.xml +++ b/addons/mail/static/src/components/composer/composer.xml @@ -33,7 +33,7 @@ Replying to - + diff --git a/addons/mail/static/src/components/discuss_mobile_mailbox_selection/discuss_mobile_mailbox_selection.xml b/addons/mail/static/src/components/discuss_mobile_mailbox_selection/discuss_mobile_mailbox_selection.xml index 445b174694a..c4f75568953 100644 --- a/addons/mail/static/src/components/discuss_mobile_mailbox_selection/discuss_mobile_mailbox_selection.xml +++ b/addons/mail/static/src/components/discuss_mobile_mailbox_selection/discuss_mobile_mailbox_selection.xml @@ -3,7 +3,7 @@
- +
diff --git a/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.js b/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.js index 788e238b88a..89304fecf42 100644 --- a/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.js +++ b/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.js @@ -18,7 +18,7 @@ export class DiscussMobileMailboxSelectionItem extends Component { } /** - * @returns {Thread} + * @returns {Mailbox} */ get mailbox() { return this.props.mailbox; diff --git a/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.xml b/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.xml index 4824d58bd50..c905ade5d60 100644 --- a/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.xml +++ b/addons/mail/static/src/components/discuss_mobile_mailbox_selection_item/discuss_mobile_mailbox_selection_item.xml @@ -4,7 +4,7 @@ - + diff --git a/addons/mail/static/src/models/composer_view.js b/addons/mail/static/src/models/composer_view.js index 7731fe080a4..301ebde9775 100644 --- a/addons/mail/static/src/models/composer_view.js +++ b/addons/mail/static/src/models/composer_view.js @@ -54,7 +54,7 @@ registerModel({ } if (this.threadView && this.threadView.replyingToMessageView) { const { threadView } = this; - if (this.threadView.thread === this.messaging.inbox) { + if (this.threadView.thread === this.messaging.inbox.thread) { this.delete(); } threadView.update({ replyingToMessageView: clear() }); @@ -585,7 +585,7 @@ registerModel({ params.context = { mail_post_autofollow: this.composer.activeThread.hasWriteAccess }; } } - if (this.threadView && this.threadView.replyingToMessageView && this.threadView.thread !== this.messaging.inbox) { + if (this.threadView && this.threadView.replyingToMessageView && this.threadView.thread !== this.messaging.inbox.thread) { postData.parent_id = this.threadView.replyingToMessageView.message.id; } const { threadView = {} } = this; @@ -621,7 +621,7 @@ registerModel({ } } if (threadViewThread) { - if (threadViewThread === messaging.inbox) { + if (threadViewThread === messaging.inbox.thread) { messaging.notify({ message: sprintf(messaging.env._t(`Message posted on "%s"`), message.originThread.displayName), type: 'info', @@ -794,7 +794,7 @@ registerModel({ return clear(); } if (this.threadView.threadViewer.discuss) { - return this.threadView.threadViewer.discuss.thread === this.messaging.inbox; + return this.threadView.threadViewer.discuss.thread === this.messaging.inbox.thread; } return clear(); }, @@ -1019,7 +1019,7 @@ registerModel({ this.messaging.device.isSmall || ( this.messaging.discuss.threadView === this.threadView && - this.messaging.discuss.thread === this.messaging.inbox + this.messaging.discuss.thread === this.messaging.inbox.thread ) ) { return ['ctrl-enter', 'meta-enter']; diff --git a/addons/mail/static/src/models/discuss.js b/addons/mail/static/src/models/discuss.js index 0d62965a05b..3631231947d 100644 --- a/addons/mail/static/src/models/discuss.js +++ b/addons/mail/static/src/models/discuss.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, many, one } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; import { clear, insertAndReplace, replace } from '@mail/model/model_field_command'; import { escape, sprintf } from '@web/core/utils/strings'; @@ -236,7 +236,7 @@ registerModel({ this.messaging.device.isSmall && ( this.activeMobileNavbarTabId !== 'mailbox' || - this.thread.model !== 'mail.box' + !this.thread.mailbox ) ) { return false; @@ -285,44 +285,22 @@ registerModel({ return (this.messaging.device.isSmall && this.activeMobileNavbarTabId !== 'mailbox') ? insertAndReplace() : clear(); }, /** - * @private - * @returns {FieldCommand} - */ - _computeOrderedMailboxes() { - if (!this.messaging) { - return clear(); - } - const orderedMailboxes = this.messaging.models['Thread'] - .all(thread => thread.isPinned && thread.model === 'mail.box') - .sort((mailbox1, mailbox2) => { - if (mailbox1 === this.messaging.inbox) { - return -1; - } - if (mailbox2 === this.messaging.inbox) { - return 1; - } - if (mailbox1 === this.messaging.starred) { - return -1; - } - if (mailbox2 === this.messaging.starred) { - return 1; - } - const mailbox1Name = mailbox1.displayName; - const mailbox2Name = mailbox2.displayName; - return mailbox1Name < mailbox2Name ? -1 : 1; - }); - return replace(orderedMailboxes); - }, - /** - * Only pinned threads are allowed in discuss. + * Only mailboxes and pinned channels are allowed in Discuss. * * @private - * @returns {Thread|undefined} + * @returns {FieldCommand|undefined} */ _computeThread() { - if (!this.thread || !this.thread.isPinned) { + if (!this.thread) { return clear(); } + if (this.thread.channel && this.thread.isPinned) { + return undefined; + } + if (this.thread.mailbox) { + return undefined; + } + return clear(); }, /** * @private @@ -442,9 +420,6 @@ registerModel({ inverse: 'discuss', isCausal: true, }), - orderedMailboxes: many('Thread', { - compute: '_computeOrderedMailboxes', - }), /** * Quick search input value in the discuss sidebar (desktop). Useful * to filter channels and chats based on this input content. diff --git a/addons/mail/static/src/models/discuss_sidebar_mailbox_view.js b/addons/mail/static/src/models/discuss_sidebar_mailbox_view.js index 2b2c266c5f0..f87e3718ded 100644 --- a/addons/mail/static/src/models/discuss_sidebar_mailbox_view.js +++ b/addons/mail/static/src/models/discuss_sidebar_mailbox_view.js @@ -10,7 +10,7 @@ registerModel({ recordMethods: { /** * @private - * @returns {Thread} + * @returns {Mailbox} */ _computeMailbox() { if (this.discussViewOwnerAsHistory) { @@ -38,7 +38,7 @@ registerModel({ inverse: 'starredView', readonly: true, }), - mailbox: one('Thread', { + mailbox: one('Mailbox', { compute: '_computeMailbox', readonly: true, required: true, diff --git a/addons/mail/static/src/models/discuss_view.js b/addons/mail/static/src/models/discuss_view.js index ec2074befc2..697ef49e456 100644 --- a/addons/mail/static/src/models/discuss_view.js +++ b/addons/mail/static/src/models/discuss_view.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, one } from '@mail/model/model_field'; +import { attr, many, one } from '@mail/model/model_field'; import { clear, insertAndReplace } from '@mail/model/model_field_command'; import { OnChange } from '@mail/model/model_onchange'; @@ -58,13 +58,13 @@ registerModel({ /** * Called when clicking on a mailbox selection item. * - * @param {Thread} mailbox + * @param {Mailbox} mailbox */ onClickMobileMailboxSelectionItem(mailbox) { if (!mailbox.exists()) { return; } - mailbox.open(); + mailbox.thread.open(); }, /** * @param {Event} ev @@ -119,6 +119,15 @@ registerModel({ active_id: this.discuss.activeId, }); }, + /** + * @private + * @returns {Array[]} + */ + _sortMailboxes() { + return [ + ['smaller-first', 'sequence'], + ]; + }, }, fields: { /** @@ -146,6 +155,10 @@ registerModel({ inverse: 'discussViewOwnerAsMobileAddItemHeader', isCausal: true, }), + orderedMailboxes: many('Mailbox', { + related: 'messaging.allMailboxes', + sort: '_sortMailboxes', + }), /** * Reference of the quick search input. Useful to filter channels and * chats based on this input content. diff --git a/addons/mail/static/src/models/file_uploader.js b/addons/mail/static/src/models/file_uploader.js index 504e05e3d58..2149b32563f 100644 --- a/addons/mail/static/src/models/file_uploader.js +++ b/addons/mail/static/src/models/file_uploader.js @@ -76,7 +76,7 @@ registerModel({ if (this.chatterOwner) { return replace(this.chatterOwner.thread); } - if (this.composerView) { + if (this.composerView && this.composerView.composer) { return replace(this.composerView.composer.activeThread); } return clear(); diff --git a/addons/mail/static/src/models/mailbox.js b/addons/mail/static/src/models/mailbox.js new file mode 100644 index 00000000000..ce1631a76ef --- /dev/null +++ b/addons/mail/static/src/models/mailbox.js @@ -0,0 +1,153 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { attr, one } from '@mail/model/model_field'; +import { clear, insertAndReplace, replace } from '@mail/model/model_field_command'; +import { OnChange } from '@mail/model/model_onchange'; + +registerModel({ + name: 'Mailbox', + identifyingFields: [['messagingAsHistory', 'messagingAsInbox', 'messagingAsStarred']], + recordMethods: { + /** + * @returns {string|FieldCommand} + */ + _computeFetchMessagesUrl() { + switch (this) { + case this.messaging.history: + return '/mail/history/messages'; + case this.messaging.inbox: + return '/mail/inbox/messages'; + case this.messaging.starred: + return '/mail/starred/messages'; + default: + return clear(); + } + }, + /** + * @returns {FieldCommand} + */ + _computeMessagingAsAnyMailbox() { + if (!this.messaging) { + return clear(); + } + return replace(this.messaging); + }, + /** + * @returns {string|FieldCommand} + */ + _computeName() { + switch (this) { + case this.messaging.history: + return this.env._t("History"); + case this.messaging.inbox: + return this.env._t("Inbox"); + case this.messaging.starred: + return this.env._t("Starred"); + default: + return clear(); + } + }, + /** + * @returns {integer|FieldCommand} + */ + _computeSequence() { + switch (this) { + case this.messaging.history: + return 2; + case this.messaging.inbox: + return 0; + case this.messaging.starred: + return 1; + default: + return clear(); + } + }, + /** + * @returns {FieldCommand} + */ + _computeThread() { + const threadId = (() => { + switch (this) { + case this.messaging.history: + return 'history'; + case this.messaging.inbox: + return 'inbox'; + case this.messaging.starred: + return 'starred'; + } + })(); + if (!threadId) { + return clear(); + } + return insertAndReplace({ + id: threadId, + model: 'mail.box', + }); + }, + _onChangeCounter() { + if (this !== this.messaging.inbox) { + return; + } + if ( + this.thread.threadViews.length > 0 && + this.previousValueOfInboxCounter > 0 && this.counter === 0 + ) { + this.env.services.effect.add({ + message: this.env._t("Congratulations, your inbox is empty!"), + type: 'rainbow_man', + }); + } + this.update({ previousValueOfInboxCounter: this.counter }); + }, + }, + fields: { + counter: attr({ + default: 0, + }), + fetchMessagesUrl: attr({ + compute: '_computeFetchMessagesUrl', + }), + /** + * Useful to fill its inverse `Messaging/allMailboxes`. + */ + messagingAsAnyMailbox: one('Messaging', { + compute: '_computeMessagingAsAnyMailbox', + inverse: 'allMailboxes', + }), + messagingAsHistory: one('Messaging', { + inverse: 'history', + readonly: true, + }), + messagingAsInbox: one('Messaging', { + inverse: 'inbox', + readonly: true, + }), + messagingAsStarred: one('Messaging', { + inverse: 'starred', + readonly: true, + }), + name: attr({ + compute: '_computeName', + }), + /** + * Useful to display rainbow man on inbox. + */ + previousValueOfInboxCounter: attr({ + default: 0, + }), + sequence: attr({ + compute: '_computeSequence', + }), + thread: one('Thread', { + compute: '_computeThread', + inverse: 'mailbox', + }), + }, + onChanges: [ + new OnChange({ + dependencies: ['counter'], + methodName: '_onChangeCounter', + }), + ], +}); diff --git a/addons/mail/static/src/models/message.js b/addons/mail/static/src/models/message.js index 9558efd5135..d46f30a4782 100644 --- a/addons/mail/static/src/models/message.js +++ b/addons/mail/static/src/models/message.js @@ -602,13 +602,13 @@ registerModel({ _computeThreads() { const threads = []; if (this.isHistory && this.messaging.history) { - threads.push(this.messaging.history); + threads.push(this.messaging.history.thread); } if (this.isNeedaction && this.messaging.inbox) { - threads.push(this.messaging.inbox); + threads.push(this.messaging.inbox.thread); } if (this.isStarred && this.messaging.starred) { - threads.push(this.messaging.starred); + threads.push(this.messaging.starred.thread); } if (this.originThread) { threads.push(this.originThread); diff --git a/addons/mail/static/src/models/message_action_list.js b/addons/mail/static/src/models/message_action_list.js index 12eff4fcc4e..03f18a996cd 100644 --- a/addons/mail/static/src/models/message_action_list.js +++ b/addons/mail/static/src/models/message_action_list.js @@ -123,7 +123,7 @@ registerModel({ return Boolean( this.messaging && this.messaging.inbox && this.messageView && this.messageView.messageListViewMessageViewItemOwner && this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread && - this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread === this.messaging.inbox + this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread === this.messaging.inbox.thread ); }, /** @@ -135,8 +135,8 @@ registerModel({ this.messaging && this.messaging.inbox && this.message && !this.message.isTemporary && !this.message.isTransient && this.messageView && this.messageView.messageListViewMessageViewItemOwner && this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread && ( - this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread === this.messaging.inbox || - this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread.model === 'mail.channel' + this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread === this.messaging.inbox.thread || + this.messageView.messageListViewMessageViewItemOwner.messageListViewOwner.threadViewOwner.thread.channel ) ); }, diff --git a/addons/mail/static/src/models/messaging.js b/addons/mail/static/src/models/messaging.js index eacc4855a35..7905208d9a8 100644 --- a/addons/mail/static/src/models/messaging.js +++ b/addons/mail/static/src/models/messaging.js @@ -322,6 +322,9 @@ registerModel({ }, }, fields: { + allMailboxes: many('Mailbox', { + inverse: 'messagingAsAnyMailbox', + }), /** * Inverse of the messaging field present on all models. This field * therefore contains all existing records. @@ -383,14 +386,16 @@ registerModel({ fetchImStatusTimerDuration: attr({ default: 50 * 1000, }), - /** - * Mailbox History. - */ - history: one('Thread'), - /** - * Mailbox Inbox. - */ - inbox: one('Thread'), + history: one('Mailbox', { + default: insertAndReplace(), + inverse: 'messagingAsHistory', + isCausal: true, + }), + inbox: one('Mailbox', { + default: insertAndReplace(), + inverse: 'messagingAsInbox', + isCausal: true, + }), /** * Promise that will be resolved when messaging is initialized. */ @@ -447,7 +452,6 @@ registerModel({ messagingMenu: one('MessagingMenu', { default: insertAndReplace(), isCausal: true, - readonly: true, }), notificationHandler: one('MessagingNotificationHandler', { compute: '_computeNotificationHandler', @@ -489,10 +493,11 @@ registerModel({ isCausal: true, readonly: true, }), - /** - * Mailbox Starred. - */ - starred: one('Thread'), + starred: one('Mailbox', { + default: insertAndReplace(), + inverse: 'messagingAsStarred', + isCausal: true, + }), userNotificationManager: one('UserNotificationManager', { default: insertAndReplace(), isCausal: true, diff --git a/addons/mail/static/src/models/messaging_initializer.js b/addons/mail/static/src/models/messaging_initializer.js index ff332c9a4f4..8662bc57c23 100644 --- a/addons/mail/static/src/models/messaging_initializer.js +++ b/addons/mail/static/src/models/messaging_initializer.js @@ -2,7 +2,7 @@ import { registerModel } from '@mail/model/model_core'; import { executeGracefully } from '@mail/utils/utils'; -import { link, insert, insertAndReplace, replace } from '@mail/model/model_field_command'; +import { link, insert, replace } from '@mail/model/model_field_command'; registerModel({ name: 'MessagingInitializer', @@ -21,26 +21,6 @@ registerModel({ * the current user. This includes pinned channels for instance. */ async start() { - this.messaging.update({ - history: insertAndReplace({ - id: 'history', - isServerPinned: true, - model: 'mail.box', - name: this.env._t("History"), - }), - inbox: insertAndReplace({ - id: 'inbox', - isServerPinned: true, - model: 'mail.box', - name: this.env._t("Inbox"), - }), - starred: insertAndReplace({ - id: 'starred', - isServerPinned: true, - model: 'mail.box', - name: this.env._t("Starred"), - }), - }); this.messaging.device.start(); const discuss = this.messaging.discuss; const data = await this.performInitRpc(); diff --git a/addons/mail/static/src/models/messaging_menu.js b/addons/mail/static/src/models/messaging_menu.js index 4ae903875a9..ea8346fcec6 100644 --- a/addons/mail/static/src/models/messaging_menu.js +++ b/addons/mail/static/src/models/messaging_menu.js @@ -100,7 +100,7 @@ registerModel({ this.messaging.refreshIsNotificationPermissionDefault(); if (this.isOpen) { // populate some needaction messages on threads. - this.messaging.inbox.cache.update({ isCacheRefreshRequested: true }); + this.messaging.inbox.thread.cache.update({ isCacheRefreshRequested: true }); } }, /** diff --git a/addons/mail/static/src/models/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler.js index e93ae1c70c0..01e76cb4c63 100644 --- a/addons/mail/static/src/models/messaging_notification_handler.js +++ b/addons/mail/static/src/models/messaging_notification_handler.js @@ -514,11 +514,11 @@ registerModel({ // kept for compatibility in stable inbox.update({ counter: decrement(message_ids.length) }); } - if (inbox.counter > inbox.cache.fetchedMessages.length) { + if (inbox.counter > inbox.thread.cache.fetchedMessages.length) { // Force refresh Inbox because depending on what was marked as // read the cache might become empty even though there are more // messages on the server. - inbox.cache.update({ hasToLoadMessages: true }); + inbox.thread.cache.update({ hasToLoadMessages: true }); } }, /** diff --git a/addons/mail/static/src/models/mobile_messaging_navbar_view.js b/addons/mail/static/src/models/mobile_messaging_navbar_view.js index 739735eeb88..3965b979ffd 100644 --- a/addons/mail/static/src/models/mobile_messaging_navbar_view.js +++ b/addons/mail/static/src/models/mobile_messaging_navbar_view.js @@ -19,9 +19,9 @@ registerModel({ this.discuss.update({ activeMobileNavbarTabId: tabId }); if ( this.discuss.activeMobileNavbarTabId === 'mailbox' && - (!this.discuss.thread || this.discuss.thread.model !== 'mailbox') + (!this.discuss.thread || !this.discuss.thread.mailbox) ) { - this.discuss.update({ thread: replace(this.messaging.inbox) }); + this.discuss.update({ thread: replace(this.messaging.inbox.thread) }); } if (this.discuss.activeMobileNavbarTabId !== 'mailbox') { this.discuss.update({ thread: clear() }); diff --git a/addons/mail/static/src/models/notification_list_view.js b/addons/mail/static/src/models/notification_list_view.js index 1d84e3e3561..0d792b0d914 100644 --- a/addons/mail/static/src/models/notification_list_view.js +++ b/addons/mail/static/src/models/notification_list_view.js @@ -32,28 +32,6 @@ registerModel({ */ _computeFilteredThreads() { switch (this.filter) { - case 'mailbox': { - return replace(this.messaging.models['Thread'] - .all(thread => thread.isPinned && thread.model === 'mail.box') - .sort((mailbox1, mailbox2) => { - if (mailbox1 === this.messaging.inbox) { - return -1; - } - if (mailbox2 === this.messaging.inbox) { - return 1; - } - if (mailbox1 === this.messaging.starred) { - return -1; - } - if (mailbox2 === this.messaging.starred) { - return 1; - } - const mailbox1Name = mailbox1.displayName; - const mailbox2Name = mailbox2.displayName; - mailbox1Name < mailbox2Name ? -1 : 1; - }) - ); - } case 'channel': { return replace(this.messaging.models['Thread'] .all(thread => @@ -132,7 +110,7 @@ registerModel({ } return insertAndReplace( this.messaging.models['Thread'] - .all(t => t.model !== 'mail.box' && t.needactionMessagesAsOriginThread.length > 0) + .all(t => !t.mailbox && t.needactionMessagesAsOriginThread.length > 0) .sort((t1, t2) => { if (t1.needactionMessagesAsOriginThread.length > 0 && t2.needactionMessagesAsOriginThread.length === 0) { return -1; diff --git a/addons/mail/static/src/models/thread.js b/addons/mail/static/src/models/thread.js index 32cce8705c7..d4dd1ddd469 100644 --- a/addons/mail/static/src/models/thread.js +++ b/addons/mail/static/src/models/thread.js @@ -815,7 +815,7 @@ registerModel({ async open({ expanded = false, focus } = {}) { const discuss = this.messaging.discuss; // check if thread must be opened in form view - if (!['mail.box', 'mail.channel'].includes(this.model)) { + if (!this.channel && !this.mailbox) { if (expanded || discuss.discussView) { // Close chat window because having the same thread opened // both in chat window and as main document does not look @@ -831,7 +831,7 @@ registerModel({ // check if thread must be opened in discuss if ( (!this.messaging.device.isSmall && (discuss.discussView || expanded)) || - this.model === 'mail.box' + this.mailbox ) { return discuss.openThread(this, { focus: focus !== undefined ? focus : !this.messaging.device.isMobileDevice, @@ -1061,7 +1061,7 @@ registerModel({ * @returns {FieldCommand} */ _computeComposer() { - if (this.model === 'mail.box') { + if (this.mailbox) { return clear(); } return insertAndReplace(); @@ -1138,6 +1138,9 @@ registerModel({ const guestNames = this.guestMembers.map(guest => guest.name); return [...partnerNames, ...guestNames].join(this.env._t(", ")); } + if (this.mailbox) { + return this.mailbox.name; + } return this.name; }, /** @@ -1145,12 +1148,12 @@ registerModel({ * @returns {Object} */ _computeFetchMessagesParams() { - if (this.model === 'mail.box') { - return {}; - } if (this.model === 'mail.channel') { return { 'channel_id': this.id }; } + if (this.mailbox) { + return {}; + } return { 'thread_id': this.id, 'thread_model': this.model, @@ -1161,17 +1164,12 @@ registerModel({ * @returns {string} */ _computeFetchMessagesUrl() { - switch (this) { - case this.messaging.inbox: - return '/mail/inbox/messages'; - case this.messaging.history: - return '/mail/history/messages'; - case this.messaging.starred: - return '/mail/starred/messages'; - } if (this.model === 'mail.channel') { return `/mail/channel/messages`; } + if (this.mailbox) { + return this.mailbox.fetchMessagesUrl; + } return `/mail/thread/messages`; }, /** @@ -1636,23 +1634,6 @@ registerModel({ forceNotifyNextCurrentPartnerTypingStatus: false, }); }, - /** - * @private - */ - _onChangeCounter() { - if (this === this.messaging.inbox) { - if ( - this.threadViews.length > 0 && - this.lastCounter > 0 && this.counter === 0 - ) { - this.env.services.effect.add({ - message: this.env._t("Congratulations, your inbox is empty!"), - type: 'rainbow_man', - }); - } - this.update({ lastCounter: this.counter }); - } - }, /** * @private */ @@ -1813,9 +1794,6 @@ registerModel({ compute: '_computeCorrespondentOfDmChat', inverse: 'dmChatWithCurrentPartner', }), - counter: attr({ - default: 0, - }), creator: one('User'), /** * Timer of current partner that was currently typing something, but @@ -2093,10 +2071,6 @@ registerModel({ compute: '_computeLastSeenByCurrentPartnerMessageId', default: 0, }), - /** - * Useful to display rainbow man on inbox. - */ - lastCounter: attr(), /** * Local value of message unread counter, that means it is based on initial server value and * updated with interface updates. @@ -2104,6 +2078,9 @@ registerModel({ localMessageUnreadCounter: attr({ compute: '_computeLocalMessageUnreadCounter', }), + mailbox: one('Mailbox', { + inverse: 'thread', + }), mainAttachment: one('Attachment'), /** * States the number of members in this thread according to the server. @@ -2408,10 +2385,6 @@ registerModel({ dependencies: ['lastSeenByCurrentPartnerMessageId'], methodName: '_onChangeLastSeenByCurrentPartnerMessageId', }), - new OnChange({ - dependencies: ['counter'], - methodName: '_onChangeCounter', - }), new OnChange({ dependencies: ['isServerPinned'], methodName: '_onIsServerPinnedChanged', diff --git a/addons/mail/static/src/models/thread_view.js b/addons/mail/static/src/models/thread_view.js index 4a8b9baa1cd..5cc1f98c1ea 100644 --- a/addons/mail/static/src/models/thread_view.js +++ b/addons/mail/static/src/models/thread_view.js @@ -107,7 +107,7 @@ registerModel({ * @returns {FieldCommand} */ _computeComposerView() { - if (!this.thread || this.thread.model === 'mail.box') { + if (!this.thread || this.thread.mailbox) { return clear(); } if (this.threadViewer && this.threadViewer.chatter) { @@ -121,7 +121,7 @@ registerModel({ */ _computeHasComposerThreadName() { if (this.threadViewer.discuss) { - return this.threadViewer.discuss.thread === this.messaging.inbox; + return this.threadViewer.discuss.thread === this.messaging.inbox.thread; } return clear(); }, @@ -140,7 +140,7 @@ registerModel({ * @returns {boolean} */ _computeHasSquashCloseMessages() { - return Boolean(this.threadViewer && !this.threadViewer.chatter && this.thread && this.thread.model !== 'mail.box'); + return Boolean(this.threadViewer && !this.threadViewer.chatter && this.thread && !this.thread.mailbox); }, /** * @private diff --git a/addons/mail/static/tests/qunit_mobile_suite_tests/components/discuss_mobile_mailbox_selection_tests.js b/addons/mail/static/tests/qunit_mobile_suite_tests/components/discuss_mobile_mailbox_selection_tests.js index f353af21ac3..9766748599f 100644 --- a/addons/mail/static/tests/qunit_mobile_suite_tests/components/discuss_mobile_mailbox_selection_tests.js +++ b/addons/mail/static/tests/qunit_mobile_suite_tests/components/discuss_mobile_mailbox_selection_tests.js @@ -34,7 +34,7 @@ QUnit.test('select another mailbox', async function (assert) { ); assert.strictEqual( document.querySelector('.o_Discuss_thread').dataset.threadLocalId, - messaging.inbox.localId, + messaging.inbox.thread.localId, "inbox mailbox should be opened initially" ); assert.containsOnce( @@ -55,7 +55,7 @@ QUnit.test('select another mailbox', async function (assert) { ); assert.strictEqual( document.querySelector('.o_Discuss_thread').dataset.threadLocalId, - messaging.starred.localId, + messaging.starred.thread.localId, "starred mailbox should be opened after clicking on it" ); }); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_inbox_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_inbox_tests.js index ea2e2c189f0..717ddbdeac6 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_inbox_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_inbox_tests.js @@ -35,7 +35,7 @@ QUnit.test('reply: discard on pressing escape', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, insertText, openDiscuss } = await start(); + const { afterEvent, click, insertText, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -43,8 +43,7 @@ QUnit.test('reply: discard on pressing escape', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -134,7 +133,7 @@ QUnit.test('reply: discard on discard button click', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, openDiscuss } = await start(); + const { afterEvent, click, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -142,8 +141,7 @@ QUnit.test('reply: discard on discard button click', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -192,7 +190,7 @@ QUnit.test('reply: discard on reply button toggle', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, openDiscuss } = await start(); + const { afterEvent, click, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -200,8 +198,7 @@ QUnit.test('reply: discard on reply button toggle', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -244,7 +241,7 @@ QUnit.test('reply: discard on click away', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, openDiscuss } = await start(); + const { afterEvent, click, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -252,8 +249,7 @@ QUnit.test('reply: discard on click away', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -325,7 +321,7 @@ QUnit.test('"reply to" composer should log note if message replied to is a note' notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, insertText, openDiscuss } = await start({ + const { afterEvent, click, insertText, messaging, openDiscuss } = await start({ async mockRPC(route, args) { if (route === '/mail/message/post') { assert.step('/mail/message/post'); @@ -349,8 +345,7 @@ QUnit.test('"reply to" composer should log note if message replied to is a note' predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -392,7 +387,7 @@ QUnit.test('"reply to" composer should send message if message replied to is not notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, insertText, openDiscuss } = await start({ + const { afterEvent, click, insertText, messaging, openDiscuss } = await start({ async mockRPC(route, args) { if (route === '/mail/message/post') { assert.step('/mail/message/post'); @@ -416,8 +411,7 @@ QUnit.test('"reply to" composer should send message if message replied to is not predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -494,7 +488,7 @@ QUnit.test('show subject of message in Inbox', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -502,8 +496,7 @@ QUnit.test('show subject of message in Inbox', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -541,7 +534,7 @@ QUnit.test('show subject of message in history', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start({ + const { afterEvent, messaging, openDiscuss } = await start({ discuss: { params: { default_active_id: 'mail.box_history', @@ -555,8 +548,7 @@ QUnit.test('show subject of message in history', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'history' + threadViewer.thread === messaging.history.thread ); }, }); @@ -595,7 +587,7 @@ QUnit.test('click on (non-channel/non-partner) origin thread link should redirec notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, env, openDiscuss } = await start(); + const { afterEvent, env, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -603,8 +595,7 @@ QUnit.test('click on (non-channel/non-partner) origin thread link should redirec predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -675,7 +666,7 @@ QUnit.test('subject should not be shown when subject is the same as the thread n notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -683,8 +674,7 @@ QUnit.test('subject should not be shown when subject is the same as the thread n predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -713,7 +703,7 @@ QUnit.test('subject should not be shown when subject is the same as the thread n notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -721,8 +711,7 @@ QUnit.test('subject should not be shown when subject is the same as the thread n predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -751,7 +740,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -759,8 +748,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -789,7 +777,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -797,8 +785,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -827,7 +814,7 @@ QUnit.test('subject should be shown when the thread name has an extra prefix com notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -835,8 +822,7 @@ QUnit.test('subject should be shown when the thread name has an extra prefix com predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -865,7 +851,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -873,8 +859,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -903,7 +888,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -911,8 +896,7 @@ QUnit.test('subject should not be shown when subject differs from thread name on predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js index 954548e64cb..f84f1c3d14f 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_pinned_tests.js @@ -19,7 +19,7 @@ QUnit.test('sidebar: pinned channel 1: init with one pinned channel', async func await openDiscuss(); assert.containsOnce( document.body, - `.o_Discuss_thread[data-thread-local-id="${messaging.inbox.localId}"]`, + `.o_Discuss_thread[data-thread-local-id="${messaging.inbox.thread.localId}"]`, "The Inbox is opened in discuss" ); assert.containsOnce( @@ -121,7 +121,7 @@ QUnit.test('sidebar: unpin channel from bus', async function (assert) { assert.containsOnce( document.body, - `.o_Discuss_thread[data-thread-local-id="${messaging.inbox.localId}"]`, + `.o_Discuss_thread[data-thread-local-id="${messaging.inbox.thread.localId}"]`, "The Inbox is opened in discuss" ); assert.containsOnce( diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js index 9b3240bd337..c09c2440077 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_sidebar_category_tests.js @@ -414,7 +414,7 @@ QUnit.test('channel - states: the active category item should be visble even if 'the active channel item should remain even if the category is folded' ); - await click(`.o_DiscussSidebarMailbox[data-thread-local-id="${ + await click(`.o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"]`); assert.containsNone( @@ -803,7 +803,7 @@ QUnit.test('chat - states: the active category item should be visble even if the 'the active chat item should remain even if the category is folded' ); - await click(`.o_DiscussSidebarMailbox[data-thread-local-id="${ + await click(`.o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"]`); assert.containsNone( diff --git a/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js index 66d2e1417fd..1c5bb7f7b3c 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/discuss_tests.js @@ -163,7 +163,7 @@ QUnit.test('basic rendering: sidebar', async function (assert) { assert.strictEqual( document.querySelectorAll(` .o_DiscussSidebar_categoryMailbox - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).length, @@ -173,7 +173,7 @@ QUnit.test('basic rendering: sidebar', async function (assert) { assert.strictEqual( document.querySelectorAll(` .o_DiscussSidebar_categoryMailbox - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).length, @@ -183,7 +183,7 @@ QUnit.test('basic rendering: sidebar', async function (assert) { assert.strictEqual( document.querySelectorAll(` .o_DiscussSidebar_categoryMailbox - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).length, @@ -263,7 +263,7 @@ QUnit.test('sidebar: basic mailbox rendering', async function (assert) { await openDiscuss(); const inbox = document.querySelector(` .o_DiscussSidebar_categoryMailbox - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `); @@ -289,7 +289,7 @@ QUnit.test('sidebar: basic mailbox rendering', async function (assert) { ); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -306,7 +306,7 @@ QUnit.test('sidebar: default active inbox', async function (assert) { await openDiscuss(); const inbox = document.querySelector(` .o_DiscussSidebar_categoryMailbox - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `); @@ -323,7 +323,7 @@ QUnit.test('sidebar: change item', async function (assert) { await openDiscuss(); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -331,7 +331,7 @@ QUnit.test('sidebar: change item', async function (assert) { ); assert.notOk( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).classList.contains('o-active'), @@ -339,13 +339,13 @@ QUnit.test('sidebar: change item', async function (assert) { ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `); assert.notOk( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -353,7 +353,7 @@ QUnit.test('sidebar: change item', async function (assert) { ); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).classList.contains('o-active'), @@ -369,7 +369,7 @@ QUnit.test('sidebar: inbox with counter', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -379,7 +379,7 @@ QUnit.test('sidebar: inbox with counter', async function (assert) { ); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -874,7 +874,7 @@ QUnit.test('default thread rendering', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).length, @@ -883,7 +883,7 @@ QUnit.test('default thread rendering', async function (assert) { ); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).length, @@ -892,7 +892,7 @@ QUnit.test('default thread rendering', async function (assert) { ); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).length, @@ -913,7 +913,7 @@ QUnit.test('default thread rendering', async function (assert) { ); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -934,13 +934,13 @@ QUnit.test('default thread rendering', async function (assert) { ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).classList.contains('o-active'), @@ -961,13 +961,13 @@ QUnit.test('default thread rendering', async function (assert) { ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).classList.contains('o-active'), @@ -1051,7 +1051,7 @@ QUnit.test('default select thread in discuss params', async function (assert) { await openDiscuss(); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).classList.contains('o-active'), @@ -1072,7 +1072,7 @@ QUnit.test('auto-select thread in discuss context', async function (assert) { await openDiscuss(); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `).classList.contains('o-active'), @@ -1458,8 +1458,7 @@ QUnit.test('inbox messages are never squashed', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -2237,7 +2236,7 @@ QUnit.test('basic top bar rendering', async function (assert) { ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] `); @@ -2315,7 +2314,7 @@ QUnit.test('inbox: mark all messages as read', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -2350,7 +2349,7 @@ QUnit.test('inbox: mark all messages as read', async function (assert) { await afterNextRender(() => markAllReadButton.click()); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -2401,7 +2400,7 @@ QUnit.test('starred: unstar all', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] .o_DiscussSidebarMailbox_counter @@ -2423,7 +2422,7 @@ QUnit.test('starred: unstar all', async function (assert) { await afterNextRender(() => unstarAllButton.click()); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] .o_DiscussSidebarMailbox_counter @@ -2473,7 +2472,7 @@ QUnit.test('toggle_star message', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] .o_DiscussSidebarMailbox_counter @@ -2502,7 +2501,7 @@ QUnit.test('toggle_star message', async function (assert) { assert.verifySteps(['rpc:toggle_message_starred']); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] .o_DiscussSidebarMailbox_counter @@ -2525,7 +2524,7 @@ QUnit.test('toggle_star message', async function (assert) { assert.verifySteps(['rpc:toggle_message_starred']); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.starred.localId }"] .o_DiscussSidebarMailbox_counter @@ -2859,7 +2858,7 @@ QUnit.test('rendering of inbox message', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, openDiscuss } = await start(); + const { afterEvent, messaging, openDiscuss } = await start(); await afterEvent({ eventName: 'o-thread-view-hint-processed', func: openDiscuss, @@ -2867,8 +2866,7 @@ QUnit.test('rendering of inbox message', async function (assert) { predicate: ({ hint, threadViewer }) => { return ( hint.type === 'messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'inbox' + threadViewer.thread === messaging.inbox.thread ); }, }); @@ -3000,7 +2998,7 @@ QUnit.test('receive new needaction messages', async function (assert) { await openDiscuss(); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `), @@ -3008,7 +3006,7 @@ QUnit.test('receive new needaction messages', async function (assert) { ); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -3016,7 +3014,7 @@ QUnit.test('receive new needaction messages', async function (assert) { ); assert.notOk( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -3041,7 +3039,7 @@ QUnit.test('receive new needaction messages', async function (assert) { }); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -3050,7 +3048,7 @@ QUnit.test('receive new needaction messages', async function (assert) { ); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -3081,7 +3079,7 @@ QUnit.test('receive new needaction messages', async function (assert) { }); assert.strictEqual( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] .o_DiscussSidebarMailbox_counter @@ -3274,7 +3272,7 @@ QUnit.test('messages marked as read move to "History" mailbox', async function ( await openDiscuss(); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).classList.contains('o-active'), @@ -3287,13 +3285,13 @@ QUnit.test('messages marked as read move to "History" mailbox', async function ( ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -3313,7 +3311,7 @@ QUnit.test('messages marked as read move to "History" mailbox', async function ( await click('.o_ThreadViewTopbar_markAllReadButton'); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `).classList.contains('o-active'), @@ -3326,13 +3324,13 @@ QUnit.test('messages marked as read move to "History" mailbox', async function ( ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).classList.contains('o-active'), @@ -3388,7 +3386,7 @@ QUnit.test('mark a single message as read should only move this message to "Hist await openDiscuss(); assert.hasClass( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `), @@ -3402,13 +3400,13 @@ QUnit.test('mark a single message as read should only move this message to "Hist ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `); assert.hasClass( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.inbox.localId }"] `), @@ -3446,13 +3444,13 @@ QUnit.test('mark a single message as read should only move this message to "Hist ); await click(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `); assert.hasClass( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `), @@ -3497,9 +3495,7 @@ QUnit.test('all messages in "Inbox" in "History" after marked all as read', asyn predicate: ({ orderedMessages, scrollTop, thread }) => { const messageList = document.querySelector(`.o_Discuss_thread .o_ThreadView_messageList`); return ( - thread && - thread.model === 'mail.box' && - thread.id === 'inbox' && + thread === messaging.inbox.thread && orderedMessages.length === 30 && isScrolledToBottom(messageList) ); @@ -3517,7 +3513,7 @@ QUnit.test('all messages in "Inbox" in "History" after marked all as read', asyn eventName: 'o-component-message-list-scrolled', func: () => { document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-local-id="${ + .o_DiscussSidebarMailbox[data-mailbox-local-id="${ messaging.history.localId }"] `).click(); @@ -3527,8 +3523,8 @@ QUnit.test('all messages in "Inbox" in "History" after marked all as read', asyn const messageList = document.querySelector('.o_MessageList'); return ( thread && - thread.model === 'mail.box' && - thread.id === 'history' && + thread.mailbox && + thread.mailbox === messaging.history && orderedMessages.length === 30 && isScrolledToBottom(messageList) ); @@ -3543,8 +3539,8 @@ QUnit.test('all messages in "Inbox" in "History" after marked all as read', asyn predicate: ({ hint, threadViewer }) => { return ( hint.type === 'more-messages-loaded' && - threadViewer.thread.model === 'mail.box' && - threadViewer.thread.id === 'history' + threadViewer.thread.mailbox && + threadViewer.thread.mailbox === messaging.history ); }, }); @@ -3712,14 +3708,14 @@ QUnit.test('auto-focus composer on opening thread', async function (assert) { await openDiscuss(); assert.strictEqual( document.querySelectorAll(` - .o_DiscussSidebarMailbox[data-thread-name="Inbox"] + .o_DiscussSidebarMailbox[data-mailbox-name="Inbox"] `).length, 1, "should have mailbox 'Inbox' in the sidebar" ); assert.ok( document.querySelector(` - .o_DiscussSidebarMailbox[data-thread-name="Inbox"] + .o_DiscussSidebarMailbox[data-mailbox-name="Inbox"] `).classList.contains('o-active'), "mailbox 'Inbox' should be active initially" ); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/thread_needaction_preview_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/thread_needaction_preview_tests.js index 65b824782f4..66604607f38 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/thread_needaction_preview_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/thread_needaction_preview_tests.js @@ -25,7 +25,7 @@ QUnit.test('mark as read', async function (assert) { notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click } = await start({ + const { afterEvent, click, messaging } = await start({ async mockRPC(route, args) { if (route.includes('mark_all_as_read')) { assert.step('mark_all_as_read'); @@ -45,7 +45,7 @@ QUnit.test('mark as read', async function (assert) { func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.containsOnce( @@ -83,13 +83,13 @@ QUnit.test('click on preview should mark as read and open the thread', async fun notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click } = await start(); + const { afterEvent, click, messaging } = await start(); await afterNextRender(() => afterEvent({ eventName: 'o-thread-cache-loaded-messages', func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.containsOnce( @@ -134,7 +134,7 @@ QUnit.test('click on expand from chat window should close the chat window and op notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click, env } = await start(); + const { afterEvent, click, env, messaging } = await start(); patchWithCleanup(env.services.action, { doAction(action) { assert.step('do_action'); @@ -155,7 +155,7 @@ QUnit.test('click on expand from chat window should close the chat window and op func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.containsOnce( @@ -207,7 +207,7 @@ QUnit.test('[technical] opening a non-channel chat window should not call channe notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click } = await start({ + const { afterEvent, click, messaging } = await start({ async mockRPC(route, args) { if (route.includes('channel_fold')) { const message = "should not call channel_fold when opening a non-channel chat window"; @@ -222,7 +222,7 @@ QUnit.test('[technical] opening a non-channel chat window should not call channe func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.containsOnce( @@ -271,13 +271,13 @@ QUnit.test('preview should display last needaction message preview even if there notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent } = await start(); + const { afterEvent, messaging } = await start(); await afterNextRender(() => afterEvent({ eventName: 'o-thread-cache-loaded-messages', func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.containsOnce( @@ -311,13 +311,13 @@ QUnit.test('chat window header should not have unread counter for non-channel th notification_type: 'inbox', res_partner_id: pyEnv.currentPartnerId, }); - const { afterEvent, click } = await start(); + const { afterEvent, click, messaging } = await start(); await afterNextRender(() => afterEvent({ eventName: 'o-thread-cache-loaded-messages', func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); await click('.o_ThreadNeedactionPreview'); diff --git a/addons/mail/static/tests/qunit_suite_tests/models/message_tests.js b/addons/mail/static/tests/qunit_suite_tests/models/message_tests.js index 58d50e888bf..ae2e9bef7c4 100644 --- a/addons/mail/static/tests/qunit_suite_tests/models/message_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/models/message_tests.js @@ -70,9 +70,9 @@ QUnit.test('create', async function (assert) { })) ); // from partnerId being in needaction_partner_ids - assert.ok(message.threads.includes(messaging.inbox)); + assert.ok(message.threads.includes(messaging.inbox.thread)); // from partnerId being in starred_partner_ids - assert.ok(message.threads.includes(messaging.starred)); + assert.ok(message.threads.includes(messaging.starred.thread)); const attachment = messaging.models['Attachment'].findFromIdentifyingData({ id: 750 }); assert.ok(attachment); assert.strictEqual(attachment.filename, "test.txt"); diff --git a/addons/mail/static/tests/qunit_suite_tests/models/thread_tests.js b/addons/mail/static/tests/qunit_suite_tests/models/thread_tests.js index 056c0775879..033aa436beb 100644 --- a/addons/mail/static/tests/qunit_suite_tests/models/thread_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/models/thread_tests.js @@ -15,13 +15,13 @@ QUnit.test('inbox & starred mailboxes', async function (assert) { const mailboxStarred = messaging.starred; assert.ok(mailboxInbox, "should have mailbox inbox"); assert.ok(mailboxStarred, "should have mailbox starred"); - assert.strictEqual(mailboxInbox.model, 'mail.box'); + assert.strictEqual(mailboxInbox.thread.model, 'mail.box'); assert.strictEqual(mailboxInbox.counter, 0); - assert.strictEqual(mailboxInbox.id, 'inbox'); + assert.strictEqual(mailboxInbox.thread.id, 'inbox'); assert.strictEqual(mailboxInbox.name, "Inbox"); // language-dependent - assert.strictEqual(mailboxStarred.model, 'mail.box'); + assert.strictEqual(mailboxStarred.thread.model, 'mail.box'); assert.strictEqual(mailboxStarred.counter, 0); - assert.strictEqual(mailboxStarred.id, 'starred'); + assert.strictEqual(mailboxStarred.thread.id, 'starred'); assert.strictEqual(mailboxStarred.name, "Starred"); // language-dependent }); diff --git a/addons/test_mail_full/static/tests/qunit_suite_tests/thread_needaction_preview_tests.js b/addons/test_mail_full/static/tests/qunit_suite_tests/thread_needaction_preview_tests.js index 7e48a460b38..d551191d610 100644 --- a/addons/test_mail_full/static/tests/qunit_suite_tests/thread_needaction_preview_tests.js +++ b/addons/test_mail_full/static/tests/qunit_suite_tests/thread_needaction_preview_tests.js @@ -30,13 +30,13 @@ QUnit.test('rating value displayed on the thread needaction preview', async func rating_image_url: "/rating/static/src/img/rating_5.png", rating_text: "top", }]); - const { afterEvent } = await start(); + const { afterEvent, messaging } = await start(); await afterNextRender(() => afterEvent({ eventName: 'o-thread-cache-loaded-messages', func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.strictEqual( diff --git a/addons/test_mail_full/static/tests/qunit_suite_tests/thread_preview_tests.js b/addons/test_mail_full/static/tests/qunit_suite_tests/thread_preview_tests.js index d5a6bb39f92..8e99f3a6774 100644 --- a/addons/test_mail_full/static/tests/qunit_suite_tests/thread_preview_tests.js +++ b/addons/test_mail_full/static/tests/qunit_suite_tests/thread_preview_tests.js @@ -21,13 +21,13 @@ QUnit.test('rating value displayed on the thread preview', async function (asser rating_image_url: "/rating/static/src/img/rating_5.png", rating_text: "top", }); - const { afterEvent } = await start(); + const { afterEvent, messaging } = await start(); await afterNextRender(() => afterEvent({ eventName: 'o-thread-cache-loaded-messages', func: () => document.querySelector('.o_MessagingMenu_toggler').click(), message: "should wait until inbox loaded initial needaction messages", predicate: ({ threadCache }) => { - return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox'; + return threadCache.thread === messaging.inbox.thread; }, })); assert.strictEqual(