diff options
| author | Sébastien Theys <seb@odoo.com> | 2020-06-15 18:12:21 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-06-15 18:12:21 +0000 |
| commit | 3fea5b2136627c1d7e83b2a5e111952fe3eb10a1 (patch) | |
| tree | 5eefad07972a87ce4689b83260f981bc87aadad4 /addons/mail/static/src/xml | |
| parent | 0a82848606151ef60eb6523e9c4c161171f214e7 (diff) | |
[REF] mail, *: refactor messaging with OWL
This commit is a significant rewriting of client-side discuss, chatter,
chat window, and messaging menu using OWL. The behavior should be broadly
the same, with some slight functional changes here and there.
From a technical standpoint, the code of messaging is mainly organized in 2
main groups of modules:
- models, which are logical entities that depict the client-side state of
messaging as a whole.
- components, which are in charge of displaying information from models.
This refactoring also introduces new JS guidelines regarding folder structure
(/static) and naming rules for JS modules.
Community PR: https://github.com/odoo/odoo/pull/39023
Enterprise PR: https://github.com/odoo/enterprise/pull/6249
Task-1914207
This PR is a collaborative work by Alexandre, Julien, Sébastien and Xavier,
with the precious help of Lucas to speed it up towards the end.
closes odoo/odoo#39023
Related: odoo/enterprise#6249
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Co-authored-by: Alexandre Kühn <aku@odoo.com>
Co-authored-by: Julien Giannone <jgi@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
Co-authored-by: Sébastien Theys <seb@odoo.com>
Co-authored-by: Xavier Dubuc <xdu@odoo.com>
Diffstat (limited to 'addons/mail/static/src/xml')
| -rw-r--r-- | addons/mail/static/src/xml/abstract_thread_window.xml | 85 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/chatter.xml | 152 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/composer.xml | 91 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/discuss.xml | 352 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/followers.xml | 95 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/out_of_office.xml | 9 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/systray.xml | 58 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/text_emojis.xml | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/thread.xml | 536 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/thread_window.xml | 32 |
10 files changed, 2 insertions, 1410 deletions
diff --git a/addons/mail/static/src/xml/abstract_thread_window.xml b/addons/mail/static/src/xml/abstract_thread_window.xml deleted file mode 100644 index ae29a21b5ba..00000000000 --- a/addons/mail/static/src/xml/abstract_thread_window.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates xml:space="preserve"> - - <!-- - @param {mail.AbstractThreadWindow} widget - --> - <t t-name="mail.AbstractThreadWindow"> - <div class="o_thread_window o_in_home_menu" t-att-data-thread-id="widget.getID()"> - <div class="o_thread_window_header"> - <t t-call="mail.AbstractThreadWindow.HeaderContent"> - <t t-set="status" t-value="widget.getThreadStatus()"/> - <t t-set="title" t-value="widget.getTitle()"/> - <t t-set="unreadCounter" t-value="widget.getUnreadCounter()"/> - <t t-set="thread" t-value="widget.getThread()"/> - </t> - </div> - <div class="o_thread_window_content"> - </div> - <div t-if="widget.needsComposer()" class="o_thread_composer o_chat_mini_composer"> - <input class="o_composer_text_field" t-att-placeholder="widget.options.placeholder"/> - </div> - </div> - </t> - - <!-- - @param {boolean} [open=false] tell whether the hidden thread window - dropdown menu is open or not. - @param {mail.ThreadWindow[]} threadWindows list of thread windows - that are hidden, i.e. put in the hidden window dropdown menu. - @param {integer} [unreadCounter] the total unread counter of all - threads which are linked to the thread windows that are put in the - hidden thread window dropdown menu. - --> - <t t-name="mail.HiddenThreadWindowsDropdown"> - <div t-attf-class="o_thread_window o_in_home_menu o_thread_window_dropdown dropup #{open ? 'open' : ''}"> - <span role="alert" class="o_thread_window_dropdown_toggler dropdown-toggle" data-toggle="dropdown" title="Unread messages"> - <i class="fa fa-comments-o" role="img" aria-label="Messages"/> <t t-esc="threadWindows.length"/> - <span class="o_total_unread_counter"> - <t t-if="unreadCounter"><t t-esc="unreadCounter"/></t> - </span> - </span> - <ul class="dropdown-menu" role="menu"> - <t t-foreach="threadWindows" t-as="threadWindow"> - <li role="menuitem" class="o_thread_window_header" t-att-data-thread-id="threadWindow.getID()"> - <t t-call="mail.AbstractThreadWindow.HeaderContent"> - <t t-set="status" t-value="threadWindow.getThreadStatus()"/> - <t t-set="title" t-value="threadWindow.getTitle()"/> - <t t-set="unreadCounter" t-value="threadWindow.getUnreadCounter()"/> - </t> - </li> - </t> - </ul> - </div> - </t> - - <!-- - @param {string} [status] e.g. 'online', 'offline'. - @param {string} title the title of the thread window, e.g. the record - name of the document. - @param {integer} [unreadCounter] the number of unread messages on the - thread. - @param {mail.model.Thread|undefined} thread - @param {Object} widget - @param {function} widget.isMobile function without any param that - states whether it should render for desktop or mobile screen. - --> - <t t-name="mail.AbstractThreadWindow.HeaderContent"> - <span t-if="widget.isMobile()"> - <a href="#" class="o_thread_window_close fa fa-1x fa-arrow-left" aria-label="Close chat window" title="Close chat window"/> - </span> - <div t-if="thread and thread.getType() === 'dm_chat'" class="o_thread_window_avatar"> - <img alt="" t-att-src="'/web/image/res.partner/' + thread.getDirectPartnerID() + '/image_128'"/> - <t t-call="mail.UserStatus"/> - </div> - <span class="o_thread_window_title"> - <t t-esc="title"/> - <span t-if="unreadCounter"> (<t t-esc="unreadCounter"/>)</span> - <t t-if="thread and thread.hasTypingNotification() and thread.isSomeoneTyping()" t-call="mail.ThreadTypingIcon"/> - </span> - <span t-if="!widget.isMobile()" class="o_thread_window_buttons"> - <a href="#" class="o_thread_window_close fa fa-close"/> - </span> - </t> - -</templates> diff --git a/addons/mail/static/src/xml/chatter.xml b/addons/mail/static/src/xml/chatter.xml deleted file mode 100644 index 1f36287cdf8..00000000000 --- a/addons/mail/static/src/xml/chatter.xml +++ /dev/null @@ -1,152 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates> - - <!-- - Chatter attachment tab - --> - - <div t-name="mail.chatter.AttachmentBox" class="o_mail_chatter_attachments"> - <div class="o_chatter_attachment"> - <div class="o_border_dashed"> - <span class="o_attach_title">Attachments</span> - </div> - <div t-if="widget.imageList.length > 0" class="o_attachments_previews"> - <t t-foreach="widget.imageList" t-as="attachment"> - <t t-call="mail.AttachmentPreview"> - <t t-set="isDeletable" t-value="true"/> - </t> - </t> - </div> - <div t-if="widget.otherList.length > 0" class="o_attachments_list"> - <t t-foreach="widget.otherList" t-as="attachment"> - <t t-call="mail.Attachment"> - <t t-set="isDeletable" t-value="true"/> - </t> - </t> - </div> - <div class="o_chatter_attachment_form"> - <t t-call="HiddenInputFile"> - <t t-set="fileupload_id" t-value="widget.fileuploadId"/> - <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> - <t t-set="multi_upload" t-value="true"/> - <input type="hidden" name="model" t-att-value="widget.currentResModel"/> - <input type="hidden" name="id" t-att-value="widget.currentResID"/> - <center><span class="btn btn-link o_upload_attachments_button"><span class="fa fa-plus-square"/> Add Attachments</span></center> - </t> - </div> - </div> - </div> - - <!-- - Chatter Suggested Partners - --> - <t t-name="mail.chatter.ComposerSuggestedPartners"> - <!-- List of followers --> - <div class="o_composer_suggested_partners"> - <t t-foreach='widget.suggestedPartners' t-as='recipient'> - <div t-attf-title="Add as recipient and follower (reason: {{recipient.reason}})" t-att-class="recipient_index > 2 ? 'o_suggested_toggle o_hidden' : ''"> - <div class="custom-control custom-checkbox"> - <input type="checkbox" - class="custom-control-input" - t-attf-id="o_composer_suggested_partners_p{{recipient_index}}" - t-att-checked="recipient.checked ? 'checked' : undefined" - t-att-data-fullname="recipient.full_name"/> - <label t-attf-for="o_composer_suggested_partners_p{{recipient_index}}" class="custom-control-label"> - <t t-esc="recipient.name"/> - <t t-if="recipient.email_address">(<t t-esc="recipient.email_address"/>)</t> - </label> - </div> - </div> - </t> - <t t-if='widget.suggestedPartners.length > 3'> - <a href="#" class='o_suggested_show_more_less o_suggested_toggle'> - Show <t t-esc="widget.suggestedPartners.length - 3"/> more - </a> - <a href="#" class='o_suggested_show_more_less o_suggested_toggle o_hidden'> - Show <t t-esc="widget.suggestedPartners.length - 3"/> less - </a> - </t> - </div> - </t> - - <!-- - Chatter composer - - @param {mail.composer.Chatter} widget - --> - - <t t-name="mail.chatter.Composer" t-extend="mail.Composer"> - <!-- Insert information before the composer --> - <t t-jquery=".o_composer_container" t-operation="before"> - <!-- New message composer --> - <t t-if="!widget.options.isLog"> - <!-- Text for followers --> - <small class="o_chatter_composer_info"> - <b class="text-muted">To: </b> - <em class="text-muted">Followers of </em> - <b> - <t t-if="widget.options.recordName"> -  "<t t-esc="widget.options.recordName"/>" - </t> - <t t-if="!widget.options.recordName"> - this document - </t> - </b> - </small> - <t t-call="mail.chatter.ComposerSuggestedPartners"/> - </t> - </t> - - <!-- Add a button to open the full composer dialog --> - <t t-jquery=".o_composer_button_add_attachment" t-operation="after"> - <button tabindex="6" class="btn btn-secondary fa fa-expand o_composer_button_full_composer" type="button" title="Full composer" aria-label="Full composer"/> - </t> - </t> - - <!-- - Chatter (mail_thread widget) buttons - - @param {boolean} [isMobile] - @param {boolean} [logNoteButton] - @param {boolean} [newMessageButton] - @param {boolean} [scheduleActivityButton] - --> - <t t-name="mail.chatter.Buttons"> - <button t-if="newMessageButton" type="button" class="btn btn-link o_chatter_button_new_message" title="Send a message" disabled="disabled"> - Send message - </button> - <button t-if="logNoteButton" class="btn btn-link o_chatter_button_log_note" title="Log a note. Followers will not be notified." disabled="disabled"> - Log note - </button> - <button t-if="scheduleActivityButton" class="btn btn-link o_chatter_button_schedule_activity" title="Log or schedule an activity" disabled="disabled"> - <i class="fa fa-clock-o" title="Dates"/> <t t-if="isMobile">Activity</t><t t-else="">Schedule activity</t> - </button> - </t> - - <!-- - Chatter attachment paperclip button. - - @param {integer} [count] - --> - <t t-name="mail.chatter.Attachment.Button"> - <t t-set="attachment_button_aria_label">Attachments</t> - <button class="btn btn-link o_chatter_button_attachment" title="View all the attachments of the current record" t-attf-aria-label="#{attachment_button_aria_label} #{count}"> - <span> - <i class="fa fa-paperclip"/> - <span class="o_chatter_attachment_button_count" t-esc="count"/> - </span> - </button> - </t> - - <!-- - Chatter main div - --> - <t t-name="mail.Chatter"> - <aside class="o_chatter"> - <div class="o_chatter_topbar"> - <div class="o_topbar_right_area"/> - </div> - </aside> - </t> - -</templates> diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index 071a8023e83..49c0a3bf9b4 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -1,54 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <templates xml:space="preserve"> - <div t-name="mail.Composer" t-attf-class="o_thread_composer #{widget.extended ? 'o_thread_composer_extended' : (widget.notInline ? '' : 'o_chat_inline_composer')} #{widget.isMini ? 'o_chat_mini_composer' : ''}"> - <div t-if="widget.isMini || !widget.notInline" class="o_file_drop_zone_container d-none"> - <h4>Drag Files Here <span class="fa fa-download"/></h4> - </div> - <div class="o_composer_container"> - <img t-if="widget.avatarURL" height="36" width="36" class="o_thread_message_sidebar o_chatter_avatar o_object_fit_cover rounded-circle" t-att-src="widget.avatarURL" alt="Avatar"/> - <div t-if="widget.extended" class="o_composer_subject"> - <input tabindex="1" type="text" placeholder="Subject" class="o_input"/> - </div> - <div t-attf-class="o_composer #{widget.extended ? 'o_extended_composer' : ''}"> - <div t-if="widget.notInline" class="o_file_drop_zone_container d-none"> - <h4>Drag Files Here <span class="fa fa-download"/></h4> - </div> - <div class="o_composer_input"> - <textarea class="o_input o_composer_text_field" tabindex="2" placeholder="Write something..."/> - <div class="o_chatter_composer_tools"> - <button tabindex="4" class="btn btn-secondary fa fa-smile-o o_composer_button_emoji" type="button" data-toggle="popover" title="Emojis" aria-label="Emojis"/> - <button tabindex="5" class="btn btn-secondary fa fa-paperclip o_composer_button_add_attachment" type="button" aria-label="Add attachment" title="Add attachment"/> - <button t-if="widget.options.isMobile" tabindex="3" t-attf-class="btn #{widget.isMini ? 'btn-primary' : 'btn-secondary'} fa fa-paper-plane-o o_composer_button_send" type="button" title="Send" aria-label="Send"/> - </div> - </div> - </div> - <div class="o_composer_attachments_list"/> - <div class="o_composer_thread_typing"/> - </div> - <div class="o_composer_send"> - <button tabindex="3" class="btn btn-primary o_composer_button_send d-none d-md-inline-block" type="button"><t t-esc="widget.options.sendText"/></button> - <button tabindex="3" class="btn btn-secondary o_composer_button_discard d-none" type="button">Discard</button> - </div> - <span class="d-none"> - <t t-call="HiddenInputFile"> - <t t-set="fileupload_id" t-value="widget.fileuploadID"/> - <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> - <t t-set="multi_upload" t-value="true"/> - <input type="hidden" name="model" value="mail.compose.message"/> - <input type="hidden" name="id" value="0"/> - </t> - </span> - </div> - - <!-- - @param {mail.model.Thread} thread - --> - <t t-name="mail.Composer.ThreadTyping"> - <t t-esc="thread.getTypingMembersToText()"/> - </t> - - <div t-name="mail.Composer.emojis" class="o_mail_emoji_container"> + <div t-name="mail.legacy.Composer.emojis" class="o_mail_emoji_container"> <t t-foreach="emojis" t-as="emoji"> <span t-att-data-emoji="emoji.sources[0]" class="o_mail_emoji" t-att-title="emoji.description" t-att-aria-label="emoji.description"> <t t-raw="emoji.unicode"/> @@ -56,48 +9,6 @@ </t> </div> - <!-- - @param {Object[]} suggestions - @param {boolean} [suggestions.divider=false] - --> - <t t-name="mail.MentionSuggestions"> - <div class="dropdown-menu" role="menu"> - <t t-foreach="suggestions" t-as="suggestion"> - <div role="separator" t-if="suggestion.divider" class="dropdown-divider"/> - <a t-else="" href="#" class="dropdown-item o_mention_proposition" t-att-data-id="suggestion.id" role="menuitem"/> - </t> - </div> - </t> - <t t-name="mail.MentionSuggestions.Partner" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition" t-operation="append"> - <t t-call="mail.UserStatus"> - <t t-set="status" t-value="suggestion.im_status"/> - <t t-set="partnerID" t-value="suggestion.id"/> - </t> - <span class="o_mention_name"><t t-esc="suggestion.name"/></span> - <t t-if="suggestion.email"> - <span class="o_mention_info">(<t t-esc="suggestion.email"/>)</span> - </t> - </t> - </t> - <t t-name="mail.MentionSuggestions.Channel" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition" t-operation="append"> - <span class="o_mention_name"><t t-esc="suggestion.name"/></span> - </t> - </t> - <t t-name="mail.MentionSuggestions.CannedResponse" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition" t-operation="append"> - <span class="o_mention_name"><t t-esc="suggestion.source"/></span> - <span class="o_mention_info"><t t-esc="suggestion.substitution"/></span> - </t> - </t> - <t t-name="mail.MentionSuggestions.Command" t-extend="mail.MentionSuggestions"> - <t t-jquery=".o_mention_proposition" t-operation="append"> - <span class="o_mention_name">/<t t-esc="suggestion.name"/></span> - <span class="o_mention_info"><t t-esc="suggestion.help"/></span> - </t> - </t> - <t t-name="FieldMany2ManyTagsEmail" t-extend="FieldMany2ManyTag"> <t t-jquery="[t-attf-class*=badge]" t-operation="replace"> <div t-attf-class="badge badge-pill dropdown o_tag_color_0 #{el.email.indexOf('@') < 0 ? 'o_tag_error' : ''}" t-att-data-color="color" t-att-data-index="el_index" t-att-data-id="el.id" t-attf-title="Tag color: #{colornames[color]}"> diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml deleted file mode 100644 index 98788e303ff..00000000000 --- a/addons/mail/static/src/xml/discuss.xml +++ /dev/null @@ -1,352 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates xml:space="preserve"> - - <!-- - Discuss Main template - - @param {mail.discuss} widget - --> - <t t-name="mail.discuss"> - <div class="o_mail_discuss"> - <div class="o_mail_discuss_sidebar"> - <div class="o_mail_discuss_loading"> - <i class="fa fa-spinner fa-spin"/> Please wait... - </div> - </div> - <div class="o_mail_discuss_content"> - <div class="o_mail_discuss_loading"> - <i class="fa fa-spinner fa-spin"/> Please wait... - </div> - </div> - </div> - </t> - - <!-- - @param {string|integer} activeThreadID - @param {mail.model.Channel[]} channels - @param {boolean} isMyselfModerator - @param {mail.model.Mailbox} inbox - @param {mail.model.Mailbox} starred - @param {mail.model.Mailbox|undefined} moderation set if current user is moderator - @param {boolean} displayQuickSearch - @param {Object} options - --> - <t t-name="mail.discuss.Sidebar"> - <div class="o_mail_discuss_sidebar"> - <div class="o_mail_discuss_sidebar_mailboxes"> - <t t-call="mail.discuss.SidebarMailboxes"/> - </div> - <hr class="mb8"/> - <div t-if="displayQuickSearch" class="o_discuss_sidebar_quick_search"> - <t t-set="inputPlaceholder">Quick search...</t> - <input t-att-placeholder="inputPlaceholder"/> - </div> - <div class="o_mail_discuss_sidebar_channels"> - <t t-call="mail.discuss.SidebarChannels"/> - </div> - </div> - </t> - - <!-- - @param {string|integer} activeThreadID - @param {boolean} isMyselfModerator - @param {mail.model.Mailbox} inbox - @param {mail.model.Mailbox} starred - @param {mail.model.Mailbox|undefined} moderation set if current user is moderator - --> - <t t-name="mail.discuss.SidebarMailboxes"> - <div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_inbox') ? 'o_active': ''}" - data-thread-id="mailbox_inbox"> - <span class="o_thread_name"><i class="fa fa-inbox mr8"/>Inbox</span> - <t t-set="counter" t-value="inbox.getMailboxCounter()"/> - <t t-call="mail.discuss.SidebarCounter"/> - </div> - <div t-attf-class="o_mail_discuss_title_main o_mail_mailbox_title_starred o_mail_discuss_item #{(activeThreadID === 'mailbox_starred') ? 'o_active': ''}" - data-thread-id="mailbox_starred"> - <span class="o_thread_name"><i class="fa fa-star-o mr8"/>Starred</span> - <t t-set="counter" t-value="starred.getMailboxCounter()"/> - <t t-call="mail.discuss.SidebarCounter"/> - </div> - <div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_history') ? 'o_active': ''}" - data-thread-id="mailbox_history"> - <span class="o_thread_name"><i class="fa fa-history mr8"/>History</span> - </div> - <div t-if="isMyselfModerator" t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID == 'mailbox_moderation') ? 'o_active': ''}" - data-thread-id="mailbox_moderation"> - <span class="o_thread_name"> <i class="fa fa-envelope mr8"/>Moderation Queue</span> - <t t-set="counter" t-value="moderation.getMailboxCounter()"/> - <t t-call="mail.discuss.SidebarCounter"/> - </div> - </t> - - <!-- - @param {string|integer} activeThreadID - @param {mail.model.Channel[]} channels - --> - <t t-name="mail.discuss.SidebarChannels"> - <t t-set="type" t-value="'multi_user_channel'"/> - <t t-call="mail.discuss.SidebarTitle"> - <t t-set="title">Channels</t> - <t t-set="icon" t-value="fa-users"/> - </t> - <t t-call="mail.discuss.SidebarItems"> - <t t-set="displayHash" t-value="true"/> - <t t-set="inputPlaceholder">Add a channel</t> - </t> - - <t t-set="type" t-value="'dm_chat'"/> - <t t-call="mail.discuss.SidebarTitle"> - <t t-set="title">Direct Messages</t> - <t t-set="icon" t-value="fa-user"/> - </t> - <t t-call="mail.discuss.SidebarItems"> - <t t-set="displayStatus" t-value="true"/> - <t t-set="inputPlaceholder">User name</t> - </t> - </t> - - <!-- - @param {integer} counter - --> - <t t-name="mail.discuss.SidebarCounter"> - <span t-attf-class="o_mail_sidebar_needaction badge badge-pill #{(!counter ? 'd-none' : '')}"> - <t t-esc="counter"/> - </span> - </t> - - <!-- - Don't display the thread type if there is no thread of such type - and the 'add a thread' option is disabled for this type - - @param {mail.model.Channel[]} channels - @param {boolean} [disableAddThread] whether the 'Add thread' action should disabled or not for the considered discuss item category - @param {string} [icon] classname to add on title to display icon - @param {string} title the displayed type of the discuss items (e.g. "Channels") - @param {string} type the type of the thread - --> - <t t-name="mail.discuss.SidebarTitle"> - <t t-if="disableAddThread"> - <t t-set="empty" t-value="true"/> - <t t-foreach="channels" t-as="channel"> - <t t-if="channel.getType() === type"> - <t t-set="empty" t-value="false"/> - </t> - </t> - </t> - <t t-if="!disableAddThread || !empty"> - <div class="o_mail_sidebar_title"> - <h4 t-att-class="type == 'multi_user_channel' ? 'o_mail_open_channels' : ''"> - <i t-if="icon" t-attf-class="mr4 fa-fw fa #{icon}" role="img" aria-label="Channel" title="Channel"></i> - <b><t t-esc="title"/></b> - </h4> - <span t-if="!disableAddThread" class="fa fa-plus o_add" title="Add" t-attf-data-type="#{type}" role="img" aria-label="Add"/> - </div> - </t> - </t> - - <!-- - @param {string|integer} activeThreadID - @param {mail.model.Channel[]} channels - @param {boolean} disableAddThread whether the 'Add thread' action should be disable or not for the considered discuss item category - @param {boolean} [displayHash] whether the hash ('#') character should be displayed as a prefix for item's name - @param {boolean} [displayStatus] whether the item should display its status (should be the case only for chats) - @param {string} inputPlaceholder text placeholder on showing input in a sidebar category - --> - <t t-name="mail.discuss.SidebarItems"> - <div t-if="!disableAddThread" class="o_mail_add_thread" t-attf-data-type="#{type}"> - <span t-if="displayHash">#</span> - <input type="text" class="o_input" t-attf-placeholder="#{inputPlaceholder}"/> - </div> - <t t-foreach="channels" t-as="channel"> - <t t-set="counter" t-value="channel.isTwoUserThread() ? channel.getUnreadCounter() : channel.getNeedactionCounter()"/> - <div t-if="channel.getType() === type" t-att-data-thread-id="channel.getID()" t-att-title="channel.getName()" - t-attf-class="o_mail_discuss_item #{channel.hasUnreadMessages() ? ' o_unread_message' : ''} #{(activeThreadID == channel.getID()) ? 'o_active': ''}"> - <span class="o_thread_name"> - <span t-if="displayStatus"> - <t t-call="mail.UserStatus"> - <t t-set="status" t-value="channel.getStatus()"/> - <t t-set="partnerID" t-value="channel.getDirectPartnerID()"/> - </t> - </span> - <span t-if="displayHash" class="o_mail_hash">#</span> - <i t-if="channel.getType() === 'multi_user_channel' and !channel.isPublic()" class="fa fa-lock" title="Private channel" role="img" aria-label="Private channel"/> - <t t-esc="_.unescape(channel.getName())"/> - <i t-if="channel.isMassMailing()" class="fa fa-envelope-o" title="Sends messages by email" role="img" aria-label="Send by mail"/> - </span> - <t t-if="channel.hasTypingNotification() and channel.isSomeoneTyping()"> - <t t-set="thread" t-value="channel"/> - <t t-call="mail.ThreadTypingIcon"/> - </t> - <span t-attf-class="fa fa-cog o_mail_channel_settings" - title="Channel settings" role="img" aria-label="Channel settings" t-att-data-thread-id="channel.getID()"/> - <t t-call="mail.discuss.SidebarCounter"/> - <span t-if="!channel.isGroupBasedSubscription()" t-attf-class="fa fa-times o_mail_partner_unpin #{counter ? 'd-none' : ''}" - title="Leave this channel" role="img" aria-label="Leave this channel" t-att-data-thread-id="channel.getID()"/> - </div> - </t> - </t> - - <!-- - @param {string} status - @param {integer|undefined} [partnerID] - --> - <t t-name="mail.UserStatus"> - <span t-att-class="partnerID ? 'o_updatable_im_status' : ''" t-att-data-partner-id="partnerID"> - <i t-if="status == 'online'" class="o_mail_user_status o_user_online fa fa-circle" title="Online" role="img" aria-label="User is online"/> - <i t-if="status == 'away'" class="o_mail_user_status o_user_idle fa fa-circle" title="Idle" role="img" aria-label="User is idle"/> - <i t-if="status == 'offline'" class="o_mail_user_status fa fa-circle-o" title="Offline" role="img" aria-label="User is offline"/> - </span> - </t> - - <!-- - @param {string} documentName - --> - <t t-name="mail.discuss.MessageSentSnackbar"> - <div class="alert o_mail_snackbar" data-dismiss="alert" role="alert"> - Message sent in "<t t-esc="documentName"/>". - </div> - </t> - - - <!-- - Buttons of the Control Panel - - @param {boolean} [disableAddThread] whether the 'Add channel' action should be disabled or not for the considered discuss item category - --> - <t t-name="mail.discuss.ControlButtons"> - <div> - <button type="button" class="btn btn-primary o_mail_discuss_button_invite d-none d-md-inline-block" title="Invite people">Invite</button> - <button type="button" class="btn btn-secondary o_mail_discuss_button_mark_all_read d-none d-md-inline-block" title="Mark all as read">Mark all read</button> - <button type="button" class="btn btn-secondary o_mail_discuss_button_unstar_all" title="Unstar all messages">Unstar all</button> - <button type="button" class="btn btn-secondary o_mail_discuss_button_dm_chat o_hidden d-md-none" title="New Message">New Message</button> - <button t-if="!disableAddThread" type="button" class="btn btn-secondary o_mail_discuss_button_multi_user_channel d-block d-md-none" title="New Channel">New Channel</button> - <button type="button" class="btn btn-secondary o_hidden o_mail_discuss_button_select_all" title="Select all messages to moderate">Select All</button> - <button type="button" class="btn btn-secondary o_hidden o_mail_discuss_button_unselect_all" title="Unselect all messages to moderate">Unselect All</button> - <button type="button" data-decision="accept" class="btn btn-secondary o_mail_discuss_button_moderate_all" title="Accept selected messages">Accept</button> - <button type="button" data-decision="reject" class="btn btn-secondary o_mail_discuss_button_moderate_all" title="Reject selected messages">Reject</button> - <button type="button" data-decision="discard" class="btn btn-secondary o_mail_discuss_button_moderate_all" title="Discard selected messages">Discard</button> - </div> - </t> - - <!-- Invite dialog's content --> - <div t-name="mail.PartnerInviteDialog"> - <input type="text" class="o_input o_mail_discuss_partner_invite_input" id="mail_search_partners"/> - </div> - - <!-- Rename channel dialog's content --> - <div t-name="mail.RenameConversationDialog"> - <input type="text" class="o_input o_mail_discuss_rename_channel_input"/> - </div> - - <div t-name="mail.ModeratorRejectMessageDialog"> - <input class="form-control" type="text" id="message_title" placeholder="Subject" value="Message Rejected"/> - <textarea class="form-control mt16" id="reject_message" placeholder="Mail Body">Your message was rejected by moderator.</textarea> - </div> - - <!-- Mobile templates --> - <t t-name="mail.discuss_mobile"> - <div class="o_mail_discuss"> - <div class="o_mail_discuss_mobile_mailboxes_buttons"> - <button type="button" class="btn btn-primary d-inline d-md-none o_mailbox_inbox_item" title="Inbox" data-type="mailbox_inbox"> - Inbox - </button> - <button type="button" class="btn btn-secondary d-inline d-md-none o_mailbox_inbox_item" title="Starred" data-type="mailbox_starred"> - Starred - </button> - <button type="button" class="btn btn-secondary d-inline d-md-none o_mailbox_inbox_item" title="History" data-type="mailbox_history"> - History - </button> - </div> - <div class="o_mail_discuss_content"/> - <div class="o_mail_mobile_tabs"> - <div class="o_mail_mobile_tab" data-type="mailbox_inbox"> - <span class="fa fa-inbox"/> - <span class="o_tab_title">Inbox</span> - </div> - <div class="o_mail_mobile_tab" data-type="dm_chat"> - <span class="fa fa-user"/> - <span class="o_tab_title">Chat</span> - </div> - <div class="o_mail_mobile_tab" data-type="multi_user_channel"> - <span class="fa fa-users"/> - <span class="o_tab_title">Channels</span> - </div> - </div> - </div> - </t> - - <!-- - @param {boolean} [disableAddThread] whether the 'Add thread' action should be disabled or not for the considered discuss item category - @param {Object[]} previews valid objects for preview rendering (see mail.Preview template) - --> - <t t-name="mail.discuss.MobileTabPane"> - <div class="o_mail_discuss_tab_pane" t-att-data-type="type"> - <div t-if="!disableAddThread" class="o_mail_add_thread" t-att-data-type="type"> - <span t-if="type == 'multi_user_channel'">#</span> - <t t-set="inputPlaceholder" t-if="type == 'multi_user_channel'">Add a channel</t> - <t t-set="inputPlaceholder" t-if="type == 'dm_chat'">Open chat</t> - <input type="text" t-attf-placeholder="#{inputPlaceholder}"/> - </div> - <t t-foreach="previews" t-as="preview"> - <t t-call="mail.Preview"/> - </t> - </div> - </t> - - <!-- - The preview template is used by the discuss in mobile, and by the systray menu - In order to show preview of threads - - FIXME: it is shared with systray, so it should not be in discuss.xml - - @param {Object} preview a valid object for preview rendering - @param {integer} [preview.documentID] - @param {string} [preview.documentModel] - @param {string|integer} preview.id - @param {string} [preview.imageSRC] - @param {boolean} [preview.isMyselfAuthor] - @param {moment} [preview.date] - @param {string} [preview.author] - @param {string} [preview.body] - @param {string} [preview.title] - @param {string} [preview.status] - @param {integer} [preview.unreadCounter] - @param {integer[]} [preview.messageIDs] - --> - <t t-name="mail.Preview"> - <div t-attf-class="o_mail_preview #{preview.unreadCounter > 0 ? 'o_preview_unread' : ''}" - t-att-data-preview-id="preview.id" t-att-data-document-id="preview.documentID" t-att-data-document-model="preview.documentModel" t-att-data-unread-counter="preview.unreadCounter" t-att-data-message-ids="preview.messageIDs"> - <div t-attf-class="o_mail_preview_image #{preview.documentModel ? 'o_mail_preview_app' : ''}"> - <img class="o_mail_preview_image" t-att-src="preview.imageSRC" alt="Preview"/> - <t t-call="mail.UserStatus"> - <t t-set="status" t-value="preview.status"/> - </t> - </div> - <div class="o_preview_info"> - <div class="o_preview_title"> - <span class="o_preview_name"> - <t t-esc="preview.title"/> - </span> - <span class="o_preview_counter"> - <t t-if="preview.unreadCounter > 0">&nbsp;(<t t-esc="preview.unreadCounter"/>)</t> - </span> - <span t-if="preview.isLinkedToDocumentThread" class="o_discuss_icon o_thread_window_expand fa fa-expand"/> - <span class="o_last_message_date ml-auto mr-2"> <t t-esc="preview.date ? preview.date.fromNow() : ''"/> </span> - </div> - <div class="o_last_message_preview"> - <t t-if="preview.body"> - <t t-if="preview.isMyselfAuthor"> - <span class="fa fa-mail-reply" role="img" aria-label="Reply"/> You: - </t> - <t t-elif="preview.author"> - <t t-esc="preview.author"/>: - </t> - <t t-esc="preview.body"/> - </t> - </div> - <span title="Mark as Read" class="o_discuss_icon o_mail_preview_mark_as_read fa fa-check" t-if="preview.unreadCounter"/> - </div> - </div> - </t> - -</templates> diff --git a/addons/mail/static/src/xml/followers.xml b/addons/mail/static/src/xml/followers.xml deleted file mode 100644 index d1f6ebd63a4..00000000000 --- a/addons/mail/static/src/xml/followers.xml +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates> - - <!-- - Followers, actions and subtypes in a record. - --> - <t t-name="mail.Followers"> - <div class="o_followers btn-group"> - <div class="o_followers_title_box btn-group"> - <button class="btn btn-link" title="Dropdown menu - Followers" - data-toggle="dropdown" aria-expanded="false"> - <i class="fa fa-user" role="img" aria-label="Followers"></i> - <span class="o_followers_count"/> - </button> - <div class="dropdown-menu dropdown-menu-right o_followers_list" role="menu"/> - </div> - <div class="o_followers_actions btn-group"> - <button class="btn btn-link o_followers_follow_button o_followers_notfollow"> - <span class="o_follow">Follow</span> - <i class="fa fa-times o_followers_unfollow"/> - <span class="o_followers_unfollow"> Unfollow</span> - <i class="fa fa-check o_followers_following"/> - <span class="o_followers_following"> Following</span> - </button> - </div> - </div> - </t> - - <!-- - Partner or channel following the record - --> - <t t-name="mail.Followers.partner"> - <div role="menuitem" t-attf-class="dropdown-item o_partner {{ !record.is_active ? 'o_inactive': '' }}"> - <a class="o_mail_redirect text-truncate" - href="#" - t-att-title="record.title" - t-att-data-oe-model="record.partner_id ? 'res.partner' : 'mail.channel'" - t-att-data-oe-id="record.partner_id ? record.partner_id : record.channel_id"> - <img t-att-src="record.avatar_url" alt="Avatar" class="o_image_64_cover"/> - <t t-esc="record.name"/> - </a> - <button t-if="record.is_editable" - class="btn btn-icon fa fa-pencil o_edit_subtype d-none" - title="Edit subscription" - aria-label="Edit subscription" - role="img" - t-att-data-follower-id="record.id" - t-att-data-oe-id="record.partner_id ? record.partner_id : record.channel_id" - t-att-data-oe-model="record.partner_id ? 'res.partner' : 'mail.channel'"/> - <button t-if="widget.isEditable" - class="btn btn-icon fa fa-remove o_remove_follower" - aria-label="Remove this follower" - role="img" - title="Remove this follower"/> - </div> - </t> - - <!-- - 'Add followers' and 'Add channels' buttons - --> - <t t-name="mail.Followers.add_more"> - <t t-if="widget.isEditable"> - <a href="#" role="menuitem" class="dropdown-item o_add_follower">Add Followers</a> - <a href="#" role="menuitem" class="dropdown-item o_add_follower_channel">Add Channels</a> - <div role="separator" t-if="widget.followers.length > 0" class="dropdown-divider"/> - </t> - </t> - - <!-- - Message subtypes of a follower subscription - --> - <t t-name="mail.Followers.subtype"> - <div role="menuitem" class="o_subtype dropdown-item"> - <div class="custom-control custom-checkbox"> - <input type="checkbox" - t-attf-id="input_mail_followers_subtype_#{record.id + (dialog ? '_in_dialog': '')}" - t-att-name="record.name" - class="custom-control-input o_subtype_checkbox" - t-att-checked="record.followed" - t-att-data-id="record.id"/> - <label t-attf-for="input_mail_followers_subtype_#{record.id + (dialog ? '_in_dialog': '')}" - class="custom-control-label"> - <t t-esc="record.name"/> - </label> - </div> - <i t-if="display_warning" class="fa fa-warning text-warning" role="img" aria-label="Warning" title="Warning"/> - </div> - </t> - <t t-name="mail.Followers.subtypes.warning"> - <span class="text-warning"> - <i class="fa fa-warning"/> Be careful with channels following internal notifications - </span> - </t> - -</templates> diff --git a/addons/mail/static/src/xml/out_of_office.xml b/addons/mail/static/src/xml/out_of_office.xml deleted file mode 100644 index 19fb2c341c6..00000000000 --- a/addons/mail/static/src/xml/out_of_office.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates xml:space="preserve"> - <!-- - @param {mail.model.AbstractThread} thread - --> - <div class="o_out_of_office" t-name="mail.thread.OutOfOffice"> - <div class="o_out_of_office_info" t-if="thread.getOutOfOfficeInfo()" t-esc="thread.getOutOfOfficeInfo()"/> - </div> -</templates> diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index b10ef51a429..b9612e13a27 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -2,64 +2,6 @@ <templates> <!-- - @param {mail.systray.MessagingMenu} widget - --> - <t t-name="mail.systray.MessagingMenu"> - <li class="o_mail_systray_item"> - <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="false" title="Conversations" href="#" role="button"> - <i class="o_mail_messaging_menu_icon fa fa-comments fa-spinner fa-spin" role="img" aria-label="Messages"/> <span class="o_notification_counter badge badge-pill"/> - </a> - <div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu"> - <t t-if="widget.isMobile()"> - <div class="o_mail_systray_mobile_header"> - <button type="button" class="btn btn-secondary o_new_message"> New message </button> - </div> - </t> - <div t-if="!widget.isMobile()" class="o_mail_systray_dropdown_top"> - <div> - <button type="button" class="btn btn-link o_filter_button active" role="tab"> All </button> - <button type="button" class="btn btn-link o_filter_button" data-filter='chat' role="tab"> Chat </button> - <button type="button" class="btn btn-link o_filter_button" data-filter='channels' role="tab"> Channels </button> - </div> - <button type="button" class="btn btn-link o_new_message"> New message </button> - </div> - <div class="o_mail_systray_dropdown_items"/> - <t t-if="widget.isMobile()"> - <div class="o_mail_mobile_tabs"> - <div class="o_mail_mobile_tab o_filter_button active" role="tab"> - <span class="fa fa-envelope"/> - <span class="o_tab_title">All</span> - </div> - <div class="o_mail_mobile_tab o_filter_button" data-filter='chat' role="tab"> - <span class="fa fa-user"/> - <span class="o_tab_title">Chat</span> - </div> - <div class="o_mail_mobile_tab o_filter_button" data-filter='channels' role="tab"> - <span class="fa fa-users"/> - <span class="o_tab_title">Channels</span> - </div> - </div> - </t> - </div> - </li> - </t> - - <!-- - @param {Object} previews valid list of objects for preview rendering - (see mail.Preview template) - --> - <t t-name="mail.systray.MessagingMenu.Previews"> - <t t-if="_.isEmpty(previews)"> - <li class="text-center o_no_activity mt16"> - <span>No conversation yet...</span> - </li> - </t> - <t t-foreach="previews" t-as="preview"> - <t t-call="mail.Preview"/> - </t> - </t> - - <!-- @param {mail.systray.ActivityMenu} widget @param {Object[]} widget.activities --> diff --git a/addons/mail/static/src/xml/text_emojis.xml b/addons/mail/static/src/xml/text_emojis.xml index 56a74a54fd3..4f333ba941f 100644 --- a/addons/mail/static/src/xml/text_emojis.xml +++ b/addons/mail/static/src/xml/text_emojis.xml @@ -10,7 +10,7 @@ <i class="fa fa-smile-o"/> </button> <div class="dropdown-menu dropdown-menu-right border-0 p-2" style="width: 406px"> - <t t-call="mail.Composer.emojis"> + <t t-call="mail.legacy.Composer.emojis"> <t t-set="emojis" t-value="widget.emojis"></t> </t> </div> diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index 05f9f04f6f7..5a3205ed2cb 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -10,33 +10,6 @@ </t> </t> <!-- - @param {mail.model.AbstractThread} thread - @param {Object} options - @param {boolean} [options.displayEmptyThread] - @param {boolean} [options.displayModerationCommands] - @param {boolean} [options.displayNoMatchFound] - @param {Array} [options.domain=[]] the domain to restrict messages on the thread. - --> - <t t-name="mail.widget.Thread"> - <t t-if="thread.hasMessages({ 'domain': options.domain || [] })"> - <t t-call="mail.widget.Thread.Content"/> - </t> - <t t-elif="options.displayEmptyThread"> - <t t-call="mail.widget.Thread.Empty" /> - </t> - <div t-elif="options.displayNoMatchFound" class="o_mail_no_content"> - <div class="o_thread_title">No matches found</div> - <div>No message matches your search. Try to change your search filters.</div> - </div> - </t> - - <!-- Rendering of thread when messaging not yet ready --> - <div t-name="mail.widget.ThreadLoading" class="o_mail_thread_loading"> - <i class="o_mail_thread_loading_icon fa fa-spinner fa-spin"/> - <span>Please wait...</span> - </div> - - <!-- @param {mail.DocumentViewer} widget --> <t t-name="DocumentViewer.Content"> @@ -126,513 +99,4 @@ </html> </t> - <!-- - When a thread is empty - - @param {mail.model.Thread} thread - --> - <div t-name="mail.widget.Thread.Empty" class="o_mail_no_content"> - <t t-if="thread.getID() === 'mailbox_inbox'"> - <div class="o_thread_title">Congratulations, your inbox is empty</div> - <div>New messages appear here.</div> - </t> - <t t-if="thread.getID() === 'mailbox_starred'"> - <div class="o_thread_title">No starred messages</div> - <div>You can mark any message as 'starred', and it shows up in this mailbox.</div> - </t> - <t t-if="thread.getID() === 'mailbox_history'"> - <div class="o_thread_title o_neutral_face_icon">No history messages</div> - <div>Messages marked as read will appear in the history.</div> - </t> - <t t-if="thread.getID() === 'mailbox_moderation'"> - <div class="o_thread_title">You have no message to moderate</div> - <div>Pending moderation messages appear here.</div> - </t> - </div> - - <!-- - @param {mail.model.AbstractThread} thread - @param {Object} options - @param {integer} [options.displayOrder] 1 or -1 ascending (respectively, descending) order for - the thread messages (from top to bottom) - @param {Array} [options.domain=[]] the domain to restrict messages on the thread. - @param {Object} ORDER - @param {integer} ORDER.ASC=1 messages are ordered by ascending order of IDs, (from top to bottom) - @param {integer} ORDER.DESC=-1 messages are ordered by descending IDs, (from top to bottom) - - _____________ _____________ - | | | | - | message 1 | | message n | - | message 2 | | ... | - | ... | | message 2 | - | message n | | message 1 | - |_____________| |_____________| - - ORDER: ASC DESC - - --> - <t t-name="mail.widget.Thread.Content"> - <t t-set="messages" t-value="thread.getMessages({ 'domain': options.domain || [] })"/> - <t t-if="options.displayOrder === ORDER.ASC" t-call="mail.widget.Thread.Content.ASC"/> - <t t-else="" t-call="mail.widget.Thread.Content.DESC"/> - </t> - - <!-- - @param {mail.model.AbstractThread} thread - @param {Object} options - @param {boolean} [options.displayBottomThreadFreeSpace=false] - @param {boolean} [options.displayLoadMore=false] - - _____________ - | | - | message 1 | - | message 2 | - | ... | - | message n | - |_____________| - - ASC Order - --> - <t t-name="mail.widget.Thread.Content.ASC"> - <div class="o_mail_thread_content"> - <t t-if="options.displayLoadMore" t-call="mail.widget.Thread.LoadMore"/> - <t t-call="mail.widget.Thread.Messages"/> - <t t-if="options.displayBottomThreadFreeSpace"> - <div class="o_thread_bottom_free_space"/> - </t> - </div> - </t> - - <!-- - @param {mail.model.AbstractThread} thread - @param {Object} options - @param {boolean} [options.displayLoadMore=false] - @param {string|integer} [options.messagesSeparatorPosition] 'top' or - message ID, the separator is placed just after this message. - - _____________ - | | - | message n | - | ... | - | message 2 | - | message 1 | - |_____________| - - DESC Order - - --> - <t t-name="mail.widget.Thread.Content.DESC"> - <div class="o_mail_thread_content"> - <t t-if="options.messagesSeparatorPosition == 'top'" t-call="mail.MessagesSeparator"/> - <t t-set="messages" t-value="messages.slice().reverse()"/> - <t t-call="mail.widget.Thread.Messages"/> - <t t-if="options.displayLoadMore" t-call="mail.widget.Thread.LoadMore"/> - </div> - </t> - - <!-- - @param {mail.model.AbstractMessage[]} messages messages are ordered based - on desired display order - --> - <t t-name="mail.widget.Thread.Messages"> - <t t-set="current_day" t-value="0"/> - <t t-foreach="messages" t-as="message"> - <div t-if="current_day !== message.getDateDay()" class="o_thread_date_separator"> - <span class="o_thread_date"> - <t t-esc="message.getDateDay()"/> - </span> - <t t-set="current_day" t-value="message.getDateDay()"/> - </div> - - <t t-call="mail.widget.Thread.Message"/> - </t> - </t> - - <!-- - @param {mail.model.AbstractThread} thread - @param {string} dateFormat - @param {Object} options - @param {mail.model.AbstractMessage} message - @param {Object} options - @param {boolean} [options.displayAvatars] - @param {boolean} [options.displayDocumentLinks] - @param {boolean} [options.displayNotificationIcons] - @param {boolean} [options.displayMarkAsRead] - @param {boolean} [options.displayModerationCommands] when set, display the moderation commands on - the message. This includes the moderation checkboxes (needs a control panel such as in Discuss app). - @param {boolean} [options.displayReplyIcons] - @param {boolean} [options.displayStars] - @param {boolean} [options.displaySubjectsOnMessages] - @param {boolean} options.hasMessageAttachmentDeletable - @param {string|integer} [options.messagesSeparatorPosition] 'top' or - message ID, the separator is placed just after this message. - @param {integer} [options.selectedMessageID] - --> - <t t-name="mail.widget.Thread.Message"> - <div t-if="!message.isEmpty()" t-att-class="'o_thread_message ' + (message.getID() === options.selectedMessageID ? 'o_thread_selected_message ' : ' ') + (message.isDiscussion() or message.isNotification() ? ' o_mail_discussion ' : ' o_mail_not_discussion ')" t-att-data-message-id="message.getID()"> - <div t-if="options.displayAvatars" class="o_thread_message_sidebar"> - <t t-if="message.hasAuthor()"> - <div t-if="displayAuthorMessages[message.getID()]" class="o_thread_message_sidebar_image"> - <img - alt="" - t-att-src="message.getAvatarSource()" - data-oe-model="res.partner" - t-att-data-oe-id="message.shouldRedirectToAuthor() ? message.getAuthorID() : ''" - t-attf-class="o_thread_message_avatar rounded-circle #{message.shouldRedirectToAuthor() ? 'o_mail_redirect' : ''}"/> - <t t-call="mail.UserStatus"> - <t t-set="status" t-value="message.getAuthorImStatus()"/> - <t t-set="partnerID" t-value="message.getAuthorID()"/> - </t> - </div> - </t> - <t t-else=""> - <img t-if="displayAuthorMessages[message.getID()]" - alt="" - t-att-src="message.getAvatarSource()" - class="o_thread_message_avatar rounded-circle"/> - </t> - <span t-if="!displayAuthorMessages[message.getID()]" t-att-title="message.getDate().format(dateFormat)" class="o_thread_message_side_date"> - <t t-esc="message.getDate().format('hh:mm')"/> - </span> - <i t-if="!displayAuthorMessages[message.getID()] and options.displayStars and message.getType() !== 'notification'" - t-att-class="'fa o_thread_message_star o_thread_icon ' + (message.isStarred() ? 'fa-star' : 'fa-star-o')" - t-att-data-message-id="message.getID()" title="Mark as Todo" role="img" aria-label="Mark as todo"/> - <t t-if="!displayAuthorMessages[message.getID()] and thread.hasSeenFeature()" t-call="mail.widget.Thread.Message.SeenIcon"/> - </div> - <div class="o_thread_message_core"> - <p t-if="displayAuthorMessages[message.getID()]" class="o_mail_info text-muted"> - <input t-if="message.needsModeration() and message.needsModerationByUser() and options.displayModerationCommands" type="checkbox" class="moderation_checkbox" t-att-data-message-id="message.getID()"/> - <t t-if="message.isNote()"> - Note by - </t> - - <strong t-if="message.hasAuthor()" - data-oe-model="res.partner" t-att-data-oe-id="message.shouldRedirectToAuthor() ? message.getAuthorID() : ''" - t-attf-class="o_thread_author #{message.shouldRedirectToAuthor() ? 'o_mail_redirect' : ''}"> - <t t-esc="message.getDisplayedAuthor()"/> - </strong> - <strong t-elif="message.hasEmailFrom()"> - <a class="text-muted" t-attf-href="mailto:#{message.getEmailFrom()}?subject=Re: #{message.hasSubject() ? message.getSubject() : ''}"> - <t t-esc="message.getEmailFrom()"/> - </a> - </strong> - <strong t-else="" class="o_thread_author"> - <t t-esc="message.getDisplayedAuthor()"/> - </strong> - - - <small class="o_mail_timestamp" t-att-title="message.getDate().format(dateFormat)"><t t-esc="message.getTimeElapsed()"/></small> - <t t-if="message.isLinkedToDocumentThread() and options.displayDocumentLinks"> - <small>on</small> <a t-att-href="message.getURL()" t-att-data-oe-model="message.getDocumentModel()" t-att-data-oe-id="message.getDocumentID()" class="o_document_link"><t t-esc="message.getDocumentName()"/></a> - </t> - <t t-if="message.originatesFromChannel() and (message.getOriginChannelID() !== thread.getID())"> - (<small>from</small> <a t-att-data-oe-id="message.getOriginChannelID()" href="#">#<t t-esc="message.getOriginChannelName()"/></a>) - </t> - <span t-if="options.displayNotificationIcons and message.hasNotifications()" class="o_thread_tooltip_container"> - <span name="notification_icon" t-attf-class="d-inline-flex align-items-center o_thread_tooltip o_thread_message_notification {{ message.hasNotificationsError() ? 'o_thread_message_notification_error' : '' }}" t-att-data-message-id="message.getID()" t-att-data-message-type="message.getType()"> - <i t-att-class="message.getNotificationIcon()"/> - <small t-if="message.getNotificationText()" t-esc="message.getNotificationText()" class="font-weight-bold ml-1"/> - </span> - </span> - <span t-attf-class="o_thread_icons"> - <t t-if="thread.hasSeenFeature()" t-call="mail.widget.Thread.Message.SeenIcon"/> - <i t-if="options.displayStars and !message.isSystemNotification() and !message.needsModeration()" - t-att-class="'fa fa-lg o_thread_icon o_thread_message_star ' + (message.isStarred() ? 'fa-star' : 'fa-star-o')" - t-att-data-message-id="message.getID()" title="Mark as Todo" role="img" aria-label="Mark as Todo"/> - <i t-if="message.isLinkedToDocumentThread() and options.displayReplyIcons" - class="fa fa-reply o_thread_icon o_thread_message_reply" - t-att-data-message-id="message.getID()" title="Reply" role="img" aria-label="Reply"/> - <i t-if="message.isNeedaction() and options.displayMarkAsRead" - class="fa fa-check o_thread_icon o_thread_message_needaction" - t-att-data-message-id="message.getID()" title="Mark as Read" role="img" aria-label="Mark as Read"/> - - <t t-if="message.needsModeration() and message.originatesFromChannel()"> - <t t-call="mail.MessageModeration"/> - </t> - </span> - </p> - <div class="o_thread_message_content"> - <t t-raw="message.getBody()"/> - <t t-if="message.hasTrackingValues()"> - <t t-if="message.hasSubtypeDescription()"> - <p><t t-esc="message.getSubtypeDescription()"/></p> - </t> - <t t-call="mail.widget.Thread.MessageTracking"/> - </t> - <p t-if="options.displaySubjectOnMessages and message.shouldDisplaySubject()" class="o_mail_subject">Subject: <t t-esc="message.getSubject()"/></p> - <t t-if="message.hasAttachments()"> - <div t-if="message.hasImageAttachments()" class="o_attachments_previews"> - <t t-foreach="message.getImageAttachments()" t-as="attachment"> - <t t-call="mail.AttachmentPreview"> - <t t-set="isDeletable" t-value="options.hasMessageAttachmentDeletable"/> - </t> - </t> - </div> - <div t-if="message.hasNonImageAttachments()" class="o_attachments_list"> - <t t-foreach="message.getNonImageAttachments()" t-as="attachment"> - <t t-call="mail.Attachment"> - <t t-set="isDeletable" t-value="options.hasMessageAttachmentDeletable"/> - </t> - </t> - </div> - </t> - </div> - </div> - </div> - <t t-if="options.messagesSeparatorPosition == message.getID()"> - <t t-call="mail.MessagesSeparator"/> - </t> - </t> - - <!-- - Display the seen icon of a message in the thread. - It shows the fetch 'check' before the seen 'check'. We change the order in the template - so that fetch 'check' is on top of 'seen' check (z-index does not work with absolute positioning) - - @param {mail.model.Thread} thread - @param {mail.model.Message} message - --> - <t t-name="mail.widget.Thread.Message.SeenIcon"> - <t t-if="message.isMyselfAuthor() and message.getID() >= thread.getLastMessageIDSeenByEveryone()"> - <span t-attf-class="o_mail_thread_message_seen_icon #{thread.hasEveryoneSeen(message) ? 'o_all_seen' : ''}" t-att-data-message-id="message.getID()"> - <t t-if="thread.hasSomeoneFetched(message)"> - <i class="fa fa-check"/> - </t> - <t t-if="thread.hasSomeoneSeen(message)"> - <i class="fa fa-check"/> - </t> - </span> - </t> - </t> - - <!-- - Display the popover content when clicking the seen icion of a message in the thread. - - List the members that have received the messages, and the members that have seen it. - - @param {mail.model.Thread} thread - @param {mail.model.Message} message - --> - <t t-name="mail.widget.Thread.Message.SeenIconPopoverContent"> - <div class="o_mail_thread_message_seen_icon_content"> - <t t-if="thread.hasEveryoneSeen(message)"> - <p>Seen by Everyone</p> - </t> - <t t-else=""> - <t t-if="thread.hasSomeoneSeen(message)"> - <t t-set="seen_members" t-value="thread.getSeenMembers(message)"/> - Seen by: - <ul> - <li t-foreach="seen_members" t-as="member"> - <t t-esc="member.name"/> (<t t-esc="member.email"/>) - </li> - </ul> - </t> - <t t-if="thread.hasSomeoneFetched(message)"> - <t t-if="thread.hasEveryoneFetched(message)"> - <p>Received by Everyone</p> - </t> - <t t-else=""> - <t t-set="fetched_members" t-value="thread.getFetchedNotSeenMembers(message)"/> - <t t-if="!_.isEmpty(fetched_members)"> - Received by: - <ul> - <li t-foreach="fetched_members" t-as="member"> - <t t-esc="member.name"/> (<t t-esc="member.email"/>) - </li> - </ul> - </t> - </t> - </t> - </t> - </div> - </t> - - <!-- - @param {Object[]} notifications: list of notifications - A notification is an object with at least the following keys: - {notification_status, partner_name} - --> - <t t-name="mail.widget.Thread.Message.MailTooltip"> - <div t-foreach="notifications" t-as="notification"> - <span name="notification_status" class="d-inline-block text-center o_thread_tooltip_icon"> - <i t-if="notification.notification_status === 'sent'" class='fa fa-check' title="Sent" role="img" aria-label="Sent"/> - <i t-if="notification.notification_status === 'bounce'" class='fa fa-exclamation text-danger' title="Bounced" role="img" aria-label="Bounced"/> - <i t-if="notification.notification_status === 'exception'" class='fa fa-exclamation text-danger' title="Error" role="img" aria-label="Error"/> - <i t-if="notification.notification_status === 'ready'" class='fa fa-send-o' title="Ready" role="img" aria-label="Ready"/> - <i t-if="notification.notification_status === 'canceled'" class='fa fa-trash-o' title="Canceled" role="img" aria-label="Canceled"/> - </span> - <span name="partner_name" t-esc="notification.partner_name"/> - </div> - </t> - <!-- - @param {mail.model.Message} message - @param {Object} options - @param {boolean} [options.displayModerationCommands] - --> - <t t-name="mail.MessageModeration"> - <i t-if="message.isMyselfAuthor()" class="text-danger" title="Your message is pending moderation"><b>Pending moderation</b></i> - <t t-elif="message.needsModerationByUser()"> - <t t-if="options.displayModerationCommands" t-call="mail.MessageModerationDecision"/> - <i t-else="" class="text-danger" title="Open Channel in Discuss to moderate"><b>Pending moderation</b></i> - </t> - </t> - - <!-- - @param {mail.model.Message} message - --> - <t t-name="mail.MessageModerationDecision"> - <i class="o_thread_icon ml4 o_thread_message_moderation text-success" - t-att-data-message-id="message.getID()" data-decision="accept" title="Accept"><b>Accept |</b></i> - <i class="o_thread_icon ml4 o_thread_message_moderation text-danger" - t-att-data-message-id="message.getID()" data-decision="reject" title="Remove message with explanation"><b>Reject |</b></i> - <i class="o_thread_icon ml4 o_thread_message_moderation text-danger" - t-att-data-message-id="message.getID()" data-decision="discard" title="Remove message without explanation"><b>Discard |</b></i> - <i class="o_thread_icon ml4 o_thread_message_moderation text-success" - t-att-data-message-id="message.getID()" data-decision="allow" title="Add this email address to white list of people"><b>Always Allow |</b></i> - <i class="o_thread_icon ml4 o_thread_message_moderation text-danger" - t-att-data-message-id="message.getID()" data-decision="ban" title="Ban this email address"><b>Ban</b></i> - </t> - - <t t-name="mail.MessagesSeparator"> - <div class="o_thread_new_messages_separator"> - <span class="o_thread_separator_label">New messages</span> - </div> - </t> - - <!-- - @param {mail.model.Message} message - --> - <t t-name="mail.widget.Thread.MessageTracking"> - <ul class="o_mail_thread_message_tracking"> - <t t-foreach='message.getTrackingValues()' t-as='value'> - <li> - <t t-esc="value.changed_field"/>: - <t t-if="value.old_value"> - <span> <t t-esc="value.old_value || ((value.field_type !== 'boolean') and '')"/> </span> - <span t-if="value.old_value !== value.new_value" class="fa fa-long-arrow-right" role="img" aria-label="Changed" title="Changed"/> - </t> - <span t-if="value.old_value !== value.new_value"> - <t t-esc="value.new_value || ((value.field_type !== 'boolean') and '')"/> - </span> - </li> - </t> - </ul> - </t> - - <!-- - @param {Array} attachments - --> - <t t-name="mail.composer.Attachments"> - <div t-if="attachments.length > 0" class="o_attachments o_attachments_list"> - <t t-foreach="attachments" t-as='attachment'> - <t t-call="mail.Attachment"> - <t t-set="editable" t-value="true"/> - </t> - </t> - </div> - </t> - - <!-- - @param {Object} attachment - @param {integer} attachment.id - @param {string} attachment.name - @param {string} attachment.url - @param {boolean} [isDeletable=false] - --> - <t t-name="mail.AttachmentPreview"> - <div class="o_attachment" t-att-title="attachment.name"> - <div class="o_attachment_wrap"> - <div class="o_image_box"> - <div class="o_attachment_image" t-attf-style="background-image:url('/web/image/#{attachment.id}/160x160/?crop=true')"/> - <div t-attf-class="o_image_overlay o_attachment_view" t-att-data-id="attachment.id"> - <span t-if="isDeletable" class="fa fa-times o_attachment_delete_cross" t-att-title="'Delete ' + attachment.name" t-att-data-id="attachment.id" t-att-data-name="attachment.name"/> - <span class="o_attachment_title text-white"><t t-esc="attachment.name"/></span> - <a class="o_attachment_download" t-att-href='attachment.url'> - <i t-attf-class="fa fa-download text-white" t-att-title="'Download ' + attachment.name" role="img" aria-label="Download"></i> - </a> - </div> - </div> - </div> - </div> - </t> - - <!-- - @param {Object} attachment - @param {string} attachment.filename - @param {integer} attachment.id - @param {string} [attachment.mimetype] - @param {string} attachment.name - @param {boolean} attachment.upload - @param {string} attachment.url - @param {boolean} [editable=false] if set, it means the attachment is rendered in the composer. - Some changes are required in that case, such as "delete" button is not visible (pretty unlink is used instead). - @param {boolean} [isDeletable=false] - --> - <t t-name="mail.Attachment"> - <t t-set="type" t-value="attachment.mimetype and attachment.mimetype.split('/').shift()"/> - <div t-attf-class="o_attachment #{ editable ? 'o_attachment_editable' : '' } #{attachment.upload ? 'o_attachment_uploading' : ''}" t-att-title="attachment.name"> - <div class="o_attachment_wrap"> - <span t-if="!editable and isDeletable" class="fa fa-times o_attachment_delete_cross" t-att-title="'Delete ' + attachment.name" t-att-data-id="attachment.id" t-att-data-name="attachment.name"/> - <t t-set="has_preview" t-value="type == 'image' or type == 'video' or attachment.mimetype == 'application/pdf'"/> - <t t-set="ext" t-value="attachment.filename.split('.').pop()"/> - - <div t-attf-class="o_image_box float-left #{has_preview ? 'o_attachment_view' : ''}" t-att-data-id="attachment.id"> - <div t-if="has_preview" - class="o_image o_hover" - t-att-style="type == 'image' ? 'background-image:url(/web/image/' + attachment.id + '/38x38/?crop=true' : '' " - t-att-data-mimetype="attachment.mimetype"> - </div> - <a t-elif="!editable" t-att-href='attachment.url' t-att-title="'Download ' + attachment.name" aria-label="Download"> - <span class="o_image o_hover" t-att-data-mimetype="attachment.mimetype" t-att-data-ext="ext"/> - </a> - <span t-else="" class="o_image" t-att-data-mimetype="attachment.mimetype" t-att-data-ext="ext" role="img" aria-label="Document not downloadable"/> - </div> - - <div class="caption"> - <span t-if="has_preview or editable" t-attf-class="ml4 #{has_preview? 'o_attachment_view' : ''}" t-att-data-id="attachment.id"><t t-esc='attachment.name'/></span> - <a t-else="" class="ml4" t-att-href="attachment.url" t-att-title="'Download ' + attachment.name"><t t-esc='attachment.name'/></a> - </div> - <div t-if="editable" class="caption small"> - <b t-attf-class="ml4 small text-uppercase #{has_preview? 'o_attachment_view' : ''}" t-att-data-id="attachment.id"><t t-esc="ext"/></b> - <div class="progress o_attachment_progress_bar"> - <div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div> - </div> - </div> - <div t-if="!editable" class="caption small"> - <b t-if="has_preview" class="ml4 small text-uppercase o_attachment_view" t-att-data-id="attachment.id"><t t-esc="ext"/></b> - <a t-else="" class="ml4 small text-uppercase" t-att-href="attachment.url" t-att-title="'Download ' + attachment.name"><b><t t-esc='ext'/></b></a> - <a class="ml4 o_attachment_download float-right" t-att-title="'Download ' + attachment.name" t-att-href='attachment.url'><i t-attf-class="fa fa-download" role="img" aria-label="Download"/></a> - </div> - <div t-if="editable" class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div> - <div t-if="editable" class="o_attachment_delete" t-att-data-id="attachment.id"><span class="text-white" role="img" aria-label="Delete" title="Delete">×</span></div> - </div> - </div> - </t> - - <!-- - @param {Object} options - @param {boolean} [options.loadMoreOnScroll] - --> - <t t-name="mail.widget.Thread.LoadMore"> - <div class="o_thread_show_more"> - <t t-if="options.loadMoreOnScroll"> - <span><i class="fa fa-spinner fa-spin" role="img" aria-label="Please wait" title="Please wait"/> Loading older messages... </span> - </t> - <t t-else=""> - <button class="btn btn-link">-------- Show older messages --------</button> - </t> - </div> - </t> - - <!-- - @param {mail.model.Thread} thread with typing feature - --> - <t t-name="mail.ThreadTypingIcon"> - <span class="o_mail_thread_typing_icon" t-att-title="thread.getTypingMembersToText()"> - <span class="o_mail_thread_typing_icon_dot"/> - <span class="o_mail_thread_typing_icon_dot"/> - <span class="o_mail_thread_typing_icon_dot"/> - </span> - </t> - </templates> diff --git a/addons/mail/static/src/xml/thread_window.xml b/addons/mail/static/src/xml/thread_window.xml deleted file mode 100644 index 1e8d3e97c2e..00000000000 --- a/addons/mail/static/src/xml/thread_window.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<templates xml:space="preserve"> - - <!-- - @param {mail.ThreadWindow} widget - --> - <t t-name="mail.ThreadWindow" t-extend="mail.AbstractThreadWindow"> - <t t-jquery=".o_thread_window_header" t-operation="after"> - <t t-if="widget.hasThread()"> - <t t-if="widget.getThread().hasOutOfOffice()"> - <t t-call="mail.thread.OutOfOffice"> - <t t-set="thread" t-value="widget.getThread()"/> - </t> - </t> - </t> - <div t-else="" class="o_thread_search_input"> - <span> To: </span> - <input type="text" placeholder="User name"/> - </div> - </t> - </t> - - <!-- - @param {string} expandTitle text to display on mouse hover (title attribute) - --> - <t t-extend="mail.AbstractThreadWindow.HeaderContent"> - <t t-jquery=".o_thread_window_buttons" t-operation="prepend"> - <a href="#" class="o_thread_window_expand fa fa-expand" t-att-title="expandTitle" t-att-aria-label="expandTitle"/> - </t> - </t> - -</templates> |
