diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/components/discuss_sidebar_item | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/components/discuss_sidebar_item')
3 files changed, 392 insertions, 0 deletions
diff --git a/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.js b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.js new file mode 100644 index 00000000..0226035c --- /dev/null +++ b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.js @@ -0,0 +1,220 @@ +odoo.define('mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.js', function (require) { +'use strict'; + +const components = { + EditableText: require('mail/static/src/components/editable_text/editable_text.js'), + ThreadIcon: require('mail/static/src/components/thread_icon/thread_icon.js'), +}; +const useShouldUpdateBasedOnProps = require('mail/static/src/component_hooks/use_should_update_based_on_props/use_should_update_based_on_props.js'); +const useStore = require('mail/static/src/component_hooks/use_store/use_store.js'); +const { isEventHandled } = require('mail/static/src/utils/utils.js'); + +const Dialog = require('web.Dialog'); + +const { Component } = owl; + +class DiscussSidebarItem extends Component { + + /** + * @override + */ + constructor(...args) { + super(...args); + useShouldUpdateBasedOnProps(); + useStore(props => { + const discuss = this.env.messaging.discuss; + const thread = this.env.models['mail.thread'].get(props.threadLocalId); + const correspondent = thread ? thread.correspondent : undefined; + return { + correspondentName: correspondent && correspondent.name, + discussIsRenamingThread: discuss && discuss.renamingThreads.includes(thread), + isDiscussThread: discuss && discuss.thread === thread, + starred: this.env.messaging.starred, + thread, + threadChannelType: thread && thread.channel_type, + threadCounter: thread && thread.counter, + threadDisplayName: thread && thread.displayName, + threadGroupBasedSubscription: thread && thread.group_based_subscription, + threadLocalMessageUnreadCounter: thread && thread.localMessageUnreadCounter, + threadMassMailing: thread && thread.mass_mailing, + threadMessageNeedactionCounter: thread && thread.message_needaction_counter, + threadModel: thread && thread.model, + }; + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Get the counter of this discuss item, which is based on the thread type. + * + * @returns {integer} + */ + get counter() { + if (this.thread.model === 'mail.box') { + return this.thread.counter; + } else if (this.thread.channel_type === 'channel') { + return this.thread.message_needaction_counter; + } else if (this.thread.channel_type === 'chat') { + return this.thread.localMessageUnreadCounter; + } + return 0; + } + + /** + * @returns {mail.discuss} + */ + get discuss() { + return this.env.messaging && this.env.messaging.discuss; + } + + /** + * @returns {boolean} + */ + hasUnpin() { + return this.thread.channel_type === 'chat'; + } + + /** + * @returns {mail.thread} + */ + get thread() { + return this.env.models['mail.thread'].get(this.props.threadLocalId); + } + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @returns {Promise} + */ + _askAdminConfirmation() { + return new Promise(resolve => { + Dialog.confirm(this, + this.env._t("You are the administrator of this channel. Are you sure you want to leave?"), + { + buttons: [ + { + text: this.env._t("Leave"), + classes: 'btn-primary', + close: true, + click: resolve + }, + { + text: this.env._t("Discard"), + close: true + } + ] + } + ); + }); + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + _onCancelRenaming(ev) { + this.discuss.cancelThreadRenaming(this.thread); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClick(ev) { + if (isEventHandled(ev, 'EditableText.click')) { + return; + } + this.thread.open(); + } + + /** + * Stop propagation to prevent selecting this item. + * + * @private + * @param {CustomEvent} ev + */ + _onClickedEditableText(ev) { + ev.stopPropagation(); + } + + /** + * @private + * @param {MouseEvent} ev + */ + async _onClickLeave(ev) { + ev.stopPropagation(); + if (this.thread.creator === this.env.messaging.currentUser) { + await this._askAdminConfirmation(); + } + this.thread.unsubscribe(); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickRename(ev) { + ev.stopPropagation(); + this.discuss.setThreadRenaming(this.thread); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickSettings(ev) { + ev.stopPropagation(); + return this.env.bus.trigger('do-action', { + action: { + type: 'ir.actions.act_window', + res_model: this.thread.model, + res_id: this.thread.id, + views: [[false, 'form']], + target: 'current' + }, + }); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickUnpin(ev) { + ev.stopPropagation(); + this.thread.unsubscribe(); + } + + /** + * @private + * @param {CustomEvent} ev + * @param {Object} ev.detail + * @param {string} ev.detail.newName + */ + _onValidateEditableText(ev) { + ev.stopPropagation(); + this.discuss.renameThread(this.thread, ev.detail.newName); + } + +} + +Object.assign(DiscussSidebarItem, { + components, + props: { + threadLocalId: String, + }, + template: 'mail.DiscussSidebarItem', +}); + +return DiscussSidebarItem; + +}); diff --git a/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.scss b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.scss new file mode 100644 index 00000000..aebc4b9a --- /dev/null +++ b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.scss @@ -0,0 +1,109 @@ +// ------------------------------------------------------------------ +// Layout +// ------------------------------------------------------------------ + +.o_DiscussSidebarItem { + display: flex; + align-items: center; + padding: map-get($spacers, 1) 0; + + &:hover .o_DiscussSidebarItem_commands { + display: flex; + } +} + +.o_DiscussSidebarItem_activeIndicator { + width: $o-mail-discuss-sidebar-active-indicator-width; + align-self: stretch; + flex: 0 0 auto; +} + +.o_DiscussSidebarItem_command { + margin-left: 3px; + margin-right: 3px; + + &:first-child { + margin-left: 0px; + } + + &:last-child { + margin-right: 0px; + } +} + +.o_DiscussSidebarItem_commands { + display: none; +} + +.o_DiscussSidebarItem_item { + margin-left: 3px; + margin-right: 3px; + + &:first-child { + margin-left: 0px; + margin-right: $o-mail-discuss-sidebar-active-indicator-margin-right; + } + + &:last-child { + margin-right: $o-mail-discuss-sidebar-scrollbar-width; + } +} + +.o_DiscussSidebarItem_name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + &.o-editable { + margin-left: $o-mail-discuss-sidebar-active-indicator-width + $o-mail-discuss-sidebar-active-indicator-margin-right; + margin-right: $o-mail-discuss-sidebar-scrollbar-width; + } +} + +.o_DiscussSidebarItem_nameInput { + width: 100%; +} + +// ------------------------------------------------------------------ +// Style +// ------------------------------------------------------------------ + +.o_DiscussSidebarItem { + cursor: pointer; + + &:hover { + background-color: darken(gray('900'), 5%); + } + + &.o-starred-box { + .o_DiscussSidebarItem_counter { + border-color: gray('600'); + background-color: gray('600'); + } + } +} + +.o_DiscussSidebarItem_activeIndicator.o-item-active { + background-color: $o-brand-primary; +} + +.o_DiscussSidebarItem_command:not(:hover) { + color: gray('600'); +} + +.o_DiscussSidebarItem_counter { + background-color: $o-brand-primary; +} + +.o_DiscussSidebarItem_name { + + &.o-item-unread { + font-weight: bold; + } +} + +.o_DiscussSidebarItem_nameInput { + outline: none; + border: none; + border-radius: 2px; +} diff --git a/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml new file mode 100644 index 00000000..74aace21 --- /dev/null +++ b/addons/mail/static/src/components/discuss_sidebar_item/discuss_sidebar_item.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates xml:space="preserve"> + + <t t-name="mail.DiscussSidebarItem" owl="1"> + <div class="o_DiscussSidebarItem" + t-att-class="{ + 'o-active': thread and discuss.thread === thread, + 'o-starred-box': thread and thread === env.messaging.starred, + 'o-unread': thread and thread.localMessageUnreadCounter > 0, + }" t-on-click="_onClick" t-att-data-thread-local-id="thread ? thread.localId : undefined" t-att-data-thread-name="thread ? thread.displayName : undefined" + > + <t t-if="thread"> + <div class=" o_DiscussSidebarItem_activeIndicator o_DiscussSidebarItem_item" t-att-class="{ 'o-item-active': discuss.thread === thread }"/> + <ThreadIcon class="o_DiscussSidebarItem_item" threadLocalId="thread.localId"/> + <t t-if="thread.channel_type === 'chat' and discuss.renamingThreads.includes(thread)"> + <div class="o_DiscussSidebarItem_item o_DiscussSidebarItem_name o-editable"> + <EditableText + class="o_DiscussSidebarItem_nameInput" + placeholder="thread.correspondent ? thread.correspondent.name : thread.name" + value="thread.displayName" + t-on-o-cancel="_onCancelRenaming" + t-on-o-clicked="_onClickedEditableText" + t-on-o-validate="_onValidateEditableText" + /> + </div> + </t> + <t t-else=""> + <div class="o_DiscussSidebarItem_item o_DiscussSidebarItem_name" t-att-class="{ 'o-item-unread': thread.localMessageUnreadCounter > 0 }"> + <t t-esc="thread.displayName"/> + </div> + <t t-if="thread.mass_mailing"> + <i class="fa fa-envelope-o" title="Messages are sent by email" role="img"/> + </t> + </t> + <div class="o-autogrow o_DiscussSidebarItem_item"/> + <t t-if="thread.model !== 'mail.box'"> + <div class="o_DiscussSidebarItem_commands o_DiscussSidebarItem_item"> + <t t-if="thread.channel_type === 'channel'"> + <div class="fa fa-cog o_DiscussSidebarItem_command o_DiscussSidebarItem_commandSettings" t-on-click="_onClickSettings" title="Channel settings" role="img"/> + <t t-if="!thread.message_needaction_counter and !thread.group_based_subscription"> + <div class="o_DiscussSidebarItem_command o_DiscussSidebarItem_commandLeave fa fa-times" t-on-click="_onClickLeave" title="Leave this channel" role="img"/> + </t> + </t> + <t t-if="thread.channel_type === 'chat'"> + <div class="o_DiscussSidebarItem_command o_DiscussSidebarItem_commandRename fa fa-cog" t-on-click="_onClickRename" title="Rename conversation" role="img"/> + </t> + <t t-if="hasUnpin()"> + <t t-if="!thread.localMessageUnreadCounter"> + <div class="fa fa-times o_DiscussSidebarItem_command o_DiscussSidebarItem_commandUnpin" t-on-click="_onClickUnpin" title="Unpin conversation" role="img"/> + </t> + </t> + </div> + </t> + <t t-if="counter > 0"> + <div class="o_DiscussSidebarItem_counter o_DiscussSidebarItem_item badge badge-pill"> + <t t-esc="counter"/> + </div> + </t> + </t> + </div> + </t> + +</templates> |
