[IMP] im_livechat,mail: remove MobileMessagingNavbar/tabs deep props
In preparation for using OWL v2 in discuss code. (shouldUpdateBasedOnProps will be removed) Solution consists of introducing MobileMessagingNavbarView model. Task-2695743 closes odoo/odoo#80617 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Discuss } from '@mail/components/discuss/discuss';
|
||||
|
||||
import { patch } from 'web.utils';
|
||||
|
||||
const components = { Discuss };
|
||||
|
||||
patch(components.Discuss.prototype, 'im_livechat/static/src/components/discuss/discuss.js', {
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
mobileNavbarTabs(...args) {
|
||||
return [...this._super(...args), {
|
||||
icon: 'fa fa-comments',
|
||||
id: 'livechat',
|
||||
label: this.env._t("Livechat"),
|
||||
}];
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addFields } from '@mail/model/model_core';
|
||||
import { one2many } from '@mail/model/model_field';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/messaging/messaging';
|
||||
|
||||
addFields('Messaging', {
|
||||
/**
|
||||
* All pinned livechats that are known.
|
||||
*/
|
||||
pinnedLivechats: one2many('Thread', {
|
||||
inverse: 'messagingAsPinnedLivechat',
|
||||
readonly: true,
|
||||
}),
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { patchRecordMethods } from '@mail/model/model_core';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view';
|
||||
|
||||
patchRecordMethods('MobileMessagingNavbarView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeTabs() {
|
||||
const res = this._super();
|
||||
if (this.messaging.pinnedLivechats.length > 0) {
|
||||
return [...res, {
|
||||
icon: 'fa fa-comments',
|
||||
id: 'livechat',
|
||||
label: this.env._t("Livechat"),
|
||||
}];
|
||||
}
|
||||
return res;
|
||||
},
|
||||
});
|
||||
@@ -1,10 +1,34 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { patchModelMethods, patchRecordMethods } from '@mail/model/model_core';
|
||||
import { insert, link, unlink } from '@mail/model/model_field_command';
|
||||
import { addFields, addRecordMethods, patchModelMethods, patchRecordMethods } from '@mail/model/model_core';
|
||||
import { many2one } from '@mail/model/model_field';
|
||||
import { clear, insert, link, replace, unlink } from '@mail/model/model_field_command';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/thread/thread';
|
||||
|
||||
addFields('Thread', {
|
||||
/**
|
||||
* If set, current thread is a livechat.
|
||||
*/
|
||||
messagingAsPinnedLivechat: many2one('Messaging', {
|
||||
compute: '_computeMessagingAsPinnedLivechat',
|
||||
inverse: 'pinnedLivechats',
|
||||
}),
|
||||
});
|
||||
|
||||
addRecordMethods('Thread', {
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeMessagingAsPinnedLivechat() {
|
||||
if (!this.messaging || this.channel_type !== 'livechat' || !this.isPinned) {
|
||||
return clear();
|
||||
}
|
||||
return replace(this.messaging);
|
||||
},
|
||||
});
|
||||
|
||||
patchModelMethods('Thread', {
|
||||
/**
|
||||
* @override
|
||||
|
||||
@@ -21,7 +21,6 @@ export class Discuss extends Component {
|
||||
useUpdate({ func: () => this._update() });
|
||||
onWillUnmount(() => this._willUnmount());
|
||||
this._onHideMobileAddItemHeader = this._onHideMobileAddItemHeader.bind(this);
|
||||
this._onSelectMobileNavbarTab = this._onSelectMobileNavbarTab.bind(this);
|
||||
}
|
||||
|
||||
_update() {
|
||||
@@ -78,25 +77,6 @@ export class Discuss extends Component {
|
||||
return this.messaging && this.messaging.discuss;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
mobileNavbarTabs() {
|
||||
return [{
|
||||
icon: 'fa fa-inbox',
|
||||
id: 'mailbox',
|
||||
label: this.env._t("Mailboxes"),
|
||||
}, {
|
||||
icon: 'fa fa-user',
|
||||
id: 'chat',
|
||||
label: this.env._t("Chat"),
|
||||
}, {
|
||||
icon: 'fa fa-users',
|
||||
id: 'channel',
|
||||
label: this.env._t("Channel"),
|
||||
}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -169,33 +149,6 @@ export class Discuss extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} detail
|
||||
* @param {string} detail.tabId
|
||||
*/
|
||||
_onSelectMobileNavbarTab(detail) {
|
||||
if (this.discuss.activeMobileNavbarTabId === detail.tabId) {
|
||||
return;
|
||||
}
|
||||
this.discuss.update({ activeMobileNavbarTabId: detail.tabId });
|
||||
if (
|
||||
this.discuss.activeMobileNavbarTabId === 'mailbox' &&
|
||||
(!this.discuss.thread || this.discuss.thread.model !== 'mailbox')
|
||||
) {
|
||||
this.discuss.update({ thread: link(this.messaging.inbox) });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'mailbox') {
|
||||
this.discuss.update({ thread: unlink() });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'chat') {
|
||||
this.discuss.update({ isAddingChat: false });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'channel') {
|
||||
this.discuss.update({ isAddingChannel: false });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign(Discuss, {
|
||||
|
||||
@@ -76,12 +76,10 @@
|
||||
filter="discuss.activeMobileNavbarTabId"
|
||||
/>
|
||||
</t>
|
||||
<t t-if="messaging.device.isMobile and !(discuss.threadView and discuss.threadView.replyingToMessageView)">
|
||||
<t t-if="discuss.mobileMessagingNavbarView">
|
||||
<MobileMessagingNavbar
|
||||
className="'o_Discuss_mobileNavbar'"
|
||||
activeTabId="discuss.activeMobileNavbarTabId"
|
||||
tabs="mobileNavbarTabs()"
|
||||
onSelectMobileMessagingNavbarTab="_onSelectMobileNavbarTab"
|
||||
mobileMessagingNavbarViewLocalId="discuss.mobileMessagingNavbarView.localId"
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
@@ -23,7 +23,6 @@ export class MessagingMenu extends Component {
|
||||
this._onMobileNewMessageInputSource = this._onMobileNewMessageInputSource.bind(this);
|
||||
this._onClickCaptureGlobal = this._onClickCaptureGlobal.bind(this);
|
||||
this._onHideMobileNewMessage = this._onHideMobileNewMessage.bind(this);
|
||||
this._onSelectMobileNavbarTab = this._onSelectMobileNavbarTab.bind(this);
|
||||
onMounted(() => this._mounted());
|
||||
onWillUnmount(() => this._willUnmount());
|
||||
}
|
||||
@@ -54,25 +53,6 @@ export class MessagingMenu extends Component {
|
||||
return this.env._t("Search user...");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
get tabs() {
|
||||
return [{
|
||||
icon: 'fa fa-envelope',
|
||||
id: 'all',
|
||||
label: this.env._t("All"),
|
||||
}, {
|
||||
icon: 'fa fa-user',
|
||||
id: 'chat',
|
||||
label: this.env._t("Chat"),
|
||||
}, {
|
||||
icon: 'fa fa-users',
|
||||
id: 'channel',
|
||||
label: this.env._t("Channel"),
|
||||
}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -171,15 +151,6 @@ export class MessagingMenu extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} detail
|
||||
* @param {string} detail.tabId
|
||||
*/
|
||||
_onSelectMobileNavbarTab(detail) {
|
||||
this.messagingMenu.update({ activeTabId: detail.tabId });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign(MessagingMenu, {
|
||||
|
||||
@@ -54,12 +54,10 @@
|
||||
classNameObj="{ 'o-mobile': messaging.device.isMobile }"
|
||||
filter="messagingMenu.activeTabId"
|
||||
/>
|
||||
<t t-if="messaging.device.isMobile">
|
||||
<t t-if="messagingMenu.mobileMessagingNavbarView">
|
||||
<MobileMessagingNavbar
|
||||
className="'o_MessagingMenu_mobileNavbar'"
|
||||
activeTabId="messagingMenu.activeTabId"
|
||||
tabs="tabs"
|
||||
onSelectMobileMessagingNavbarTab="_onSelectMobileNavbarTab"
|
||||
mobileMessagingNavbarViewLocalId="messagingMenu.mobileMessagingNavbarView.localId"
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
+5
-35
@@ -6,50 +6,20 @@ const { Component } = owl;
|
||||
|
||||
export class MobileMessagingNavbar extends Component {
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
* @returns {MobileMessagingNavbarView}
|
||||
*/
|
||||
_onClick(ev) {
|
||||
if (this.props.onSelectMobileMessagingNavbarTab) {
|
||||
this.props.onSelectMobileMessagingNavbarTab({
|
||||
tabId: ev.currentTarget.dataset.tabId,
|
||||
});
|
||||
}
|
||||
get mobileMessagingNavbarView() {
|
||||
return this.messaging && this.messaging.models['MobileMessagingNavbarView'].get(this.props.mobileMessagingNavbarViewLocalId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign(MobileMessagingNavbar, {
|
||||
defaultProps: {
|
||||
tabs: [],
|
||||
},
|
||||
props: {
|
||||
activeTabId: String,
|
||||
onSelectMobileMessagingNavbarTab: {
|
||||
type: Function,
|
||||
optional: true,
|
||||
},
|
||||
tabs: {
|
||||
type: Array,
|
||||
element: {
|
||||
type: Object,
|
||||
shape: {
|
||||
icon: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
id: String,
|
||||
label: String,
|
||||
},
|
||||
},
|
||||
},
|
||||
mobileMessagingNavbarViewLocalId: String,
|
||||
},
|
||||
template: 'mail.MobileMessagingNavbar',
|
||||
});
|
||||
|
||||
registerMessagingComponent(MobileMessagingNavbar, { propsCompareDepth: { tabs: 2 } });
|
||||
registerMessagingComponent(MobileMessagingNavbar);
|
||||
|
||||
+9
-7
@@ -3,13 +3,15 @@
|
||||
|
||||
<t t-name="mail.MobileMessagingNavbar" owl="1">
|
||||
<div class="o_MobileMessagingNavbar" t-attf-class="{{ className }}" t-ref="root">
|
||||
<t t-foreach="props.tabs" t-as="tab" t-key="tab.id">
|
||||
<div class="o_MobileMessagingNavbar_tab" t-att-class="{ 'o-active': props.activeTabId === tab.id }" t-on-click="_onClick" t-att-data-tab-id="tab.id">
|
||||
<t t-if="tab.icon">
|
||||
<span class="o_MobileMessagingNavbar_tabIcon" t-att-class="tab.icon"/>
|
||||
</t>
|
||||
<span class="o_MobileMessagingNavbar_tabLabel"><t t-esc="tab.label"/></span>
|
||||
</div>
|
||||
<t t-if="mobileMessagingNavbarView">
|
||||
<t t-foreach="mobileMessagingNavbarView.tabs" t-as="tab" t-key="tab.id">
|
||||
<div class="o_MobileMessagingNavbar_tab" t-att-class="{ 'o-active': mobileMessagingNavbarView.activeTabId === tab.id }" t-on-click="mobileMessagingNavbarView.onClick.bind(mobileMessagingNavbarView, tab.id)" t-att-data-tab-id="tab.id">
|
||||
<t t-if="tab.icon">
|
||||
<span class="o_MobileMessagingNavbar_tabIcon" t-att-class="tab.icon"/>
|
||||
</t>
|
||||
<span class="o_MobileMessagingNavbar_tabLabel"><t t-esc="tab.label"/></span>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -285,6 +285,20 @@ registerModel({
|
||||
}
|
||||
return this.isAddingChat;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeMobileMessagingNavbarView() {
|
||||
if (
|
||||
this.messaging.device &&
|
||||
this.messaging.device.isMobile &&
|
||||
!(this.threadView && this.threadView.replyingToMessageView)
|
||||
) {
|
||||
return insertAndReplace();
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
/**
|
||||
* Only pinned threads are allowed in discuss.
|
||||
*
|
||||
@@ -387,6 +401,15 @@ registerModel({
|
||||
menu_id: attr({
|
||||
default: null,
|
||||
}),
|
||||
/**
|
||||
* The navbar view on the discuss app when in mobile and when not
|
||||
* replying to a message from inbox.
|
||||
*/
|
||||
mobileMessagingNavbarView: one2one('MobileMessagingNavbarView', {
|
||||
compute: '_computeMobileMessagingNavbarView',
|
||||
inverse: 'discuss',
|
||||
isCausal: true,
|
||||
}),
|
||||
/**
|
||||
* Quick search input value in the discuss sidebar (desktop). Useful
|
||||
* to filter channels and chats based on this input content.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr, one2many } from '@mail/model/model_field';
|
||||
import { attr, one2many, one2one } from '@mail/model/model_field';
|
||||
import { clear, insertAndReplace } from '@mail/model/model_field_command';
|
||||
|
||||
registerModel({
|
||||
name: 'MessagingMenu',
|
||||
@@ -48,6 +49,16 @@ registerModel({
|
||||
const notificationPemissionCounter = this.messaging.isNotificationPermissionDefault ? 1 : 0;
|
||||
return inboxCounter + unreadChannelsCounter + notificationGroupsCounter + notificationPemissionCounter;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {MobileMessagingNavbarView|FieldCommand}
|
||||
*/
|
||||
_computeMobileMessagingNavbarView() {
|
||||
if (this.messaging.device && this.messaging.device.isMobile) {
|
||||
return insertAndReplace();
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
/**
|
||||
@@ -77,10 +88,18 @@ registerModel({
|
||||
isOpen: attr({
|
||||
default: false,
|
||||
}),
|
||||
/**
|
||||
* The navbar view on the messaging menu when in mobile.
|
||||
*/
|
||||
mobileMessagingNavbarView: one2one('MobileMessagingNavbarView', {
|
||||
compute: '_computeMobileMessagingNavbarView',
|
||||
inverse: 'messagingMenu',
|
||||
isCausal: true,
|
||||
}),
|
||||
/**
|
||||
* States all the pinned channels that have unread messages.
|
||||
*/
|
||||
pinnedAndUnreadChannels: one2many('Thread', {
|
||||
pinnedAndUnreadChannels: one2many('Thread', {
|
||||
inverse: 'messagingMenuAsPinnedAndUnreadChannel',
|
||||
readonly: true,
|
||||
}),
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr, one2one } from '@mail/model/model_field';
|
||||
import { clear, replace } from '@mail/model/model_field_command';
|
||||
|
||||
registerModel({
|
||||
name: 'MobileMessagingNavbarView',
|
||||
identifyingFields: [['discuss', 'messagingMenu']],
|
||||
recordMethods: {
|
||||
/**
|
||||
* @param {string} tabId
|
||||
*/
|
||||
onClick(tabId) {
|
||||
if (this.discuss) {
|
||||
if (this.discuss.activeMobileNavbarTabId === tabId) {
|
||||
return;
|
||||
}
|
||||
this.discuss.update({ activeMobileNavbarTabId: tabId });
|
||||
if (
|
||||
this.discuss.activeMobileNavbarTabId === 'mailbox' &&
|
||||
(!this.discuss.thread || this.discuss.thread.model !== 'mailbox')
|
||||
) {
|
||||
this.discuss.update({ thread: replace(this.messaging.inbox) });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'mailbox') {
|
||||
this.discuss.update({ thread: clear() });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'chat') {
|
||||
this.discuss.update({ isAddingChat: false });
|
||||
}
|
||||
if (this.discuss.activeMobileNavbarTabId !== 'channel') {
|
||||
this.discuss.update({ isAddingChannel: false });
|
||||
}
|
||||
}
|
||||
if (this.messagingMenu) {
|
||||
this.messagingMenu.update({ activeTabId: tabId });
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeActiveTabId() {
|
||||
if (this.discuss) {
|
||||
return this.discuss.activeMobileNavbarTabId;
|
||||
}
|
||||
if (this.messagingMenu) {
|
||||
return this.messagingMenu.activeTabId;
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
_computeTabs() {
|
||||
if (this.discuss) {
|
||||
return [{
|
||||
icon: 'fa fa-inbox',
|
||||
id: 'mailbox',
|
||||
label: this.env._t("Mailboxes"),
|
||||
}, {
|
||||
icon: 'fa fa-user',
|
||||
id: 'chat',
|
||||
label: this.env._t("Chat"),
|
||||
}, {
|
||||
icon: 'fa fa-users',
|
||||
id: 'channel',
|
||||
label: this.env._t("Channel"),
|
||||
}];
|
||||
}
|
||||
if (this.messagingMenu) {
|
||||
return [{
|
||||
icon: 'fa fa-envelope',
|
||||
id: 'all',
|
||||
label: this.env._t("All"),
|
||||
}, {
|
||||
icon: 'fa fa-user',
|
||||
id: 'chat',
|
||||
label: this.env._t("Chat"),
|
||||
}, {
|
||||
icon: 'fa fa-users',
|
||||
id: 'channel',
|
||||
label: this.env._t("Channel"),
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
/**
|
||||
* Tab selected in this navbar.
|
||||
* Either 'all', 'mailbox', 'chat' or 'channel'.
|
||||
*/
|
||||
activeTabId: attr({
|
||||
compute: '_computeActiveTabId',
|
||||
}),
|
||||
discuss: one2one('Discuss', {
|
||||
inverse: 'mobileMessagingNavbarView',
|
||||
readonly: true,
|
||||
}),
|
||||
messagingMenu: one2one('MessagingMenu', {
|
||||
inverse: 'mobileMessagingNavbarView',
|
||||
readonly: true,
|
||||
}),
|
||||
/**
|
||||
* Ordered list of tabs that this navbar has.
|
||||
* Format of tab:
|
||||
* {
|
||||
* icon: <the classname for this tab>
|
||||
* id: <the id for this tab>
|
||||
* label: <the label/name of this tab>
|
||||
* }
|
||||
*/
|
||||
tabs: attr({
|
||||
compute: '_computeTabs',
|
||||
}),
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user