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/widgets/discuss | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/widgets/discuss')
| -rw-r--r-- | addons/mail/static/src/widgets/discuss/discuss.js | 397 | ||||
| -rw-r--r-- | addons/mail/static/src/widgets/discuss/discuss.scss | 36 | ||||
| -rw-r--r-- | addons/mail/static/src/widgets/discuss/discuss.xml | 27 |
3 files changed, 460 insertions, 0 deletions
diff --git a/addons/mail/static/src/widgets/discuss/discuss.js b/addons/mail/static/src/widgets/discuss/discuss.js new file mode 100644 index 00000000..86f3ba32 --- /dev/null +++ b/addons/mail/static/src/widgets/discuss/discuss.js @@ -0,0 +1,397 @@ +odoo.define('mail/static/src/widgets/discuss/discuss.js', function (require) { +'use strict'; + +const components = { + Discuss: require('mail/static/src/components/discuss/discuss.js'), +}; +const InvitePartnerDialog = require('mail/static/src/widgets/discuss_invite_partner_dialog/discuss_invite_partner_dialog.js'); + +const AbstractAction = require('web.AbstractAction'); +const { action_registry, qweb } = require('web.core'); + +const { Component } = owl; + +const DiscussWidget = AbstractAction.extend({ + template: 'mail.widgets.Discuss', + hasControlPanel: true, + loadControlPanel: true, + withSearchBar: true, + searchMenuTypes: ['filter', 'favorite'], + /** + * @override {web.AbstractAction} + * @param {web.ActionManager} parent + * @param {Object} action + * @param {Object} [action.context] + * @param {string} [action.context.active_id] + * @param {Object} [action.params] + * @param {string} [action.params.default_active_id] + * @param {Object} [options={}] + */ + init(parent, action, options={}) { + this._super(...arguments); + + // render buttons in control panel + this.$buttons = $(qweb.render('mail.widgets.Discuss.DiscussControlButtons')); + this.$buttons.find('button').css({ display: 'inline-block' }); + this.$buttons.on('click', '.o_invite', ev => this._onClickInvite(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonMarkAllRead', + ev => this._onClickMarkAllAsRead(ev) + ); + this.$buttons.on('click', '.o_mobile_new_channel', ev => this._onClickMobileNewChannel(ev)); + this.$buttons.on('click', '.o_mobile_new_message', ev => this._onClickMobileNewMessage(ev)); + this.$buttons.on('click', '.o_unstar_all', ev => this._onClickUnstarAll(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonSelectAll', ev => this._onClickSelectAll(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonUnselectAll', ev => this._onClickUnselectAll(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonModeration.o-accept', ev => this._onClickModerationAccept(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonModeration.o-discard', ev => this._onClickModerationDiscard(ev)); + this.$buttons.on('click', '.o_widget_Discuss_controlPanelButtonModeration.o-reject', ev => this._onClickModerationReject(ev)); + + // control panel attributes + this.action = action; + this.actionManager = parent; + this.searchModelConfig.modelName = 'mail.message'; + this.discuss = undefined; + this.options = options; + + this.component = undefined; + + this._lastPushStateActiveThread = null; + }, + /** + * @override + */ + async willStart() { + await this._super(...arguments); + this.env = Component.env; + await this.env.messagingCreatedPromise; + const initActiveId = this.options.active_id || + (this.action.context && this.action.context.active_id) || + (this.action.params && this.action.params.default_active_id) || + 'mail.box_inbox'; + this.discuss = this.env.messaging.discuss; + this.discuss.update({ initActiveId }); + }, + /** + * @override {web.AbstractAction} + */ + destroy() { + if (this.component) { + this.component.destroy(); + this.component = undefined; + } + if (this.$buttons) { + this.$buttons.off().remove(); + } + this._super(...arguments); + }, + /** + * @override {web.AbstractAction} + */ + on_attach_callback() { + this._super(...arguments); + if (this.component) { + // prevent twice call to on_attach_callback (FIXME) + return; + } + const DiscussComponent = components.Discuss; + this.component = new DiscussComponent(); + this._pushStateActionManagerEventListener = ev => { + ev.stopPropagation(); + if (this._lastPushStateActiveThread === this.discuss.thread) { + return; + } + this._pushStateActionManager(); + this._lastPushStateActiveThread = this.discuss.thread; + }; + this._showRainbowManEventListener = ev => { + ev.stopPropagation(); + this._showRainbowMan(); + }; + this._updateControlPanelEventListener = ev => { + ev.stopPropagation(); + this._updateControlPanel(); + }; + + this.el.addEventListener( + 'o-push-state-action-manager', + this._pushStateActionManagerEventListener + ); + this.el.addEventListener( + 'o-show-rainbow-man', + this._showRainbowManEventListener + ); + this.el.addEventListener( + 'o-update-control-panel', + this._updateControlPanelEventListener + ); + return this.component.mount(this.el); + }, + /** + * @override {web.AbstractAction} + */ + on_detach_callback() { + this._super(...arguments); + if (this.component) { + this.component.destroy(); + } + this.component = undefined; + this.el.removeEventListener( + 'o-push-state-action-manager', + this._pushStateActionManagerEventListener + ); + this.el.removeEventListener( + 'o-show-rainbow-man', + this._showRainbowManEventListener + ); + this.el.removeEventListener( + 'o-update-control-panel', + this._updateControlPanelEventListener + ); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _pushStateActionManager() { + this.actionManager.do_push_state({ + action: this.action.id, + active_id: this.discuss.activeId, + }); + }, + /** + * @private + * @returns {boolean} + */ + _shouldHaveInviteButton() { + return ( + this.discuss.thread && + this.discuss.thread.channel_type === 'channel' + ); + }, + /** + * @private + */ + _showRainbowMan() { + this.trigger_up('show_effect', { + message: this.env._t("Congratulations, your inbox is empty!"), + type: 'rainbow_man', + }); + }, + /** + * @private + */ + _updateControlPanel() { + // Invite + if (this._shouldHaveInviteButton()) { + this.$buttons.find('.o_invite').removeClass('o_hidden'); + } else { + this.$buttons.find('.o_invite').addClass('o_hidden'); + } + // Mark All Read + if ( + this.discuss.threadView && + this.discuss.thread && + this.discuss.thread === this.env.messaging.inbox + ) { + this.$buttons + .find('.o_widget_Discuss_controlPanelButtonMarkAllRead') + .removeClass('o_hidden') + .prop('disabled', this.discuss.threadView.messages.length === 0); + } else { + this.$buttons + .find('.o_widget_Discuss_controlPanelButtonMarkAllRead') + .addClass('o_hidden'); + } + // Unstar All + if ( + this.discuss.threadView && + this.discuss.thread && + this.discuss.thread === this.env.messaging.starred + ) { + this.$buttons + .find('.o_unstar_all') + .removeClass('o_hidden') + .prop('disabled', this.discuss.threadView.messages.length === 0); + } else { + this.$buttons + .find('.o_unstar_all') + .addClass('o_hidden'); + } + // Mobile: Add channel + if ( + this.env.messaging.device.isMobile && + this.discuss.activeMobileNavbarTabId === 'channel' + ) { + this.$buttons + .find('.o_mobile_new_channel') + .removeClass('o_hidden'); + } else { + this.$buttons + .find('.o_mobile_new_channel') + .addClass('o_hidden'); + } + // Mobile: Add message + if ( + this.env.messaging.device.isMobile && + this.discuss.activeMobileNavbarTabId === 'chat' + ) { + this.$buttons + .find('.o_mobile_new_message') + .removeClass('o_hidden'); + } else { + this.$buttons + .find('.o_mobile_new_message') + .addClass('o_hidden'); + } + // Select All & Unselect All + const $selectAll = this.$buttons.find('.o_widget_Discuss_controlPanelButtonSelectAll'); + const $unselectAll = this.$buttons.find('.o_widget_Discuss_controlPanelButtonUnselectAll'); + + if ( + this.discuss.threadView && + ( + this.discuss.threadView.checkedMessages.length > 0 || + this.discuss.threadView.uncheckedMessages.length > 0 + ) + ) { + $selectAll.removeClass('o_hidden'); + $selectAll.toggleClass('disabled', this.discuss.threadView.uncheckedMessages.length === 0); + $unselectAll.removeClass('o_hidden'); + $unselectAll.toggleClass('disabled', this.discuss.threadView.checkedMessages.length === 0); + } else { + $selectAll.addClass('o_hidden'); + $selectAll.addClass('disabled'); + $unselectAll.addClass('o_hidden'); + $unselectAll.addClass('disabled'); + } + + // Moderation Actions + const $moderationButtons = this.$buttons.find('.o_widget_Discuss_controlPanelButtonModeration'); + if ( + this.discuss.threadView && + this.discuss.threadView.checkedMessages.length > 0 && + this.discuss.threadView.checkedMessages.filter( + message => !message.isModeratedByCurrentPartner + ).length === 0 + ) { + $moderationButtons.removeClass('o_hidden'); + } else { + $moderationButtons.addClass('o_hidden'); + } + + let title; + if (this.env.messaging.device.isMobile || !this.discuss.thread) { + title = this.env._t("Discuss"); + } else { + const prefix = + this.discuss.thread.channel_type === 'channel' && + this.discuss.thread.public !== 'private' + ? '#' + : ''; + title = `${prefix}${this.discuss.thread.displayName}`; + } + + this.updateControlPanel({ + cp_content: { + $buttons: this.$buttons, + }, + title, + }); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + */ + _onClickInvite() { + new InvitePartnerDialog(this, { + activeThreadLocalId: this.discuss.thread.localId, + messagingEnv: this.env, + }).open(); + }, + /** + * @private + */ + _onClickMarkAllAsRead() { + this.env.models['mail.message'].markAllAsRead(this.domain); + }, + /** + * @private + */ + _onClickMobileNewChannel() { + this.discuss.update({ isAddingChannel: true }); + }, + /** + * @private + */ + _onClickMobileNewMessage() { + this.discuss.update({ isAddingChat: true }); + }, + /** + * @private + */ + _onClickModerationAccept() { + this.env.models['mail.message'].moderate( + this.discuss.threadView.checkedMessages, + 'accept' + ); + }, + /** + * @private + */ + _onClickModerationDiscard() { + this.discuss.update({ hasModerationDiscardDialog: true }); + }, + /** + * @private + */ + _onClickModerationReject() { + this.discuss.update({ hasModerationRejectDialog: true }); + }, + /** + * @private + */ + _onClickSelectAll() { + this.env.models['mail.message'].checkAll( + this.discuss.thread, + this.discuss.stringifiedDomain + ); + }, + /** + * @private + */ + _onClickUnselectAll() { + this.env.models['mail.message'].uncheckAll( + this.discuss.thread, + this.discuss.stringifiedDomain + ); + }, + /** + * @private + */ + _onClickUnstarAll() { + this.env.models['mail.message'].unstarAll(); + }, + /** + * @private + * @param {Object} searchQuery + */ + _onSearch: function (searchQuery) { + this.discuss.update({ + stringifiedDomain: JSON.stringify(searchQuery.domain), + }); + }, +}); + +action_registry.add('mail.widgets.discuss', DiscussWidget); + +return DiscussWidget; + +}); diff --git a/addons/mail/static/src/widgets/discuss/discuss.scss b/addons/mail/static/src/widgets/discuss/discuss.scss new file mode 100644 index 00000000..2bed9b7c --- /dev/null +++ b/addons/mail/static/src/widgets/discuss/discuss.scss @@ -0,0 +1,36 @@ +// ------------------------------------------------------------------ +// Layout +// ------------------------------------------------------------------ + +.o_widget_Discuss { + display: flex; + flex: 0 0 100%; + flex-flow: column; + height: 100%; +} + +// ------------------------------------------------------------------ +// Style +// ------------------------------------------------------------------ + +.o_widget_Discuss { + + .o_control_panel { + border-bottom: 0; // cancel default border, so that we only apply it on top of discuss content + } + + .o_Discuss_content { + border-top: 1px solid darken($o-control-panel-background-color, 20%); + } + + .o_Discuss.o-mobile { + + &:not(.o-adding-item) { + border-top: 1px solid darken($o-control-panel-background-color, 20%); + } + + &.o-adding-item .o_Discuss_mobileAddItemHeader { + border-bottom: 1px solid darken($o-control-panel-background-color, 20%); + } + } +} diff --git a/addons/mail/static/src/widgets/discuss/discuss.xml b/addons/mail/static/src/widgets/discuss/discuss.xml new file mode 100644 index 00000000..f8e6de37 --- /dev/null +++ b/addons/mail/static/src/widgets/discuss/discuss.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates xml:space="preserve"> + + <!-- + @param {mail/static/src/widgets/discuss/discuss.js} widget + --> + <t t-name="mail.widgets.Discuss"> + <div class="o_widget_Discuss"/> + </t> + + <!-- @param {boolean} isMobile --> + <t t-name="mail.widgets.Discuss.DiscussControlButtons"> + <div> + <button class="o_widget_Discuss_controlPanelButtonInvite o_invite o_hidden btn btn-primary" type="button" title="Invite people">Invite</button> + <button class="o_widget_Discuss_controlPanelButtonMarkAllRead o_hidden btn btn-secondary" type="button" title="Mark all as read">Mark all read</button> + <button class="o_widget_Discuss_controlPanelButtonUnstarAll o_unstar_all o_hidden btn btn-secondary" type="button" title="Unstar all messages">Unstar all</button> + <button class="o_widget_Discuss_controlPanelButtonMobileNewMessage o_mobile_new_message o_hidden btn btn-secondary" type="button" title="New Message">New Message</button> + <button class="o_widget_Discuss_controlPanelButtonMobileNewChannel o_mobile_new_channel o_hidden btn btn-secondary" title="New Channel" type="button">New Channel</button> + <button class="o_widget_Discuss_controlPanelButtonSelectAll btn btn-secondary o_hidden" title="Select all messages">Select All</button> + <button class="o_widget_Discuss_controlPanelButtonUnselectAll btn btn-secondary o_hidden" title="Unselect all messages">Unselect All</button> + <button class="o_widget_Discuss_controlPanelButtonModeration btn btn-secondary o_hidden o-accept" title="Accept selected messages">Accept</button> + <button class="o_widget_Discuss_controlPanelButtonModeration btn btn-secondary o_hidden o-reject" title="Reject selected messages">Reject</button> + <button class="o_widget_Discuss_controlPanelButtonModeration btn btn-secondary o_hidden o-discard" title="Discard selected messages">Discard</button> + </div> + </t> + +</templates> |
