diff --git a/addons/mail/static/src/components/notification_list/notification_list.js b/addons/mail/static/src/components/notification_list/notification_list.js
index 0ab0f9c8ee1..df46ba3533e 100644
--- a/addons/mail/static/src/components/notification_list/notification_list.js
+++ b/addons/mail/static/src/components/notification_list/notification_list.js
@@ -2,22 +2,10 @@
import { registerMessagingComponent } from '@mail/utils/messaging_component';
-const { Component, onMounted } = owl;
+const { Component } = owl;
export class NotificationList extends Component {
- /**
- * @override
- */
- setup() {
- super.setup();
- onMounted(() => this._mounted());
- }
-
- _mounted() {
- this._loadPreviews();
- }
-
/**
* @returns {NotificationListView}
*/
@@ -25,22 +13,6 @@ export class NotificationList extends Component {
return this.messaging && this.messaging.models['NotificationListView'].get(this.props.localId);
}
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
- /**
- * Load previews of given thread. Basically consists of fetching all missing
- * last messages of each thread.
- *
- * @private
- */
- async _loadPreviews() {
- const threads = this.notificationListView.threadPreviewViews
- .map(threadPreviewView => threadPreviewView.thread);
- this.messaging.models['Thread'].loadPreviews(threads);
- }
-
}
Object.assign(NotificationList, {
diff --git a/addons/mail/static/src/components/notification_popover/notification_popover.js b/addons/mail/static/src/components/notification_popover/notification_popover.js
deleted file mode 100644
index b9cda34e071..00000000000
--- a/addons/mail/static/src/components/notification_popover/notification_popover.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/** @odoo-module **/
-
-import { registerMessagingComponent } from '@mail/utils/messaging_component';
-
-const { Component } = owl;
-
-export class NotificationPopover extends Component {
-
- /**
- * @returns {MessageView}
- */
- get messageView() {
- return this.messaging && this.messaging.models['MessageView'].get(this.props.messageViewLocalId);
- }
-
-}
-
-Object.assign(NotificationPopover, {
- props: { messageViewLocalId: String },
- template: 'mail.NotificationPopover',
-});
-
-registerMessagingComponent(NotificationPopover);
diff --git a/addons/mail/static/src/components/notification_popover/notification_popover.xml b/addons/mail/static/src/components/notification_popover/notification_popover.xml
deleted file mode 100644
index 347676240b3..00000000000
--- a/addons/mail/static/src/components/notification_popover/notification_popover.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/mail/static/src/components/tracking_value/tracking_value.js b/addons/mail/static/src/components/tracking_value/tracking_value.js
new file mode 100644
index 00000000000..17856fb3e33
--- /dev/null
+++ b/addons/mail/static/src/components/tracking_value/tracking_value.js
@@ -0,0 +1,14 @@
+/** @odoo-module **/
+
+import { registerMessagingComponent } from '@mail/utils/messaging_component';
+
+const { Component } = owl;
+
+export class TrackingValue extends Component {}
+
+Object.assign(TrackingValue, {
+ props: { value: Object },
+ template: 'mail.TrackingValue',
+});
+
+registerMessagingComponent(TrackingValue);
diff --git a/addons/mail/static/src/components/tracking_value/tracking_value.scss b/addons/mail/static/src/components/tracking_value/tracking_value.scss
new file mode 100644
index 00000000000..3c0215bc542
--- /dev/null
+++ b/addons/mail/static/src/components/tracking_value/tracking_value.scss
@@ -0,0 +1,6 @@
+
+.o_TrackingValue_item {
+ // Could be replaced by "me-1" after the migration to BS5
+ // for the backend AND the frontend
+ margin-inline-end: map-get($spacers, 1);
+}
\ No newline at end of file
diff --git a/addons/mail/static/src/components/tracking_value/tracking_value.xml b/addons/mail/static/src/components/tracking_value/tracking_value.xml
new file mode 100644
index 00000000000..7990674b0ae
--- /dev/null
+++ b/addons/mail/static/src/components/tracking_value/tracking_value.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
None
+
+
+
+
+
None
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/mail/static/src/models/messaging_menu.js b/addons/mail/static/src/models/messaging_menu.js
index a838d4d755d..8860b016e92 100644
--- a/addons/mail/static/src/models/messaging_menu.js
+++ b/addons/mail/static/src/models/messaging_menu.js
@@ -7,6 +7,14 @@ import { clear, insertAndReplace } from '@mail/model/model_field_command';
registerModel({
name: 'MessagingMenu',
identifyingFields: ['messaging'],
+ lifecycleHooks: {
+ _created() {
+ document.addEventListener('click', this._onClickCaptureGlobal, true);
+ },
+ _willDelete() {
+ document.removeEventListener('click', this._onClickCaptureGlobal, true);
+ },
+ },
recordMethods: {
/**
* Close the messaging menu. Should reset its internal state.
@@ -45,6 +53,38 @@ registerModel({
onHideMobileNewMessage() {
this.update({ isMobileNewMessageToggled: false });
},
+ /**
+ * @private
+ * @param {Event} ev
+ * @param {Object} ui
+ * @param {Object} ui.item
+ * @param {integer} ui.item.id
+ */
+ onMobileNewMessageInputSelect(ev, ui) {
+ this.messaging.openChat({ partnerId: ui.item.id });
+ },
+ /**
+ * @param {Object} req
+ * @param {string} req.term
+ * @param {function} res
+ */
+ onMobileNewMessageInputSource(req, res) {
+ const value = _.escape(req.term);
+ this.messaging.models['Partner'].imSearch({
+ callback: partners => {
+ const suggestions = partners.map(partner => {
+ return {
+ id: partner.id,
+ value: partner.nameOrDisplayName,
+ label: partner.nameOrDisplayName,
+ };
+ });
+ res(_.sortBy(suggestions, 'label'));
+ },
+ keyword: value,
+ limit: 10,
+ });
+ },
/**
* Toggle the visibility of the messaging menu "new message" input in
* mobile.
@@ -113,6 +153,26 @@ registerModel({
_computeNotificationListView() {
return this.isOpen ? insertAndReplace() : clear();
},
+ /**
+ * Closes the menu when clicking outside, if appropriate.
+ *
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClickCaptureGlobal(ev) {
+ if (!this.exists()) {
+ return;
+ }
+ if (!this.component) {
+ return;
+ }
+ // ignore click inside the menu
+ if (!this.component.root.el || this.component.root.el.contains(ev.target)) {
+ return;
+ }
+ // in all other cases: close the messaging menu when clicking outside
+ this.close();
+ },
},
fields: {
/**
diff --git a/addons/mail/static/src/models/notification_group_view.js b/addons/mail/static/src/models/notification_group_view.js
index f73db4f9fd7..379c5fbd240 100644
--- a/addons/mail/static/src/models/notification_group_view.js
+++ b/addons/mail/static/src/models/notification_group_view.js
@@ -2,6 +2,7 @@
import { registerModel } from '@mail/model/model_core';
import { attr, one } from '@mail/model/model_field';
+import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'NotificationGroupView',
@@ -30,8 +31,21 @@ registerModel({
onClickMarkAsRead(ev) {
this.notificationGroup.notifyCancel();
},
+ /**
+ * @private
+ * @returns {string|undefined}
+ */
+ _computeImageSrc() {
+ if (this.notificationGroup.notification_type === 'email') {
+ return '/mail/static/src/img/smiley/mailfailure.jpg';
+ }
+ return clear();
+ },
},
fields: {
+ imageSrc: attr({
+ compute: '_computeImageSrc',
+ }),
/**
* Reference of the "mark as read" button. Useful to disable the
* top-level click handler when clicking on this specific button.
diff --git a/addons/mail/static/src/models/notification_list_view.js b/addons/mail/static/src/models/notification_list_view.js
index 81c03a53bce..f6d029492c4 100644
--- a/addons/mail/static/src/models/notification_list_view.js
+++ b/addons/mail/static/src/models/notification_list_view.js
@@ -7,6 +7,11 @@ import { clear, insertAndReplace, replace } from '@mail/model/model_field_comman
registerModel({
name: 'NotificationListView',
identifyingFields: [['discussOwner', 'messagingMenuOwner']],
+ lifecycleHooks: {
+ _created() {
+ this._loadPreviews();
+ },
+ },
recordMethods: {
/**
* @private
@@ -183,6 +188,17 @@ registerModel({
})
);
},
+ /**
+ * Load previews of given thread. Basically consists of fetching all missing
+ * last messages of each thread.
+ *
+ * @private
+ */
+ async _loadPreviews() {
+ const threads = this.threadPreviewViews
+ .map(threadPreviewView => threadPreviewView.thread);
+ this.messaging.models['Thread'].loadPreviews(threads);
+ },
},
fields: {
discussOwner: one('Discuss', {
diff --git a/addons/mail/static/src/models/thread.js b/addons/mail/static/src/models/thread.js
index b234bac0218..bb3cd4bdc57 100644
--- a/addons/mail/static/src/models/thread.js
+++ b/addons/mail/static/src/models/thread.js
@@ -1619,7 +1619,7 @@ registerModel({
*/
_computeTypingStatusText() {
if (this.orderedOtherTypingMembers.length === 0) {
- return this.constructor.fields.typingStatusText.default;
+ return clear();
}
if (this.orderedOtherTypingMembers.length === 1) {
return sprintf(
diff --git a/addons/mail/static/tests/helpers/mock_server.js b/addons/mail/static/tests/helpers/mock_server.js
index 8c4dc8a81b9..4ad066ba732 100644
--- a/addons/mail/static/tests/helpers/mock_server.js
+++ b/addons/mail/static/tests/helpers/mock_server.js
@@ -1492,6 +1492,7 @@ MockServer.include({
history_partner_ids: historyPartnerIds,
needaction_partner_ids: needactionPartnerIds,
notifications,
+ parentMessage: message.parent_id ? this._mockMailMessageMessageFormat([message.parent_id])[0] : false,
recipients: partners.map(p => ({ id: p.id, name: p.name })),
record_name: thread && (thread.name !== undefined ? thread.name : thread.display_name),
tracking_value_ids: formattedTrackingValues,
diff --git a/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js
index e8dea292876..21421dd2dd8 100644
--- a/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js
+++ b/addons/mail/static/tests/qunit_suite_tests/components/channel_invitation_form_tests.js
@@ -77,7 +77,7 @@ QUnit.test('should be able to search for a new user to invite from an existing c
await click(`.o_ThreadViewTopbar_inviteButton`);
await insertText('.o_ChannelInvitationForm_searchInput', "TestPartner2");
assert.strictEqual(
- document.querySelector(`.o_ChannelInvitationForm_selectablePartnerName`).textContent,
+ document.querySelector(`.o_ChannelInvitationFormSelectablePartner_name`).textContent,
"TestPartner2",
"should display 'TestPartner2' as it matches search term",
);
@@ -117,7 +117,7 @@ QUnit.test('should be able to create a new group chat from an existing chat', as
await click(`.o_ThreadViewTopbar_inviteButton`);
await insertText('.o_ChannelInvitationForm_searchInput', "TestPartner2");
- await click(`.o_ChannelInvitationForm_selectablePartnerCheckbox`);
+ await click(`.o_ChannelInvitationFormSelectablePartner_checkbox`);
await click(`.o_ChannelInvitationForm_inviteButton`);
assert.strictEqual(
document.querySelector(`.o_ThreadViewTopbar_threadName`).textContent,
diff --git a/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js
index a1b8f6db184..5ffccc58f0f 100644
--- a/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js
+++ b/addons/mail/static/tests/qunit_suite_tests/components/chat_window_manager_tests.js
@@ -2113,11 +2113,11 @@ QUnit.test('chat window does not fetch messages if hidden', async function (asse
await click('.o_ChatWindowHiddenMenu_dropdownToggle');
assert.containsOnce(
document.body,
- '.o_ChatWindowHiddenMenu_chatWindowHeader',
+ '.o_ChatWindowHiddenMenuItem',
"1 hidden chat window should be listed in hidden menu"
);
- await click('.o_ChatWindowHiddenMenu_chatWindowHeader');
+ await click('.o_ChatWindowHiddenMenuItem_chatWindowHeader');
assert.containsN(
document.body,
'.o_ChatWindow',
diff --git a/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js
index 25deefadc5c..98384436e68 100644
--- a/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js
+++ b/addons/mail/static/tests/qunit_suite_tests/components/composer_tests.js
@@ -207,7 +207,7 @@ QUnit.test('add an emoji', async function (assert) {
});
await createComposerComponent(thread.composer);
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value,
"π",
@@ -234,7 +234,7 @@ QUnit.test('add an emoji after some text', async function (assert) {
);
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value,
"Blablaπ",
@@ -264,7 +264,7 @@ QUnit.test('add emoji replaces (keyboard) text selection', async function (asser
// simulate selection of all the content by keyboard
composerTextInputTextArea.setSelectionRange(0, composerTextInputTextArea.value.length);
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value,
"π",
@@ -416,7 +416,7 @@ QUnit.test('add an emoji after a canned response', async function (assert) {
// select emoji
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value.replace(/\s/, " "),
"Hello! How are you? π",
@@ -564,7 +564,7 @@ QUnit.test('add an emoji after a channel mention', async function (assert) {
// select emoji
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value.replace(/\s/, " "),
"#General π",
@@ -747,7 +747,7 @@ QUnit.test('add an emoji after a command', async function (assert) {
// select emoji
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value.replace(/\s/, " "),
"/who π",
@@ -907,7 +907,7 @@ QUnit.test('add an emoji after a partner mention', async function (assert) {
// select emoji
await click('.o_Composer_buttonEmojis');
- await click('.o_EmojiList_emoji[data-unicode="π"]');
+ await click('.o_Emoji[data-unicode="π"]');
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value.replace(/\s/, " "),
"@TestPartner π",
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 413e030fea8..5d6c2cce502 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
@@ -295,7 +295,7 @@ QUnit.test('reply: discard on click away', async function (assert) {
"emoji list should be opened after clicking on emojis button"
);
- await click(`.o_EmojiList_emoji`);
+ await click(`.o_Emoji`);
assert.containsNone(
document.body,
'.o_EmojiList',
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 52ea33cbef4..df9e2d9b294 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
@@ -4001,5 +4001,37 @@ QUnit.test('send message only once when enter is pressed twice quickly', async f
);
});
+QUnit.test('message being a replied to another message should show message being replied in the message view', async function (assert) {
+ assert.expect(1);
+
+ const pyEnv = await startServer();
+ const mailChannelId1 = pyEnv['mail.channel'].create();
+ const mailMessageId1 = pyEnv['mail.message'].create({
+ body: "1st message",
+ model: 'mail.channel',
+ res_id: mailChannelId1,
+ });
+ const mailMessageId2 = pyEnv['mail.message'].create({
+ body: "2nd message",
+ model: 'mail.channel',
+ parent_id: mailMessageId1,
+ res_id: mailChannelId1,
+ });
+ const { messaging } = await this.start({
+ discuss: {
+ context: {
+ active_id: `mail.channel_${mailChannelId1}`,
+ },
+ },
+ });
+ assert.containsOnce(
+ document.querySelector(`.o_Message[data-message-local-id="${
+ messaging.models['Message'].findFromIdentifyingData({ id: mailMessageId2 }).localId
+ }"]`),
+ '.o_MessageInReplyToView',
+ "message being a replied to another message should show message being replied in the message view",
+ );
+});
+
});
});
diff --git a/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js
index fd02940883b..212442b4be6 100644
--- a/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js
+++ b/addons/mail/static/tests/qunit_suite_tests/components/message_tests.js
@@ -145,26 +145,26 @@ QUnit.test('Notification Sent', async function (assert) {
await click('.o_Message_notificationIconClickable');
assert.containsOnce(
document.body,
- '.o_NotificationPopover',
+ '.o_MessageNotificationPopoverContent',
"notification popover should be open"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationIcon',
+ '.o_MessageNotificationPopoverContent_notificationIcon',
"popover should have one icon"
);
assert.hasClass(
- document.querySelector('.o_NotificationPopover_notificationIcon'),
+ document.querySelector('.o_MessageNotificationPopoverContent_notificationIcon'),
'fa-check',
"popover should have the sent icon"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationPartnerName',
+ '.o_MessageNotificationPopoverContent_notificationPartnerName',
"popover should have the partner name"
);
assert.strictEqual(
- document.querySelector('.o_NotificationPopover_notificationPartnerName').textContent.trim(),
+ document.querySelector('.o_MessageNotificationPopoverContent_notificationPartnerName').textContent.trim(),
"Someone",
"partner name should be correct"
);
diff --git a/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js
index e72aefe30a6..4fb2a4e9bd8 100644
--- a/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js
+++ b/addons/mail/static/tests/qunit_suite_tests/components/thread_view_tests.js
@@ -728,26 +728,26 @@ QUnit.test('basic rendering of canceled notification', async function (assert) {
await click('.o_Message_notificationIconClickable');
assert.containsOnce(
document.body,
- '.o_NotificationPopover',
+ '.o_MessageNotificationPopoverContent',
"notification popover should be opened after notification has been clicked"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationIcon',
+ '.o_MessageNotificationPopoverContent_notificationIcon',
"an icon should be shown in notification popover"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationIcon.fa.fa-trash-o',
+ '.o_MessageNotificationPopoverContent_notificationIcon.fa.fa-trash-o',
"the icon shown in notification popover should be the canceled icon"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationPartnerName',
+ '.o_MessageNotificationPopoverContent_notificationPartnerName',
"partner name should be shown in notification popover"
);
assert.strictEqual(
- document.querySelector('.o_NotificationPopover_notificationPartnerName').textContent.trim(),
+ document.querySelector('.o_MessageNotificationPopoverContent_notificationPartnerName').textContent.trim(),
"Someone",
"partner name shown in notification popover should be the one concerned by the notification"
);
diff --git a/addons/sms/__manifest__.py b/addons/sms/__manifest__.py
index 9252e676299..29a92dfa30e 100644
--- a/addons/sms/__manifest__.py
+++ b/addons/sms/__manifest__.py
@@ -46,7 +46,6 @@ The service is provided by the In App Purchase Odoo platform.
'web.assets_backend': [
'sms/static/src/js/fields_phone_widget.js',
'sms/static/src/js/fields_sms_widget.js',
- 'sms/static/src/components/*/*.js',
'sms/static/src/models/*.js',
],
'web.qunit_suite_tests': [
diff --git a/addons/sms/static/src/components/notification_group/notification_group.js b/addons/sms/static/src/components/notification_group/notification_group.js
deleted file mode 100644
index aa746b9bab7..00000000000
--- a/addons/sms/static/src/components/notification_group/notification_group.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/** @odoo-module **/
-
-import { NotificationGroup } from '@mail/components/notification_group/notification_group';
-
-import { patch } from 'web.utils';
-
-patch(NotificationGroup.prototype, 'sms/static/src/components/notification_group/notification_group.js', {
-
- //--------------------------------------------------------------------------
- // Public
- //--------------------------------------------------------------------------
-
- /**
- * @override
- */
- image() {
- if (this.notificationGroupView.notificationGroup.notification_type === 'sms') {
- return '/sms/static/img/sms_failure.svg';
- }
- return this._super(...arguments);
- },
-});
diff --git a/addons/sms/static/src/models/notification_group_view.js b/addons/sms/static/src/models/notification_group_view.js
new file mode 100644
index 00000000000..9840fc8b96e
--- /dev/null
+++ b/addons/sms/static/src/models/notification_group_view.js
@@ -0,0 +1,17 @@
+/** @odoo-module **/
+
+import { patchRecordMethods } from '@mail/model/model_core';
+// ensure that the model definition is loaded before the patch
+import '@mail/models/notification_group_view';
+
+patchRecordMethods('NotificationGroupView', {
+ /**
+ * @override
+ */
+ _computeImageSrc() {
+ if (this.notificationGroup.notification_type === 'sms') {
+ return '/sms/static/img/sms_failure.svg';
+ }
+ return this._super();
+ },
+});
diff --git a/addons/sms/static/tests/qunit_suite_tests/components/message_tests.js b/addons/sms/static/tests/qunit_suite_tests/components/message_tests.js
index 868c53a5e29..e62f19bc943 100644
--- a/addons/sms/static/tests/qunit_suite_tests/components/message_tests.js
+++ b/addons/sms/static/tests/qunit_suite_tests/components/message_tests.js
@@ -69,26 +69,26 @@ QUnit.test('Notification Sent', async function (assert) {
});
assert.containsOnce(
document.body,
- '.o_NotificationPopover',
+ '.o_MessageNotificationPopoverContent',
"notification popover should be open"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationIcon',
+ '.o_MessageNotificationPopoverContent_notificationIcon',
"popover should have one icon"
);
assert.hasClass(
- document.querySelector('.o_NotificationPopover_notificationIcon'),
+ document.querySelector('.o_MessageNotificationPopoverContent_notificationIcon'),
'fa-check',
"popover should have the sent icon"
);
assert.containsOnce(
document.body,
- '.o_NotificationPopover_notificationPartnerName',
+ '.o_MessageNotificationPopoverContent_notificationPartnerName',
"popover should have the partner name"
);
assert.strictEqual(
- document.querySelector('.o_NotificationPopover_notificationPartnerName').textContent.trim(),
+ document.querySelector('.o_MessageNotificationPopoverContent_notificationPartnerName').textContent.trim(),
"Someone",
"partner name should be correct"
);
diff --git a/addons/snailmail/static/src/components/message/message.xml b/addons/snailmail/static/src/components/message/message.xml
index e1537fd6669..265edb66d81 100644
--- a/addons/snailmail/static/src/components/message/message.xml
+++ b/addons/snailmail/static/src/components/message/message.xml
@@ -20,7 +20,7 @@
It was decided that the information displayed for snailmail messages
has to be different than for standard messages, see task-1907998.
-->
-
+
diff --git a/addons/snailmail/static/src/components/notification_group/notification_group.js b/addons/snailmail/static/src/components/notification_group/notification_group.js
deleted file mode 100644
index 3b71701f897..00000000000
--- a/addons/snailmail/static/src/components/notification_group/notification_group.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/** @odoo-module **/
-
-import { NotificationGroup } from '@mail/components/notification_group/notification_group';
-
-import { patch } from 'web.utils';
-
-patch(NotificationGroup.prototype, 'snailmail/static/src/components/notification_group/notification_group.js', {
-
- //--------------------------------------------------------------------------
- // Public
- //--------------------------------------------------------------------------
-
- /**
- * @override
- */
- image() {
- if (this.notificationGroupView.notificationGroup.notification_type === 'snail') {
- return '/snailmail/static/img/snailmail_failure.png';
- }
- return this._super(...arguments);
- },
-});
diff --git a/addons/snailmail/static/src/models/notification_group_view.js b/addons/snailmail/static/src/models/notification_group_view.js
new file mode 100644
index 00000000000..27316a21934
--- /dev/null
+++ b/addons/snailmail/static/src/models/notification_group_view.js
@@ -0,0 +1,17 @@
+/** @odoo-module **/
+
+import { patchRecordMethods } from '@mail/model/model_core';
+// ensure that the model definition is loaded before the patch
+import '@mail/models/notification_group_view';
+
+patchRecordMethods('NotificationGroupView', {
+ /**
+ * @override
+ */
+ _computeImageSrc() {
+ if (this.notificationGroup.notification_type === 'snail') {
+ return '/snailmail/static/img/snailmail_failure.png';
+ }
+ return this._super();
+ },
+});
diff --git a/addons/test_mail/static/tests/tracking_value_tests.js b/addons/test_mail/static/tests/tracking_value_tests.js
index d2c1b082937..3f047e52894 100644
--- a/addons/test_mail/static/tests/tracking_value_tests.js
+++ b/addons/test_mail/static/tests/tracking_value_tests.js
@@ -52,41 +52,41 @@ QUnit.test('basic rendering of tracking value (float type)', async function (ass
await click('.o_form_button_save');
assert.containsOnce(
document.body,
- '.o_Message_trackingValue',
+ '.o_TrackingValue',
"should display a tracking value"
);
assert.containsOnce(
document.body,
- '.o_Message_trackingValueFieldName',
+ '.o_TrackingValue_fieldName',
"should display the name of the tracked field"
);
assert.strictEqual(
- document.querySelector('.o_Message_trackingValueFieldName').textContent,
+ document.querySelector('.o_TrackingValue_fieldName').textContent,
"Float:",
"should display the correct tracked field name (Float)",
);
assert.containsOnce(
document.body,
- '.o_Message_trackingValueOldValue',
+ '.o_TrackingValue_oldValue',
"should display the old value"
);
assert.strictEqual(
- document.querySelector('.o_Message_trackingValueOldValue').textContent,
+ document.querySelector('.o_TrackingValue_oldValue').textContent,
"12.30",
"should display the correct old value (12.30)",
);
assert.containsOnce(
document.body,
- '.o_Message_trackingValueSeparator',
+ '.o_TrackingValue_separator',
"should display the separator"
);
assert.containsOnce(
document.body,
- '.o_Message_trackingValueNewValue',
+ '.o_TrackingValue_newValue',
"should display the new value"
);
assert.strictEqual(
- document.querySelector('.o_Message_trackingValueNewValue').textContent,
+ document.querySelector('.o_TrackingValue_newValue').textContent,
"45.67",
"should display the correct new value (45.67)",
);
@@ -102,7 +102,7 @@ QUnit.test('rendering of tracked field of type float: from non-0 to 0', async fu
await testUtils.fields.editInput(form.$('input[name=float_field]'), 0);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Float:1.000.00",
"should display the correct content of tracked field of type float: from non-0 to 0 (Float: 1.00 -> 0.00)"
);
@@ -118,7 +118,7 @@ QUnit.test('rendering of tracked field of type float: from 0 to non-0', async fu
await testUtils.fields.editInput(form.$('input[name=float_field]'), 1);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Float:0.001.00",
"should display the correct content of tracked field of type float: from 0 to non-0 (Float: 0.00 -> 1.00)"
);
@@ -134,7 +134,7 @@ QUnit.test('rendering of tracked field of type integer: from non-0 to 0', async
await testUtils.fields.editInput(form.$('input[name=integer_field]'), 0);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Integer:10",
"should display the correct content of tracked field of type integer: from non-0 to 0 (Integer: 1 -> 0)"
);
@@ -150,7 +150,7 @@ QUnit.test('rendering of tracked field of type integer: from 0 to non-0', async
await testUtils.fields.editInput(form.$('input[name=integer_field]'), 1);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Integer:01",
"should display the correct content of tracked field of type integer: from 0 to non-0 (Integer: 0 -> 1)"
);
@@ -166,7 +166,7 @@ QUnit.test('rendering of tracked field of type monetary: from non-0 to 0', async
await testUtils.fields.editSelect(form.$('div[name=monetary_field] > input'), 0);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Monetary:1.000.00",
"should display the correct content of tracked field of type monetary: from non-0 to 0 (Monetary: 1.00 -> 0.00)"
);
@@ -182,7 +182,7 @@ QUnit.test('rendering of tracked field of type monetary: from 0 to non-0', async
await testUtils.fields.editSelect(form.$('div[name=monetary_field] > input'), 1);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Monetary:0.001.00",
"should display the correct content of tracked field of type monetary: from 0 to non-0 (Monetary: 0.00 -> 1.00)"
);
@@ -198,7 +198,7 @@ QUnit.test('rendering of tracked field of type boolean: from true to false', asy
form.$('.custom-checkbox input').click();
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Boolean:YesNo",
"should display the correct content of tracked field of type boolean: from true to false (Boolean: True -> False)"
);
@@ -214,7 +214,7 @@ QUnit.test('rendering of tracked field of type boolean: from false to true', asy
form.$('.custom-checkbox input').click();
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Boolean:NoYes",
"should display the correct content of tracked field of type boolean: from false to true (Boolean: False -> True)"
);
@@ -230,7 +230,7 @@ QUnit.test('rendering of tracked field of type char: from a string to empty stri
await testUtils.fields.editInput(form.$('input[name=char_field]'), '');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Char:MarcNone",
"should display the correct content of tracked field of type char: from a string to empty string (Char: Marc -> None)"
);
@@ -246,7 +246,7 @@ QUnit.test('rendering of tracked field of type char: from empty string to a stri
await testUtils.fields.editInput(form.$('input[name=char_field]'), 'Marc');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Char:NoneMarc",
"should display the correct content of tracked field of type char: from empty string to a string (Char: None -> Marc)"
);
@@ -262,7 +262,7 @@ QUnit.test('rendering of tracked field of type date: from no date to a set date'
await testUtils.fields.editAndTrigger(form.$('.o_datepicker[name=date_field] .o_datepicker_input'), '12/14/2018', ['change']);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Date:None12/14/2018",
"should display the correct content of tracked field of type date: from no date to a set date (Date: None -> 12/14/2018)"
);
@@ -278,7 +278,7 @@ QUnit.test('rendering of tracked field of type date: from a set date to no date'
await testUtils.fields.editAndTrigger(form.$('.o_datepicker[name=date_field] .o_datepicker_input'), '', ['change']);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Date:12/14/2018None",
"should display the correct content of tracked field of type date: from a set date to no date (Date: 12/14/2018 -> None)"
);
@@ -294,7 +294,7 @@ QUnit.test('rendering of tracked field of type datetime: from no date and time t
await testUtils.fields.editAndTrigger(form.$('.o_datepicker[name=datetime_field] .o_datepicker_input'), '12/14/2018 13:42:28', ['change']);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Datetime:None12/14/2018 13:42:28",
"should display the correct content of tracked field of type datetime: from no date and time to a set date and time (Datetime: None -> 12/14/2018 13:42:28)"
);
@@ -310,7 +310,7 @@ QUnit.test('rendering of tracked field of type datetime: from a set date and tim
await testUtils.fields.editAndTrigger(form.$('.o_datepicker[name=datetime_field] .o_datepicker_input'), '', ['change']);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Datetime:12/14/2018 13:42:28None",
"should display the correct content of tracked field of type datetime: from a set date and time to no date and time (Datetime: 12/14/2018 13:42:28 -> None)"
);
@@ -326,7 +326,7 @@ QUnit.test('rendering of tracked field of type text: from some text to empty', a
await testUtils.fields.editInput(form.$('textarea[name=text_field]'), '');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Text:MarcNone",
"should display the correct content of tracked field of type text: from some text to empty (Text: Marc -> None)"
);
@@ -342,7 +342,7 @@ QUnit.test('rendering of tracked field of type text: from empty to some text', a
await testUtils.fields.editInput(form.$('textarea[name=text_field]'), 'Marc');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Text:NoneMarc",
"should display the correct content of tracked field of type text: from empty to some text (Text: None -> Marc)"
);
@@ -358,7 +358,7 @@ QUnit.test('rendering of tracked field of type selection: from a selection to no
await testUtils.fields.editSelect(form.$('select[name=selection_field]'), '');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Selection:firstNone",
"should display the correct content of tracked field of type selection: from a selection to no selection (Selection: first -> None)"
);
@@ -374,7 +374,7 @@ QUnit.test('rendering of tracked field of type selection: from no selection to a
await testUtils.fields.editSelect(form.$('select[name=selection_field]'), '"first"');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Selection:Nonefirst",
"should display the correct content of tracked field of type selection: from no selection to a selection (Selection: None -> first)"
);
@@ -391,7 +391,7 @@ QUnit.test('rendering of tracked field of type many2one: from having a related r
await testUtils.fields.editAndTrigger(form.$('.o_field_many2one_selection input'), '', ['keyup']);
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Many2one:MarcNone",
"should display the correct content of tracked field of type many2one: from having a related record to no related record (Many2one: Marc -> None)"
);
@@ -409,7 +409,7 @@ QUnit.test('rendering of tracked field of type many2one: from no related record
await testUtils.fields.many2one.clickItem('many2one_field_id', 'Marc');
await click('.o_form_button_save');
assert.strictEqual(
- document.querySelector('.o_Message_trackingValue').textContent,
+ document.querySelector('.o_TrackingValue').textContent,
"Many2one:NoneMarc",
"should display the correct content of tracked field of type many2one: from no related record to having a related record (Many2one: None -> Marc)"
);