diff --git a/addons/mail/static/src/components/activity_box/activity_box.scss b/addons/mail/static/src/components/activity_box/activity_box.scss deleted file mode 100644 index cf03cccb875..00000000000 --- a/addons/mail/static/src/components/activity_box/activity_box.scss +++ /dev/null @@ -1,15 +0,0 @@ -// ------------------------------------------------------------------ -// Layout -// ------------------------------------------------------------------ - -.o_ActivityBoxView_activityList { - max-width: var(--Chatter-max-width, none); -} - -// ------------------------------------------------------------------ -// Style -// ------------------------------------------------------------------ - -.o_ActivityBoxView_titleLine { - border-top: $border-width $border-color dashed; -} diff --git a/addons/mail/static/src/components/activity_box/activity_box.xml b/addons/mail/static/src/components/activity_box/activity_box.xml deleted file mode 100644 index f5e2829c74e..00000000000 --- a/addons/mail/static/src/components/activity_box/activity_box.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/addons/mail/static/src/components/attachment_box/attachment_box.scss b/addons/mail/static/src/components/attachment_box/attachment_box.scss deleted file mode 100644 index 77d212e5c1d..00000000000 --- a/addons/mail/static/src/components/attachment_box/attachment_box.scss +++ /dev/null @@ -1,7 +0,0 @@ -// ------------------------------------------------------------------ -// Style -// ------------------------------------------------------------------ - -.o_AttachmentBoxView_dashedLine { - border-top: $border-width dashed $border-color; -} diff --git a/addons/mail/static/src/components/attachment_box/attachment_box.xml b/addons/mail/static/src/components/attachment_box/attachment_box.xml deleted file mode 100644 index 6b85bb143ee..00000000000 --- a/addons/mail/static/src/components/attachment_box/attachment_box.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - -
-
-
- - Files - -
-
-
- - -
-
-
- -
diff --git a/addons/mail/static/src/components/chatter_topbar/chatter_topbar.scss b/addons/mail/static/src/components/chatter/chatter.scss similarity index 61% rename from addons/mail/static/src/components/chatter_topbar/chatter_topbar.scss rename to addons/mail/static/src/components/chatter/chatter.scss index 97628dcc59e..25f6dac9168 100644 --- a/addons/mail/static/src/components/chatter_topbar/chatter_topbar.scss +++ b/addons/mail/static/src/components/chatter/chatter.scss @@ -31,3 +31,24 @@ .o_ChatterTopbar_buttonClose { width: $o-statusbar-height; } + +.o_ActivityBoxView_activityList { + max-width: var(--Chatter-max-width, none); +} + +// ------------------------------------------------------------------ +// Style +// ------------------------------------------------------------------ + +.o_ActivityBoxView_titleLine { + border-top: $border-width $border-color dashed; +} + + +.o_AttachmentBoxView_dashedLine { + border-top: $border-width dashed $border-color; +} + +.o_FollowButtonView_unfollow:focus { + background-color: $gray-200; +} diff --git a/addons/mail/static/src/components/chatter/chatter.xml b/addons/mail/static/src/components/chatter/chatter.xml index 9f1799819b9..8a9cb63f7fd 100644 --- a/addons/mail/static/src/components/chatter/chatter.xml +++ b/addons/mail/static/src/components/chatter/chatter.xml @@ -8,11 +8,91 @@ record="dropZoneView" />
- +
+
+
+ + +
+
+ +
+
+ + + + +
+ + +
+
+
+
+
+ +
- - +
+
+
+ + Files + +
+
+
+ + +
+
+ - - - -
-
-
- - -
-
- -
-
- - - - - - -
-
-
- -
- - - diff --git a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.scss b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.scss deleted file mode 100644 index 6c25ad50e0a..00000000000 --- a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o_EmojiCategoryBarView { - background-color: var(--EmojiCategoryBarView-background-color, #{$o-gray-200}); -} diff --git a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml deleted file mode 100644 index 44046bb3a83..00000000000 --- a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
- -
-
- -
diff --git a/addons/mail/static/src/components/emoji_grid_item_view/emoji_grid_item_view.xml b/addons/mail/static/src/components/emoji_grid_item_view/emoji_grid_item_view.xml deleted file mode 100644 index dbd3a6aa8d1..00000000000 --- a/addons/mail/static/src/components/emoji_grid_item_view/emoji_grid_item_view.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - -
- -
-
-
diff --git a/addons/mail/static/src/components/emoji_grid_loading_screen/emoji_grid_loading_screen.xml b/addons/mail/static/src/components/emoji_grid_loading_screen/emoji_grid_loading_screen.xml deleted file mode 100644 index 29f49f321eb..00000000000 --- a/addons/mail/static/src/components/emoji_grid_loading_screen/emoji_grid_loading_screen.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
-
- -
- - diff --git a/addons/mail/static/src/components/emoji_grid_row_view/emoji_grid_row_view.xml b/addons/mail/static/src/components/emoji_grid_row_view/emoji_grid_row_view.xml index 57ce507246b..a6184ce3e9e 100644 --- a/addons/mail/static/src/components/emoji_grid_row_view/emoji_grid_row_view.xml +++ b/addons/mail/static/src/components/emoji_grid_row_view/emoji_grid_row_view.xml @@ -3,9 +3,11 @@
- +
+ +
- +
diff --git a/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.scss b/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.scss deleted file mode 100644 index 366de627326..00000000000 --- a/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.scss +++ /dev/null @@ -1,5 +0,0 @@ - -.o_EmojiGridSearchNoContentView_image { - filter: grayscale(1); - font-size: 5rem; -} diff --git a/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.xml b/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.xml deleted file mode 100644 index 018306ffc98..00000000000 --- a/addons/mail/static/src/components/emoji_grid_search_no_content_view/emoji_grid_search_no_content_view.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
-
😢
- -
-
-
diff --git a/addons/mail/static/src/components/emoji_grid_section_view/emoji_grid_section_view.xml b/addons/mail/static/src/components/emoji_grid_section_view/emoji_grid_section_view.xml deleted file mode 100644 index ed6628be60e..00000000000 --- a/addons/mail/static/src/components/emoji_grid_section_view/emoji_grid_section_view.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - -
- -
-
-
diff --git a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml index 9858cf4f4aa..8ed58e7ac3c 100644 --- a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml +++ b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml @@ -3,9 +3,15 @@
- - -
+
+
+ +
+
+
😢
+ +
+
diff --git a/addons/mail/static/src/components/emoji_picker_header_action_list_view/emoji_picker_header_action_list_view.xml b/addons/mail/static/src/components/emoji_picker_header_action_list_view/emoji_picker_header_action_list_view.xml deleted file mode 100644 index f6b6d9e4007..00000000000 --- a/addons/mail/static/src/components/emoji_picker_header_action_list_view/emoji_picker_header_action_list_view.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
- -
-
- -
diff --git a/addons/mail/static/src/components/emoji_picker_header_view/emoji_picker_header_view.xml b/addons/mail/static/src/components/emoji_picker_header_view/emoji_picker_header_view.xml deleted file mode 100644 index 6354b90483e..00000000000 --- a/addons/mail/static/src/components/emoji_picker_header_view/emoji_picker_header_view.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - -
- - - -
-
- -
diff --git a/addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.scss b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss similarity index 66% rename from addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.scss rename to addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss index e8acc6edea2..ecf0a6e9a79 100644 --- a/addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.scss +++ b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss @@ -13,3 +13,12 @@ .o_EmojiSearchBarView_searchInput:focus { outline: none; } + +.o_EmojiCategoryBarView { + background-color: var(--EmojiCategoryBarView-background-color, #{$o-gray-200}); +} + +.o_EmojiGridSearchNoContentView_image { + filter: grayscale(1); + font-size: 5rem; +} diff --git a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml index 007517815c4..9ff0d29da3f 100644 --- a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml +++ b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml @@ -3,8 +3,21 @@
- - +
+
+ +
+ +
+ +
+
+
+
+ + +
+
diff --git a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.dark.scss b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view_dark.scss similarity index 100% rename from addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.dark.scss rename to addons/mail/static/src/components/emoji_picker_view/emoji_picker_view_dark.scss diff --git a/addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.xml b/addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.xml deleted file mode 100644 index c801f2be12b..00000000000 --- a/addons/mail/static/src/components/emoji_search_bar_view/emoji_search_bar_view.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - -
-
- - -
-
-
- -
diff --git a/addons/mail/static/src/components/emoji_view/emoji_view.xml b/addons/mail/static/src/components/emoji_view/emoji_view.xml index 0f98ca000d5..2daf4f5e506 100644 --- a/addons/mail/static/src/components/emoji_view/emoji_view.xml +++ b/addons/mail/static/src/components/emoji_view/emoji_view.xml @@ -2,7 +2,9 @@ - +
+ +
diff --git a/addons/mail/static/src/components/follow_button/follow_button.scss b/addons/mail/static/src/components/follow_button/follow_button.scss deleted file mode 100644 index 73e68fa6dc4..00000000000 --- a/addons/mail/static/src/components/follow_button/follow_button.scss +++ /dev/null @@ -1,3 +0,0 @@ -.o_FollowButtonView_unfollow:focus { - background-color: $gray-200; -} diff --git a/addons/mail/static/src/components/follow_button/follow_button.xml b/addons/mail/static/src/components/follow_button/follow_button.xml deleted file mode 100644 index 0f6b64954b8..00000000000 --- a/addons/mail/static/src/components/follow_button/follow_button.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - -
- - -
-
- -
diff --git a/addons/mail/static/src/models/activity_box_view.js b/addons/mail/static/src/models/activity_box_view.js deleted file mode 100644 index a828f86c8a1..00000000000 --- a/addons/mail/static/src/models/activity_box_view.js +++ /dev/null @@ -1,29 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { attr, many, one } from '@mail/model/model_field'; - -registerModel({ - name: 'ActivityBoxView', - template: 'mail.ActivityBoxView', - recordMethods: { - /** - * Handles click on activity box title. - */ - onClickActivityBoxTitle(ev) { - ev.preventDefault(); - this.update({ isActivityListVisible: !this.isActivityListVisible }); - }, - }, - fields: { - activityViews: many('ActivityView', { inverse: 'activityBoxView', - compute() { - return this.chatter.thread.activities.map(activity => { - return { activity }; - }); - }, - }), - chatter: one('Chatter', { identifying: true, inverse: 'activityBoxView' }), - isActivityListVisible: attr({ default: true }), - }, -}); diff --git a/addons/mail/static/src/models/activity_mark_done_popover_content_view.js b/addons/mail/static/src/models/activity_mark_done_popover_content_view.js index 5a619c25fb3..8e9ed116cea 100644 --- a/addons/mail/static/src/models/activity_mark_done_popover_content_view.js +++ b/addons/mail/static/src/models/activity_mark_done_popover_content_view.js @@ -39,7 +39,7 @@ registerModel({ * Handles click on this "Done" button. */ async onClickDone() { - const chatter = this.activityViewOwner && this.activityViewOwner.activityBoxView.chatter; + const chatter = this.activityViewOwner && this.activityViewOwner.chatterOwner; const reloadFunc = this.reloadFunc; const webRecord = this.webRecord; const thread = this.activity.thread; @@ -60,7 +60,7 @@ registerModel({ * Handles click on this "Done & Schedule Next" button. */ async onClickDoneAndScheduleNext() { - const chatter = this.activityViewOwner && this.activityViewOwner.activityBoxView.chatter; + const chatter = this.activityViewOwner && this.activityViewOwner.chatterOwner; const reloadFunc = this.reloadFunc; const webRecord = this.webRecord; const thread = this.activity.thread; diff --git a/addons/mail/static/src/models/activity_view.js b/addons/mail/static/src/models/activity_view.js index bf0227c8118..7ab8674091e 100644 --- a/addons/mail/static/src/models/activity_view.js +++ b/addons/mail/static/src/models/activity_view.js @@ -34,7 +34,7 @@ registerModel({ * Handles the click on the cancel button */ async onClickCancel() { - const { chatter } = this.activityBoxView; // save value before deleting activity + const chatter = this.chatterOwner; // save value before deleting activity await this.activity.deleteServerRecord(); if (chatter.exists() && chatter.component) { chatter.reloadParentView(); @@ -51,7 +51,7 @@ registerModel({ * Handles the click on the edit button */ async onClickEdit() { - const { chatter } = this.activityBoxView; + const chatter = this.chatterOwner; await this.activity.edit(); if (chatter.exists() && chatter.component) { chatter.reloadParentView(); @@ -70,7 +70,6 @@ registerModel({ }, fields: { activity: one('Activity', { identifying: true, inverse: 'activityViews' }), - activityBoxView: one('ActivityBoxView', { identifying: true, inverse: 'activityViews' }), /** * Determines whether the details are visible. */ @@ -86,6 +85,7 @@ registerModel({ return sprintf(this.env._t("for %s"), this.activity.assignee.nameOrDisplayName); }, }), + chatterOwner: one('Chatter', { identifying: true, inverse: 'activityViews' }), clockWatcher: one('ClockWatcher', { default: { clock: { frequency: 60 * 1000 } }, inverse: 'activityViewOwner' }), /** * Compute the label for "when" the activity is due. diff --git a/addons/mail/static/src/models/attachment_box_view.js b/addons/mail/static/src/models/attachment_box_view.js deleted file mode 100644 index 5fb035cc6ea..00000000000 --- a/addons/mail/static/src/models/attachment_box_view.js +++ /dev/null @@ -1,40 +0,0 @@ -/** @odoo-module **/ - -import { useComponentToModel } from '@mail/component_hooks/use_component_to_model'; -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: 'AttachmentBoxView', - template: 'mail.AttachmentBoxView', - componentSetup() { - useComponentToModel({ fieldName: 'component' }); - }, - recordMethods: { - /** - * Handles click on the "add attachment" button. - */ - onClickAddAttachment() { - this.fileUploader.openBrowserFileUploader(); - }, - }, - fields: { - /** - * Determines the attachment list that will be used to display the attachments. - */ - attachmentList: one('AttachmentList', { inverse: 'attachmentBoxViewOwner', - compute() { - return (this.chatter.thread && this.chatter.thread.allAttachments.length > 0) - ? {} - : clear(); - }, - }), - chatter: one('Chatter', { identifying: true, inverse: 'attachmentBoxView' }), - /** - * States the OWL component displaying this attachment box. - */ - component: attr(), - fileUploader: one('FileUploader', { default: {}, inverse: 'attachmentBoxView', readonly: true, required: true }), - }, -}); diff --git a/addons/mail/static/src/models/attachment_delete_confirm_view.js b/addons/mail/static/src/models/attachment_delete_confirm_view.js index c846e2936ed..2ad7f2e6766 100644 --- a/addons/mail/static/src/models/attachment_delete_confirm_view.js +++ b/addons/mail/static/src/models/attachment_delete_confirm_view.js @@ -54,17 +54,15 @@ registerModel({ compute() { if ( this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm && - this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner && - this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner.chatter + this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm.attachmentList.chatterOwner ) { - return this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner.chatter; + return this.dialogOwner.attachmentCardOwnerAsAttachmentDeleteConfirm.attachmentList.chatterOwner; } if ( this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm && - this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner && - this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner.chatter + this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm.attachmentList.chatterOwner ) { - return this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm.attachmentList.attachmentBoxViewOwner.chatter; + return this.dialogOwner.attachmentImageOwnerAsAttachmentDeleteConfirm.attachmentList.chatterOwner; } return clear(); }, diff --git a/addons/mail/static/src/models/attachment_image.js b/addons/mail/static/src/models/attachment_image.js index ae9b157c36d..fe054928e6f 100644 --- a/addons/mail/static/src/models/attachment_image.js +++ b/addons/mail/static/src/models/attachment_image.js @@ -90,7 +90,7 @@ registerModel({ if (this.attachmentList.composerViewOwner) { return 50; } - if (this.attachmentList.attachmentBoxViewOwner) { + if (this.attachmentList.chatterOwner) { return 160; } if (this.attachmentList.messageViewOwner) { diff --git a/addons/mail/static/src/models/attachment_list.js b/addons/mail/static/src/models/attachment_list.js index 7ba62382630..7ce11f8c39a 100644 --- a/addons/mail/static/src/models/attachment_list.js +++ b/addons/mail/static/src/models/attachment_list.js @@ -28,9 +28,9 @@ registerModel({ }, fields: { /** - * Link with a AttachmentBoxView to handle attachments. + * Link with a chatter to handle attachments. */ - attachmentBoxViewOwner: one('AttachmentBoxView', { identifying: true, inverse: 'attachmentList' }), + chatterOwner: one('Chatter', { identifying: true, inverse: 'attachmentList' }), /** * States the attachment cards that are displaying this nonImageAttachments. */ @@ -56,8 +56,8 @@ registerModel({ if (this.messageViewOwner) { return this.messageViewOwner.message.attachments; } - if (this.attachmentBoxViewOwner) { - return this.attachmentBoxViewOwner.chatter.thread.allAttachments; + if (this.chatterOwner) { + return this.chatterOwner.thread.allAttachments; } if (this.composerViewOwner && this.composerViewOwner.composer) { return this.composerViewOwner.composer.attachments; diff --git a/addons/mail/static/src/models/chatter.js b/addons/mail/static/src/models/chatter.js index 4f20ff5621d..d73273e5e02 100644 --- a/addons/mail/static/src/models/chatter.js +++ b/addons/mail/static/src/models/chatter.js @@ -2,7 +2,7 @@ import { useComponentToModel } from '@mail/component_hooks/use_component_to_model'; 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, insert, link } from '@mail/model/model_field_command'; const getThreadNextTemporaryId = (function () { @@ -40,6 +40,13 @@ registerModel({ isShowingAttachmentsLoading: true, }); }, + /** + * Handles click on activity box title. + */ + onClickActivityBoxTitle(ev) { + ev.preventDefault(); + this.update({ isActivityListVisible: !this.isActivityListVisible }); + }, /** * Handles click on the attach button. */ @@ -50,7 +57,7 @@ registerModel({ * Handles click on the attachments button. */ onClickButtonToggleAttachments() { - this.update({ attachmentBoxView: this.attachmentBoxView ? clear() : {} }); + this.update({ hasAttachmentBox: this.hasAttachmentBox ? clear() : true }); }, /** * Handles click on top bar close button. @@ -60,6 +67,15 @@ registerModel({ onClickChatterTopbarClose(ev) { this.component.trigger('o-close-chatter'); }, + /** + * @param {MouseEvent} ev + */ + onClickFollow(ev) { + if (!this.exists() || !this.thread) { + return; + } + this.thread.follow(); + }, /** * Handles click on "log note" button. * @@ -95,6 +111,34 @@ registerModel({ this.showSendMessage(); } }, + /** + * @param {MouseEvent} ev + */ + onClickUnfollow(ev) { + if (!this.exists() || !this.thread) { + return; + } + this.thread.unfollow(); + this.reloadParentView({ fieldNames: ['message_follower_ids'] }); + }, + /** + * @param {MouseEvent} ev + */ + onMouseEnterUnfollow(ev) { + if (!this.exists()) { + return; + } + this.update({ isUnfollowButtonHighlighted: true }); + }, + /** + * @param {MouseEvent} ev + */ + onMouseleaveUnfollow(ev) { + if (!this.exists()) { + return; + } + this.update({ isUnfollowButtonHighlighted: false }); + }, /** * Handles scroll on this scroll panel. * @@ -106,8 +150,8 @@ registerModel({ } this.threadView.messageListView.onScroll(); }, - openAttachmentBoxView() { - this.update({ attachmentBoxView: {} }); + openAttachmentBox() { + this.update({ hasAttachmentBox: true }); }, /** * Open a dialog to add partners as followers. @@ -186,7 +230,7 @@ registerModel({ this.thread.delete(); } this.update({ - attachmentBoxView: this.isAttachmentBoxVisibleInitially ? {} : clear(), + hasAttachmentBox: this.isAttachmentBoxVisibleInitially ? true : clear(), thread: insert({ // If the thread was considered to have the activity // mixin once, it will have it forever. @@ -205,7 +249,7 @@ registerModel({ }); const nextId = getThreadNextTemporaryId(); this.update({ - attachmentBoxView: clear(), + hasAttachmentBox: clear(), thread: insert({ areAttachmentsLoaded: true, id: nextId, @@ -240,15 +284,41 @@ registerModel({ }, }, fields: { - activityBoxView: one('ActivityBoxView', { inverse: 'chatter', + activityViews: many('ActivityView', { inverse: 'chatterOwner', compute() { - if (this.thread && this.thread.hasActivities && this.thread.activities.length > 0) { - return {}; + if (!this.thread) { + return clear(); } - return clear(); + return this.thread.activities.map(activity => { + return { activity }; + }); + }, + }), + /** + * Determines the attachment list that will be used to display the attachments. + */ + attachmentList: one('AttachmentList', { inverse: 'chatterOwner', + compute() { + return (this.thread && this.thread.allAttachments.length > 0) + ? {} + : clear(); + }, + }), + /** + * Determines the label on the attachment button of the topbar. + */ + attachmentButtonText: attr({ default: "", + compute() { + if (!this.thread) { + return clear(); + } + const attachments = this.thread.allAttachments; + if (attachments.length === 0) { + return clear(); + } + return attachments.length; }, }), - attachmentBoxView: one('AttachmentBoxView', { inverse: 'chatter' }), attachmentsLoaderTimer: one('Timer', { inverse: 'chatterOwnerAsAttachmentsLoader' }), /** * States the OWL Chatter component of this chatter. @@ -275,14 +345,6 @@ registerModel({ return this.thread ? {} : clear(); }, }), - followButtonView: one('FollowButtonView', { inverse: 'chatterOwner', - compute() { - if (this.hasFollowers && this.thread && (!this.thread.channel || this.thread.channel.channel_type !== 'chat')) { - return {}; - } - return clear(); - }, - }), followerListMenuView: one('FollowerListMenuView', { inverse: 'chatterOwner', compute() { if (this.hasFollowers && this.thread) { @@ -291,11 +353,36 @@ registerModel({ return clear(); }, }), + /** + * Text displayed by the follow button when not already followed. + */ + followingText: attr({ + compute() { + return this.env._t("Following"); + }, + }), /** * Determines whether `this` should display an activity box. */ hasActivities: attr({ default: true }), + hasActivityBox: attr({ default: false, + compute() { + if (this.thread && this.thread.hasActivities && this.thread.activities.length > 0) { + return true; + } + return clear(); + }, + }), + hasAttachmentBox: attr({ default: false }), hasExternalBorder: attr({ default: true }), + hasFollowButton: attr({ default: false, + compute() { + if (this.hasFollowers && this.thread && (!this.thread.channel || this.thread.channel.channel_type !== 'chat')) { + return true; + } + return clear(); + }, + }), /** * Determines whether `this` should display followers menu. */ @@ -328,6 +415,11 @@ registerModel({ return Boolean(this.thread && this.hasMessageList); }, }), + hasTopBar: attr({ default: false, + compute() { + return this.thread ? true : clear(); + }, + }), hasWriteAccess: attr({ compute() { return Boolean(this.thread && !this.thread.isTemporary && this.thread.hasWriteAccess); @@ -340,10 +432,16 @@ registerModel({ * of this record. */ id: attr({ identifying: true }), + isActivityListVisible: attr({ default: true }), /** * Determiners whether the attachment box is visible initially. */ isAttachmentBoxVisibleInitially: attr({ default: false }), + isFollowButtonDisabled: attr({ + compute() { + return !this.hasReadAccess; + }, + }), isInFormSheetBg: attr({ default: false }), isPreparingAttachmentsLoading: attr({ default: false, compute() { @@ -351,6 +449,7 @@ registerModel({ }, }), isShowingAttachmentsLoading: attr({ default: false }), + isUnfollowButtonHighlighted: attr({ default: false }), scrollPanelRef: attr({ ref: 'scrollPanel' }), /** * Determines whether the view should reload after file changed in this chatter, @@ -392,9 +491,12 @@ registerModel({ }; }, }), - topbar: one('ChatterTopbar', { inverse: 'chatter', + /** + * Text displayed by the follow button when already followed. + */ + unfollowingText: attr({ compute() { - return this.thread ? {} : clear(); + return this.env._t("Unfollow"); }, }), useDragVisibleDropZone: one('UseDragVisibleDropZone', { default: {}, inverse: 'chatterOwner', readonly: true, required: true }), diff --git a/addons/mail/static/src/models/chatter_topbar.js b/addons/mail/static/src/models/chatter_topbar.js deleted file mode 100644 index cea57ac0d62..00000000000 --- a/addons/mail/static/src/models/chatter_topbar.js +++ /dev/null @@ -1,28 +0,0 @@ -/** @odoo-module **/ - -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: 'ChatterTopbar', - template: 'mail.ChatterTopbar', - fields: { - /** - * Determines the label on the attachment button of the topbar. - */ - attachmentButtonText: attr({ default: "", - compute() { - if (!this.chatter || !this.chatter.thread) { - return clear(); - } - const attachments = this.chatter.thread.allAttachments; - if (attachments.length === 0) { - return clear(); - } - return attachments.length; - }, - }), - chatter: one('Chatter', { identifying: true, inverse: 'topbar' }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_category_bar_view.js b/addons/mail/static/src/models/emoji_category_bar_view.js deleted file mode 100644 index 8a9918e47bb..00000000000 --- a/addons/mail/static/src/models/emoji_category_bar_view.js +++ /dev/null @@ -1,22 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { many, one } from '@mail/model/model_field'; -import { clear } from '@mail/model/model_field_command'; - -registerModel({ - name: 'EmojiCategoryBarView', - template: 'mail.EmojiCategoryBarView', - fields: { - emojiCategoryViews: many('EmojiCategoryView', { inverse: 'emojiCategoryBarViewOwner', - compute() { - if (!this.emojiPickerView) { - return clear(); - } - return this.emojiPickerView.categories.map(category => ({ viewCategory: category })); - }, - }), - emojiPickerHeaderViewOwner: one('EmojiPickerHeaderView', { identifying: true, inverse: 'emojiCategoryBarView' }), - emojiPickerView: one('EmojiPickerView', { related: 'emojiPickerHeaderViewOwner.emojiPickerViewOwner' }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_category_view.js b/addons/mail/static/src/models/emoji_category_view.js index a4beb9e71c0..70d2c41f28f 100644 --- a/addons/mail/static/src/models/emoji_category_view.js +++ b/addons/mail/static/src/models/emoji_category_view.js @@ -11,8 +11,8 @@ registerModel({ * @param {MouseEvent} ev */ onClick() { - this.emojiPickerView.emojiSearchBarView.reset(); - this.emojiPickerView.emojiGridView.update({ categorySelectedByUser: this.viewCategory }); + this.emojiPickerViewOwner.reset(); + this.emojiPickerViewOwner.emojiGridView.update({ categorySelectedByUser: this.viewCategory }); }, /** * @param {MouseEvent} ev @@ -35,8 +35,7 @@ registerModel({ }, fields: { category: one('EmojiCategory', { related: 'viewCategory.category' }), - emojiCategoryBarViewOwner: one('EmojiCategoryBarView', { identifying: true, inverse: 'emojiCategoryViews' }), - emojiPickerView: one('EmojiPickerView', { related: 'emojiCategoryBarViewOwner.emojiPickerView' }), + emojiPickerViewOwner: one('EmojiPickerView', { identifying: true, inverse: 'emojiCategoryViews' }), isActive: attr({ compute() { return Boolean(this.viewCategory.emojiPickerViewAsActive); diff --git a/addons/mail/static/src/models/emoji_grid_item_view.js b/addons/mail/static/src/models/emoji_grid_item_view.js deleted file mode 100644 index 826c32db11c..00000000000 --- a/addons/mail/static/src/models/emoji_grid_item_view.js +++ /dev/null @@ -1,33 +0,0 @@ -/** @odoo-module **/ - -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: 'EmojiGridItemView', - template: 'mail.EmojiGridItemView', - fields: { - emojiOrEmojiInCategory: one('EmojiOrEmojiInCategory', { identifying: true, inverse: 'emojiGridItemViews' }), - emojiGridRowViewOwner: one('EmojiGridRowView', { identifying: true, inverse: 'items' }), - emojiView: one('EmojiView', { inverse: 'emojiGridItemViewOwner', - compute() { - if (this.emojiOrEmojiInCategory.emoji) { - return { emoji: this.emojiOrEmojiInCategory.emoji }; - } - if (this.emojiOrEmojiInCategory.emojiInCategory) { - return { emoji: this.emojiOrEmojiInCategory.emojiInCategory.emoji }; - } - return clear(); - }, - }), - width: attr({ default: 0, - compute() { - if (!this.emojiGridRowViewOwner.emojiGridViewOwner) { - return clear(); - } - return this.emojiGridRowViewOwner.emojiGridViewOwner.itemWidth; - }, - }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_grid_loading_screen.js b/addons/mail/static/src/models/emoji_grid_loading_screen.js deleted file mode 100644 index f28813b90f7..00000000000 --- a/addons/mail/static/src/models/emoji_grid_loading_screen.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { attr, one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiGridLoadingScreen', - template: 'mail.EmojiGridLoadingScreen', - fields: { - emojiGridViewOwner: one('EmojiGridView', { identifying: true, inverse: 'loadingScreenView' }), - text: attr({ - compute() { - return this.env._t("Loading..."); - }, - }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_grid_row_view.js b/addons/mail/static/src/models/emoji_grid_row_view.js index 4bd9da4a7d7..4344197f378 100644 --- a/addons/mail/static/src/models/emoji_grid_row_view.js +++ b/addons/mail/static/src/models/emoji_grid_row_view.js @@ -8,17 +8,18 @@ registerModel({ name: 'EmojiGridRowView', template: 'mail.EmojiGridRowView', fields: { + category: one('EmojiCategory', { related: 'viewCategory.category' }), emojiGridViewOwner: one('EmojiGridView', { related: 'emojiGridViewRowRegistryOwner.emojiGridViewOwner' }), - index: attr({ identifying: true }), - items: many('EmojiGridItemView', { inverse: 'emojiGridRowViewOwner' }), - sectionView: one('EmojiGridSectionView', { inverse: 'emojiGridRowViewOwner', + hasSection: attr({ default: false, compute() { if (this.viewCategory) { - return {}; + return true; } return clear(); }, }), + index: attr({ identifying: true }), + items: many('EmojiView', { inverse: 'emojiGridRowViewOwner' }), emojiGridViewRowRegistryOwner: one('EmojiGridViewRowRegistry', { identifying: true, inverse: 'rows' }), viewCategory: one('EmojiPickerView.Category', { inverse: 'emojiGridRowView' }), }, diff --git a/addons/mail/static/src/models/emoji_grid_search_no_content_view.js b/addons/mail/static/src/models/emoji_grid_search_no_content_view.js deleted file mode 100644 index 155c1754451..00000000000 --- a/addons/mail/static/src/models/emoji_grid_search_no_content_view.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { attr, one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiGridSearchNoContentView', - template: 'mail.EmojiGridSearchNoContentView', - fields: { - emojiGridViewOwner: one('EmojiGridView', { identifying: true, inverse: 'searchNoContentView' }), - text: attr({ - compute() { - return this.env._t("No emoji match your search"); - }, - }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_grid_section_view.js b/addons/mail/static/src/models/emoji_grid_section_view.js deleted file mode 100644 index 7afd5de9dff..00000000000 --- a/addons/mail/static/src/models/emoji_grid_section_view.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiGridSectionView', - template: 'mail.EmojiGridSectionView', - fields: { - category: one('EmojiCategory', { related: 'viewCategory.category' }), - emojiGridRowViewOwner: one('EmojiGridRowView', { identifying: true, inverse: 'sectionView' }), - viewCategory: one('EmojiPickerView.Category', { related: 'emojiGridRowViewOwner.viewCategory' }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_grid_view.js b/addons/mail/static/src/models/emoji_grid_view.js index 3f0fff7b8be..d32af58c768 100644 --- a/addons/mail/static/src/models/emoji_grid_view.js +++ b/addons/mail/static/src/models/emoji_grid_view.js @@ -24,7 +24,7 @@ registerModel({ onComponentUpdate() { if ( this.categorySelectedByUser && - this.emojiPickerViewOwner.emojiSearchBarView.currentSearch === "" + this.emojiPickerViewOwner.currentSearch === "" ) { this.doJumpToCategorySelectedByUser(); } @@ -53,7 +53,7 @@ registerModel({ * Filters emoji according to the current search terms. */ _filterEmoji(emoji) { - return (emoji._isStringInEmojiKeywords(this.emojiPickerViewOwner.emojiSearchBarView.currentSearch)); + return (emoji._isStringInEmojiKeywords(this.emojiPickerViewOwner.currentSearch)); }, }, fields: { @@ -96,6 +96,15 @@ registerModel({ ); }, }), + hasNoSearchResult: attr({ + compute() { + if (this.emojiPickerViewOwner.currentSearch !== "" && this.rows.length === 0) { + return true; + } + return clear(); + }, + default: false, + }), height: attr({ compute() { return this.rowHeight * 9.5; @@ -121,15 +130,17 @@ registerModel({ }, }), listRef: attr({ ref: 'listRef' }), - loadingScreenView: one('EmojiGridLoadingScreen', { inverse: 'emojiGridViewOwner', + loadingText: attr({ compute() { - if (!this.messaging.emojiRegistry.isLoaded) { - return {}; - } - return clear(); + return this.env._t("Loading..."); }, }), nonSearchRowRegistry: one('EmojiGridViewRowRegistry', { default: {}, inverse: 'emojiGridViewOwnerAsNonSearch' }), + noSearchResultText: attr({ + compute() { + return this.env._t("No emoji match your search"); + }, + }), onScrollThrottle: one('Throttle', { inverse: 'emojiGridViewAsOnScroll', compute() { return { func: () => this.update({ scrollRecomputeCount: increment() }) }; @@ -159,7 +170,7 @@ registerModel({ rowHeight: attr({ default: 30 }), rows: many('EmojiGridRowView', { compute() { - if (this.emojiPickerViewOwner.emojiSearchBarView.currentSearch !== "") { + if (this.emojiPickerViewOwner.currentSearch !== "") { return this.searchRowRegistry.rows; } return this.nonSearchRowRegistry.rows; @@ -188,14 +199,6 @@ registerModel({ }), scrollbarThresholdWidth: attr({ default: 15 }), scrollRecomputeCount: attr({ default: 0 }), - searchNoContentView: one('EmojiGridSearchNoContentView', { inverse: 'emojiGridViewOwner', - compute() { - if (this.emojiPickerViewOwner.emojiSearchBarView.currentSearch !== "" && this.rows.length === 0) { - return {}; - } - return clear(); - }, - }), searchRowRegistry: one('EmojiGridViewRowRegistry', { default: {}, inverse: 'emojiGridViewOwnerAsSearch' }), viewBlockRef: attr({ ref: 'viewBlockRef' }), /** diff --git a/addons/mail/static/src/models/emoji_grid_view_row_registry.js b/addons/mail/static/src/models/emoji_grid_view_row_registry.js index 1beb0f0d3a9..3ab6ea12308 100644 --- a/addons/mail/static/src/models/emoji_grid_view_row_registry.js +++ b/addons/mail/static/src/models/emoji_grid_view_row_registry.js @@ -32,7 +32,7 @@ registerModel({ return value; }, computeSearchRows() { - if (this.emojiGridViewOwner.emojiPickerViewOwner.emojiSearchBarView.currentSearch === "") { + if (this.emojiGridViewOwner.emojiPickerViewOwner.currentSearch === "") { return clear(); } const emojis = this.messaging.emojiRegistry.allEmojis.filter(this.emojiGridViewOwner._filterEmoji); diff --git a/addons/mail/static/src/models/emoji_or_emoji_in_category.js b/addons/mail/static/src/models/emoji_or_emoji_in_category.js index 3116e9017ac..5954aca6b9d 100644 --- a/addons/mail/static/src/models/emoji_or_emoji_in_category.js +++ b/addons/mail/static/src/models/emoji_or_emoji_in_category.js @@ -9,6 +9,6 @@ registerModel({ fields: { emoji: one('Emoji', { identifying: true, inverse: 'emojiOrEmojiInCategory' }), emojiInCategory: one('EmojiInCategory', { identifying: true, inverse: 'emojiOrEmojiInCategory' }), - emojiGridItemViews: many('EmojiGridItemView', { inverse: 'emojiOrEmojiInCategory' }), + emojiViews: many('EmojiView', { inverse: 'emojiOrEmojiInCategory' }), }, }); diff --git a/addons/mail/static/src/models/emoji_picker_header_action_list_view.js b/addons/mail/static/src/models/emoji_picker_header_action_list_view.js deleted file mode 100644 index f26fd64e301..00000000000 --- a/addons/mail/static/src/models/emoji_picker_header_action_list_view.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { many, one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiPickerHeaderActionListView', - template: 'mail.EmojiPickerHeaderActionListView', - fields: { - __dummyActionView: one('EmojiPickerHeaderActionView', { inverse: '__ownerAsDummy' }), - actionViews: many('EmojiPickerHeaderActionView', { inverse: 'owner', - sort: [['smaller-first', 'sequence']], - }), - emojiPickerView: one('EmojiPickerView', { related: 'owner.emojiPickerViewOwner' }), - owner: one('EmojiPickerHeaderView', { identifying: true, inverse: 'actionListView' }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_picker_header_action_view.js b/addons/mail/static/src/models/emoji_picker_header_action_view.js index 92126b0abb1..867fb3af63d 100644 --- a/addons/mail/static/src/models/emoji_picker_header_action_view.js +++ b/addons/mail/static/src/models/emoji_picker_header_action_view.js @@ -10,7 +10,7 @@ registerModel({ identifyingMode: 'xor', fields: { // dummy identifying field, so that it works without defining one initially in mail - __ownerAsDummy: one('EmojiPickerHeaderActionListView', { identifying: true, inverse: '__dummyActionView' }), + __ownerAsDummy: one('EmojiPickerView', { identifying: true, inverse: '__dummyActionView', }), content: one('Record', { required: true, compute() { return clear(); @@ -21,7 +21,7 @@ registerModel({ return clear(); }, }), - owner: one('EmojiPickerHeaderActionListView', { inverse: 'actionViews', required: true, + owner: one('EmojiPickerView', { inverse: 'actionViews', required: true, compute() { return clear(); }, diff --git a/addons/mail/static/src/models/emoji_picker_header_view.js b/addons/mail/static/src/models/emoji_picker_header_view.js deleted file mode 100644 index 7704fd4827d..00000000000 --- a/addons/mail/static/src/models/emoji_picker_header_view.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @odoo-module **/ - -import { registerModel } from '@mail/model/model_core'; -import { one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiPickerHeaderView', - template: 'mail.EmojiPickerHeaderView', - fields: { - actionListView: one('EmojiPickerHeaderActionListView', { default: {}, isCausal: true, inverse: 'owner' }), - emojiCategoryBarView: one('EmojiCategoryBarView', { default: {}, inverse: 'emojiPickerHeaderViewOwner', readonly: true, required: true }), - emojiPickerViewOwner: one('EmojiPickerView', { identifying: true, inverse: 'headerView' }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_picker_view.js b/addons/mail/static/src/models/emoji_picker_view.js index 621f05bf9c1..9b19ad4a61f 100644 --- a/addons/mail/static/src/models/emoji_picker_view.js +++ b/addons/mail/static/src/models/emoji_picker_view.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { useComponentToModel } from '@mail/component_hooks/use_component_to_model'; +import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model'; import { registerModel } from '@mail/model/model_core'; import { attr, many, one } from '@mail/model/model_field'; import { clear } from '@mail/model/model_field_command'; @@ -10,6 +11,7 @@ registerModel({ template: 'mail.EmojiPickerView', componentSetup() { useComponentToModel({ fieldName: 'component' }); + useUpdateToModel({ methodName: 'onComponentUpdate', modelName: 'EmojiPickerView' }); }, lifecycleHooks: { _created() { @@ -17,13 +19,69 @@ registerModel({ return; } this.messaging.emojiRegistry.loadEmojiData(); + if (!this.messaging.device.isSmall) { + this.update({ isDoFocus: true }); + } + }, + }, + recordMethods: { + /** + * Handles OWL update on the search bar. + */ + onComponentUpdate() { + this._handleFocus(); + }, + onFocusinInput() { + if (!this.exists()) { + return; + } + this.update({ isFocused: true }); + }, + onFocusoutInput() { + if (!this.exists()) { + return; + } + this.update({ isFocused: false }); + }, + /** + * @public + */ + onInput() { + if (!this.exists()) { + return; + } + this.update({ currentSearch: this.inputRef.el.value }); + }, + /** + * @public + */ + reset() { + this.update({ currentSearch: "" }); + this.inputRef.el.value = ""; + }, + /** + * @private + */ + _handleFocus() { + if (this.isDoFocus) { + if (!this.inputRef.el) { + return; + } + this.update({ isDoFocus: false }); + this.inputRef.el.focus(); + } }, }, fields: { + __dummyActionView: one('EmojiPickerHeaderActionView', { inverse: '__ownerAsDummy' }), + actionViews: many('EmojiPickerHeaderActionView', { + inverse: 'owner', + sort: [['smaller-first', 'sequence']], + }), activeCategoryByGridViewScroll: one('EmojiPickerView.Category'), activeCategory: one('EmojiPickerView.Category', { compute() { - if (this.emojiSearchBarView.currentSearch !== "") { + if (this.currentSearch !== "") { return clear(); } if (this.activeCategoryByGridViewScroll) { @@ -41,6 +99,8 @@ registerModel({ return this.messaging.emojiRegistry.allCategories.map(category => ({ category })); }, }), + component: attr(), + currentSearch: attr({ default: "" }), defaultActiveCategory: one('EmojiPickerView.Category', { compute() { if (this.categories.length === 0) { @@ -49,10 +109,20 @@ registerModel({ return this.categories[0]; }, }), + emojiCategoryViews: many('EmojiCategoryView', { inverse: 'emojiPickerViewOwner', + compute() { + return this.categories.map(category => ({ viewCategory: category })); + }, + }), emojiGridView: one('EmojiGridView', { default: {}, inverse: 'emojiPickerViewOwner', readonly: true, required: true }), - emojiSearchBarView: one('EmojiSearchBarView', { default: {}, inverse: 'emojiPickerView', readonly: true }), - headerView: one('EmojiPickerHeaderView', { default: {}, inverse: 'emojiPickerViewOwner', readonly: true, required: true }), + inputRef: attr({ ref: 'input' }), + isDoFocus: attr({ default: false }), + isFocused: attr({ default: false }), + placeholder: attr({ required: true, + compute() { + return this.env._t("Search an emoji"); + }, + }), popoverViewOwner: one('PopoverView', { identifying: true, inverse: 'emojiPickerView' }), - component: attr(), }, }); diff --git a/addons/mail/static/src/models/emoji_search_bar_view.js b/addons/mail/static/src/models/emoji_search_bar_view.js deleted file mode 100644 index 2accc144b03..00000000000 --- a/addons/mail/static/src/models/emoji_search_bar_view.js +++ /dev/null @@ -1,82 +0,0 @@ -/** @odoo-module **/ - -import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model'; -import { registerModel } from '@mail/model/model_core'; -import { attr, one } from '@mail/model/model_field'; - -registerModel({ - name: 'EmojiSearchBarView', - template: 'mail.EmojiSearchBarView', - componentSetup() { - useUpdateToModel({ methodName: 'onComponentUpdate', modelName: 'EmojiSearchBarView' }); - }, - lifecycleHooks: { - _created() { - if (!this.messaging.device.isSmall) { - this.update({ isDoFocus: true }); - } - } - }, - recordMethods: { - /** - * Handles OWL update on this EmojiSearchBarView component. - */ - onComponentUpdate() { - this._handleFocus(); - }, - onFocusinInput() { - if (!this.exists()) { - return; - } - this.update({ isFocused: true }); - }, - onFocusoutInput() { - if (!this.exists()) { - return; - } - this.update({ isFocused: false }); - }, - /** - * @public - */ - onInput() { - if (!this.exists()) { - return; - } - this.update({ - currentSearch: this.inputRef.el.value, - }); - }, - /** - * @public - */ - reset() { - this.update({ currentSearch: "" }); - this.inputRef.el.value = ""; - }, - /** - * @private - */ - _handleFocus() { - if (this.isDoFocus) { - if (!this.inputRef.el) { - return; - } - this.update({ isDoFocus: false }); - this.inputRef.el.focus(); - } - }, - }, - fields: { - currentSearch: attr({ default: "" }), - emojiPickerView: one("EmojiPickerView", { identifying: true, inverse: "emojiSearchBarView" }), - inputRef: attr({ ref: 'input' }), - isDoFocus: attr({ default: false }), - isFocused: attr({ default: false }), - placeholder: attr({ required: true, - compute() { - return this.env._t("Search an emoji"); - }, - }), - }, -}); diff --git a/addons/mail/static/src/models/emoji_view.js b/addons/mail/static/src/models/emoji_view.js index 037e31e18d1..f56058a39eb 100644 --- a/addons/mail/static/src/models/emoji_view.js +++ b/addons/mail/static/src/models/emoji_view.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { one } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; import { clear } from '@mail/model/model_field_command'; registerModel({ @@ -12,7 +12,7 @@ registerModel({ * @param {MouseEvent} ev */ onClick(ev) { - if (!this.emojiGridItemViewOwner.emojiGridRowViewOwner) { + if (!this.emojiGridRowViewOwner) { return; } if (this.emojiPickerViewOwner.popoverViewOwner.messageActionViewOwnerAsReaction) { @@ -31,7 +31,7 @@ registerModel({ if (!this.exists()) { return; } - this.update({ emojiGridViewAsHovered: this.emojiGridItemViewOwner.emojiGridRowViewOwner.emojiGridViewOwner }); + this.update({ emojiGridViewAsHovered: this.emojiGridRowViewOwner.emojiGridViewOwner }); }, /** * @param {MouseEvent} ev @@ -44,13 +44,32 @@ registerModel({ }, }, fields: { - emoji: one('Emoji', { identifying: true, inverse: 'emojiViews' }), - emojiGridItemViewOwner: one('EmojiGridItemView', { identifying: true, inverse: 'emojiView' }), + emoji: one('Emoji', { inverse: 'emojiViews', + compute() { + if (this.emojiOrEmojiInCategory.emoji) { + return this.emojiOrEmojiInCategory.emoji; + } + if (this.emojiOrEmojiInCategory.emojiInCategory) { + return this.emojiOrEmojiInCategory.emojiInCategory.emoji; + } + return clear(); + }, + }), emojiGridViewAsHovered: one('EmojiGridView', { inverse: 'hoveredEmojiView' }), + emojiOrEmojiInCategory: one('EmojiOrEmojiInCategory', { identifying: true, inverse: 'emojiViews' }), + emojiGridRowViewOwner: one('EmojiGridRowView', { identifying: true, inverse: 'items' }), emojiPickerViewOwner: one('EmojiPickerView', { compute() { - return this.emojiGridItemViewOwner.emojiGridRowViewOwner.emojiGridViewOwner.emojiPickerViewOwner; + return this.emojiGridRowViewOwner.emojiGridViewOwner.emojiPickerViewOwner; } - }) + }), + width: attr({ default: 0, + compute() { + if (!this.emojiGridRowViewOwner.emojiGridViewOwner) { + return clear(); + } + return this.emojiGridRowViewOwner.emojiGridViewOwner.itemWidth; + }, + }), }, }); diff --git a/addons/mail/static/src/models/file_uploader.js b/addons/mail/static/src/models/file_uploader.js index d265b2b04c6..dea7a0cbe2b 100644 --- a/addons/mail/static/src/models/file_uploader.js +++ b/addons/mail/static/src/models/file_uploader.js @@ -43,8 +43,8 @@ registerModel({ if (this.fileInput && this.fileInput.el) { this.fileInput.el.value = ''; } - if (this.chatterOwner && !this.chatterOwner.attachmentBoxView) { - this.chatterOwner.openAttachmentBoxView(); + if (this.chatterOwner && !this.chatterOwner.hasAttachmentBox) { + this.chatterOwner.openAttachmentBox(); } this.messaging.messagingBus.trigger('o-file-uploader-upload', { files }); }, @@ -100,8 +100,7 @@ registerModel({ const thread = this.thread; // save before async const chatter = ( (this.chatterOwner) || - (this.attachmentBoxView && this.attachmentBoxView.chatter) || - (this.activityView && this.activityView.activityBoxView.chatter) + (this.activityView && this.activityView.chatterOwner) ); // save before async const activity = ( this.activityView && this.activityView.activity || @@ -167,7 +166,6 @@ registerModel({ fields: { activityListViewItemOwner: one('ActivityListViewItem', { identifying: true, inverse: 'fileUploader' }), activityView: one('ActivityView', { identifying: true, inverse: 'fileUploader' }), - attachmentBoxView: one('AttachmentBoxView', { identifying: true, inverse: 'fileUploader' }), chatterOwner: one('Chatter', { identifying: true, inverse: 'fileUploader' }), composerView: one('ComposerView', { identifying: true, inverse: 'fileUploader' }), fileInput: attr({ @@ -192,9 +190,6 @@ registerModel({ if (this.activityListViewItemOwner) { return this.activityListViewItemOwner.activity.thread; } - if (this.attachmentBoxView) { - return this.attachmentBoxView.chatter.thread; - } if (this.chatterOwner) { return this.chatterOwner.thread; } diff --git a/addons/mail/static/src/models/follow_button_view.js b/addons/mail/static/src/models/follow_button_view.js deleted file mode 100644 index 48fb8000f82..00000000000 --- a/addons/mail/static/src/models/follow_button_view.js +++ /dev/null @@ -1,77 +0,0 @@ -/** @odoo-module **/ - -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: 'FollowButtonView', - template: 'mail.FollowButtonView', - recordMethods: { - /** - * @param {MouseEvent} ev - */ - onClickFollow(ev) { - if (!this.exists()) { - return; - } - if (!this.chatterOwner || !this.chatterOwner.thread) { - return; - } - this.chatterOwner.thread.follow(); - }, - /** - * @param {MouseEvent} ev - */ - onClickUnfollow(ev) { - if (!this.exists()) { - return; - } - if (!this.chatterOwner || !this.chatterOwner.thread) { - return; - } - this.chatterOwner.thread.unfollow(); - this.chatterOwner.reloadParentView({ fieldNames: ['message_follower_ids'] }); - }, - /** - * @param {MouseEvent} ev - */ - onMouseEnterUnfollow(ev) { - if (!this.exists()) { - return; - } - this.update({ isUnfollowButtonHighlighted: true }); - }, - /** - * @param {MouseEvent} ev - */ - onMouseleaveUnfollow(ev) { - if (!this.exists()) { - return; - } - this.update({ isUnfollowButtonHighlighted: false }); - }, - }, - fields: { - chatterOwner: one('Chatter', { identifying: true, inverse: 'followButtonView' }), - followingText: attr({ - compute() { - return this.env._t("Following"); - }, - }), - isDisabled: attr({ - compute() { - if (!this.chatterOwner) { - return clear(); - } - return !this.chatterOwner.hasReadAccess; - }, - }), - isUnfollowButtonHighlighted: attr({ default: false }), - unfollowingText: attr({ - compute() { - return this.env._t("Unfollow"); - }, - }), - }, -}); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/activity_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/activity_tests.js index 2e9aaf8e3b1..f1812293122 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/activity_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/activity_tests.js @@ -750,7 +750,7 @@ QUnit.test('activity upload document is available', async function (assert) { "should have activity upload button" ); assert.ok( - messaging.models['Chatter'].all()[0].activityBoxView.activityViews[0].fileUploader, + messaging.models['Chatter'].all()[0].activityViews[0].fileUploader, "should have a file uploader" ); }); diff --git a/addons/mail/static/tests/qunit_suite_tests/components/attachment_box_tests.js b/addons/mail/static/tests/qunit_suite_tests/components/attachment_box_tests.js index 95270cda7c6..fb090d029ed 100644 --- a/addons/mail/static/tests/qunit_suite_tests/components/attachment_box_tests.js +++ b/addons/mail/static/tests/qunit_suite_tests/components/attachment_box_tests.js @@ -36,7 +36,7 @@ QUnit.test('base empty rendering', async function (assert) { "should have a button add" ); assert.ok( - messaging.models['Chatter'].all()[0].attachmentBoxView.fileUploader, + messaging.models['Chatter'].all()[0].fileUploader, "should have a file uploader" ); assert.strictEqual( @@ -90,7 +90,7 @@ QUnit.test('base non-empty rendering', async function (assert) { "should have a button add" ); assert.ok( - messaging.models['Chatter'].all()[0].attachmentBoxView.fileUploader, + messaging.models['Chatter'].all()[0].fileUploader, "should have a file uploader" ); assert.strictEqual( diff --git a/addons/website_slides/static/src/models/activity_view.js b/addons/website_slides/static/src/models/activity_view.js index 66f6deeabbc..3ea236f021c 100644 --- a/addons/website_slides/static/src/models/activity_view.js +++ b/addons/website_slides/static/src/models/activity_view.js @@ -9,7 +9,7 @@ registerPatch({ * Handles click on the "grant access" button. */ async onGrantAccess(ev) { - const { chatter } = this.activityBoxView; // save value before deleting activity + const chatter = this.chatterOwner; // save value before deleting activity await this.messaging.rpc({ model: 'slide.channel', method: 'action_grant_access', @@ -25,7 +25,7 @@ registerPatch({ * Handles click on the "refuse access" button. */ async onRefuseAccess(ev) { - const { chatter } = this.activityBoxView; // save value before deleting activity + const chatter = this.chatterOwner; // save value before deleting activity await this.messaging.rpc({ model: 'slide.channel', method: 'action_refuse_access',