[IMP] mail: introduce useMessagingContainer

This commit introduces component hook useMessagingContainer,
which allow to lazily use messaging component in template.

This allow simplifing some code in container, and more notably
in child messaging components, as they can now define their
template in models.

Task-3055886

Part-of: odoo/odoo#105099
This commit is contained in:
Alexandre Kühn
2022-11-06 00:28:16 +01:00
parent d87308626c
commit 30087290e9
71 changed files with 210 additions and 529 deletions
@@ -1,25 +0,0 @@
/** @odoo-module **/
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class ActivityCellView extends Component {
setup() {
useRefToModel({ fieldName: 'contentRef', refName: 'content' });
}
get activityCellView() {
return this.props.record;
}
}
Object.assign(ActivityCellView, {
props: { record: Object },
template: 'mail.ActivityCellView',
});
registerMessagingComponent(ActivityCellView);
@@ -2,10 +2,10 @@
<templates xml:space="preserve">
<t t-name="mail.ActivityCellView" owl="1">
<div class="o_ActivityCellView h-100 cursor-pointer p-3" t-on-click="activityCellView.onClick" t-ref="root">
<div class="o_ActivityCellView h-100 cursor-pointer p-3" t-on-click="onClick" t-ref="root">
<div class="o_ActivityCellView_content h-100 d-flex align-items-center justify-content-center position-relative" t-ref="content">
<div class="o_ActivityCellView_closestDeadline text-white" t-out="activityCellView.closestDeadlineFormatted"/>
<span t-if="activityCellView.filteredActivities.length > 1" class="o_ActivityCellView_activityCount badge bg-light rounded-pill border-0" t-out="activityCellView.filteredActivities.length"/>
<div class="o_ActivityCellView_closestDeadline text-white" t-out="closestDeadlineFormatted"/>
<span t-if="filteredActivities.length > 1" class="o_ActivityCellView_activityCount badge bg-light rounded-pill border-0" t-out="filteredActivities.length"/>
</div>
</div>
</t>
@@ -1,9 +1,7 @@
/** @odoo-module **/
// ensure components are registered beforehand.
import '@mail/backend_components/activity_cell_view/activity_cell_view';
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { insert } from '@mail/model/model_field_command';
import { getMessagingComponent } from '@mail/utils/messaging_component';
import { Component, onWillDestroy, onWillUpdateProps } from '@odoo/owl';
@@ -25,6 +23,7 @@ export class ActivityCellViewContainer extends Component {
* @override
*/
setup() {
useMessagingContainer();
super.setup();
this.activityCellView = undefined;
this.activityCellViewId = getNextId();
@@ -85,7 +84,6 @@ export class ActivityCellViewContainer extends Component {
}
Object.assign(ActivityCellViewContainer, {
components: { ActivityCellView: getMessagingComponent('ActivityCellView') },
props: {
activityIds: {
type: Array,
@@ -2,7 +2,9 @@
<templates xml:space="preserve">
<t t-name="mail.ActivityCellViewContainer" owl="1">
<ActivityCellView t-if="activityCellView" record="activityCellView"/>
<t t-if="isLoaded">
<ActivityCellView t-if="activityCellView" record="activityCellView"/>
</t>
</t>
</templates>
@@ -1,20 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class KanbanFieldActivityView extends Component {
get kanbanFieldActivityView() {
return this.props.record;
}
}
Object.assign(KanbanFieldActivityView, {
props: { record: Object },
template: 'mail.KanbanFieldActivityView',
});
registerMessagingComponent(KanbanFieldActivityView);
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="mail.KanbanFieldActivityView" owl="1">
<ActivityButtonView record="kanbanFieldActivityView.activityButtonView"/>
<ActivityButtonView record="activityButtonView"/>
</t>
</templates>
@@ -1,8 +1,7 @@
/** @odoo-module **/
// ensure components are registered beforehand.
import '@mail/backend_components/kanban_field_activity_view/kanban_field_activity_view';
import { getMessagingComponent } from '@mail/utils/messaging_component';
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
@@ -28,6 +27,7 @@ export class KanbanFieldActivityViewContainer extends Component {
*/
setup() {
super.setup();
useMessagingContainer();
this.kanbanFieldActivityView = undefined;
this.kanbanFieldActivityViewId = getNextId();
this._insertFromProps(this.props);
@@ -80,7 +80,6 @@ export class KanbanFieldActivityViewContainer extends Component {
}
Object.assign(KanbanFieldActivityViewContainer, {
components: { KanbanFieldActivityView: getMessagingComponent('KanbanFieldActivityView') },
fieldDependencies: {
activity_exception_decoration: { type: 'selection' },
activity_exception_icon: { type: 'char' },
@@ -2,7 +2,9 @@
<templates xml:space="preserve">
<t t-name="mail.KanbanFieldActivityViewContainer" owl="1">
<KanbanFieldActivityView t-if="kanbanFieldActivityView" record="kanbanFieldActivityView"/>
<t t-if="isLoaded">
<KanbanFieldActivityView t-if="kanbanFieldActivityView" record="kanbanFieldActivityView"/>
</t>
</t>
</templates>
@@ -1,20 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class ListFieldActivityView extends Component {
get listFieldActivityView() {
return this.props.record;
}
}
Object.assign(ListFieldActivityView, {
props: { record: Object },
template: 'mail.ListFieldActivityView',
});
registerMessagingComponent(ListFieldActivityView);
@@ -2,8 +2,8 @@
<templates xml:space="preserve">
<t t-name="mail.ListFieldActivityView" owl="1">
<ActivityButtonView record="listFieldActivityView.activityButtonView"/>
<span class="o_ListFieldActivityView_summary" t-out="listFieldActivityView.summaryText"/>
<ActivityButtonView record="activityButtonView"/>
<span class="o_ListFieldActivityView_summary" t-out="summaryText"/>
</t>
</templates>
@@ -1,8 +1,7 @@
/** @odoo-module **/
// ensure components are registered beforehand.
import '@mail/backend_components/list_field_activity_view/list_field_activity_view';
import { getMessagingComponent } from '@mail/utils/messaging_component';
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
@@ -28,6 +27,7 @@ export class ListFieldActivityViewContainer extends Component {
*/
setup() {
super.setup();
useMessagingContainer();
this.listFieldActivityView = undefined;
this.listFieldActivityViewId = getNextId();
this._insertFromProps(this.props);
@@ -80,7 +80,6 @@ export class ListFieldActivityViewContainer extends Component {
}
Object.assign(ListFieldActivityViewContainer, {
components: { ListFieldActivityView: getMessagingComponent('ListFieldActivityView') },
fieldDependencies: {
activity_exception_decoration: { type: 'selection' },
activity_exception_icon: { type: 'char' },
@@ -2,7 +2,9 @@
<templates xml:space="preserve">
<t t-name="mail.ListFieldActivityViewContainer" owl="1">
<ListFieldActivityView t-if="listFieldActivityView" record="listFieldActivityView"/>
<t t-if="isLoaded">
<ListFieldActivityView t-if="listFieldActivityView" record="listFieldActivityView"/>
</t>
</t>
</templates>
@@ -0,0 +1,21 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
import { componentRegistry, getMessagingComponent } from "@mail/utils/messaging_component";
import { useComponent } from '@odoo/owl';
export function useMessagingContainer() {
const component = useComponent();
component.isLoaded = false;
useModels();
component.env.services.messaging.modelManager.messagingCreatedPromise.then(() => {
let components = { ...component.constructor.components };
for (const name in componentRegistry) {
Object.assign(components, { [name]: getMessagingComponent(name) });
}
component.constructor.components = components;
component.isLoaded = true;
component.render();
});
}
@@ -1,23 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class CallSystrayMenu extends Component {
/**
* @returns {CallSystrayMenu}
*/
get callSystrayMenu() {
return this.props.record;
}
}
Object.assign(CallSystrayMenu, {
props: { record: Object },
template: 'mail.CallSystrayMenu',
});
registerMessagingComponent(CallSystrayMenu);
@@ -5,7 +5,7 @@
<div class="o_CallSystrayMenu dropdown" t-attf-class="{{ className }}" t-ref="root">
<t t-if="messaging">
<CallInviteRequestPopupList/>
<button t-if="messaging.rtc.channel" class="o_CallSystrayMenu_button px-3 user-select-none dropdown-toggle o-no-caret o-dropdown--narrow" t-att-title="callSystrayMenu.buttonTitle" role="button" t-on-click="messaging.rtc.onClickActivityNoticeButton">
<button t-if="messaging.rtc.channel" class="o_CallSystrayMenu_button px-3 user-select-none dropdown-toggle o-no-caret o-dropdown--narrow" t-att-title="buttonTitle" role="button" t-on-click="messaging.rtc.onClickActivityNoticeButton">
<div class="o_CallSystrayMenu_buttonContent d-flex align-items-center">
<span class="position-relative me-2">
<i class="o_CallSystrayMenu_outputIndicator fa me-2" t-att-class="{
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/call_systray_menu/call_systray_menu';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -13,8 +10,7 @@ export class CallSystrayMenuContainer extends Component {
* @override
*/
setup() {
useModels();
super.setup();
useMessagingContainer();
}
get messaging() {
@@ -25,6 +21,5 @@ export class CallSystrayMenuContainer extends Component {
CallSystrayMenuContainer.props = {};
Object.assign(CallSystrayMenuContainer, {
components: { CallSystrayMenu: getMessagingComponent('CallSystrayMenu') },
template: 'mail.CallSystrayMenuContainer',
});
@@ -3,7 +3,9 @@
<t t-name="mail.CallSystrayMenuContainer" owl="1">
<div class="CallSystrayMenuContainer">
<CallSystrayMenu t-if="messaging" record="messaging.rtc.callSystrayMenu"/>
<t t-if="isLoaded">
<CallSystrayMenu t-if="messaging" record="messaging.rtc.callSystrayMenu"/>
</t>
</div>
</t>
</templates>
@@ -1,32 +0,0 @@
/** @odoo-module **/
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class ChatWindow extends Component {
/**
* @override
*/
setup() {
super.setup();
useUpdateToModel({ methodName: 'onComponentUpdate' });
}
/**
* @returns {ChatWindow}
*/
get chatWindow() {
return this.props.record;
}
}
Object.assign(ChatWindow, {
props: { record: Object },
template: 'mail.ChatWindow',
});
registerMessagingComponent(ChatWindow);
@@ -2,35 +2,35 @@
<templates xml:space="preserve">
<t t-name="mail.ChatWindow" owl="1">
<div class="o_ChatWindow position-absolute bottom-0 d-flex flex-column rounded-top-3 bg-view" t-attf-class="{{ className }}" tabindex="0" t-att-data-visible-index="chatWindow.visibleIndex"
<div class="o_ChatWindow position-absolute bottom-0 d-flex flex-column rounded-top-3 bg-view" t-attf-class="{{ className }}" tabindex="0" t-att-data-visible-index="visibleIndex"
t-att-class="{
'o-focused': chatWindow.isFocused,
'o-folded': chatWindow.isFolded,
'o-fullscreen w-100 h-100': chatWindow.isFullscreen,
'o-focused': isFocused,
'o-folded': isFolded,
'o-fullscreen w-100 h-100': isFullscreen,
'o-isDeviceSmall position-fixed': messaging.device.isSmall,
'mw-100 mh-100': !messaging.device.isSmall,
'o-new-message': !chatWindow.thread,
}" t-att-style="chatWindow.componentStyle" t-on-keydown="chatWindow.onKeydown" t-on-focusout="chatWindow.onFocusout" t-att-data-chat-window-local-id="chatWindow.localId" t-att-data-thread-id="chatWindow.thread ? chatWindow.thread.id : ''" t-ref="root"
t-att-data-thread-model="chatWindow.thread ? chatWindow.thread.model : ''"
'o-new-message': !thread,
}" t-att-style="componentStyle" t-on-keydown="onKeydown" t-on-focusout="onFocusout" t-att-data-chat-window-local-id="localId" t-att-data-thread-id="thread ? thread.id : ''" t-ref="root"
t-att-data-thread-model="thread ? thread.model : ''"
>
<ChatWindowHeaderView
className="'o_ChatWindow_header flex-grow-0 flex-shrink-0'"
record="chatWindow.chatWindowHeaderView"
record="chatWindowHeaderView"
/>
<ChannelMemberListView t-if="chatWindow.channelMemberListView" record="chatWindow.channelMemberListView" className="'bg-view'"/>
<CallSettingsMenu t-if="chatWindow.callSettingsMenu" record="chatWindow.callSettingsMenu" className="'bg-view'"/>
<ChannelInvitationForm t-if="chatWindow.channelInvitationForm" className="'o_ChatWindow_channelInvitationForm'" record="chatWindow.channelInvitationForm"/>
<ThreadView t-if="chatWindow.threadView"
<ChannelMemberListView t-if="channelMemberListView" record="channelMemberListView" className="'bg-view'"/>
<CallSettingsMenu t-if="callSettingsMenu" record="callSettingsMenu" className="'bg-view'"/>
<ChannelInvitationForm t-if="channelInvitationForm" className="'o_ChatWindow_channelInvitationForm'" record="channelInvitationForm"/>
<ThreadView t-if="threadView"
className="'o_ChatWindow_thread flex-grow-1 flex-shrink-1'"
record="chatWindow.threadView"
record="threadView"
/>
<div t-if="chatWindow.newMessageAutocompleteInputView" class="o_ChatWindow_newMessageForm d-flex align-items-center m-3">
<div t-if="newMessageAutocompleteInputView" class="o_ChatWindow_newMessageForm d-flex align-items-center m-3">
<span class="o_ChatWindow_newMessageFormLabel flex-grow-0 flex-shrink-0 me-2">
To:
</span>
<AutocompleteInputView
className="'o_ChatWindow_newMessageFormInput flex-grow-1 flex-shrink-1 border'"
record="chatWindow.newMessageAutocompleteInputView"
record="newMessageAutocompleteInputView"
/>
</div>
</div>
@@ -1,14 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class ChatWindowManager extends Component {}
Object.assign(ChatWindowManager, {
props: { record: Object },
template: 'mail.ChatWindowManager',
});
registerMessagingComponent(ChatWindowManager);
@@ -4,8 +4,8 @@
<t t-name="mail.ChatWindowManager" owl="1">
<div class="o_ChatWindowManager flex-row-reverse d-flex" t-attf-class="{{ className }}" t-ref="root">
<!-- Note: DOM elements are ordered from left to right -->
<ChatWindowHiddenMenuView t-if="messaging.chatWindowManager.hiddenMenuView" className="'o_ChatWindowManager_hiddenMenu'" record="messaging.chatWindowManager.hiddenMenuView"/>
<ChatWindow t-foreach="messaging.chatWindowManager.allOrderedVisible" t-as="chatWindow" t-key="chatWindow.localId" record="chatWindow"/>
<ChatWindowHiddenMenuView t-if="hiddenMenuView" className="'o_ChatWindowManager_hiddenMenu'" record="hiddenMenuView"/>
<ChatWindow t-foreach="allOrderedVisible" t-as="chatWindow" t-key="chatWindow.localId" record="chatWindow"/>
</div>
</t>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/chat_window_manager/chat_window_manager';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -13,8 +10,7 @@ export class ChatWindowManagerContainer extends Component {
* @override
*/
setup() {
useModels();
super.setup();
useMessagingContainer();
}
get messaging() {
@@ -24,6 +20,5 @@ export class ChatWindowManagerContainer extends Component {
ChatWindowManagerContainer.props = {};
Object.assign(ChatWindowManagerContainer, {
components: { ChatWindowManager: getMessagingComponent('ChatWindowManager') },
template: 'mail.ChatWindowManagerContainer',
});
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="mail.ChatWindowManagerContainer" owl="1">
<ChatWindowManager t-if="messaging and messaging.chatWindowManager" record="messaging.chatWindowManager"/>
<t t-if="isLoaded">
<ChatWindowManager t-if="messaging and messaging.chatWindowManager" record="messaging.chatWindowManager"/>
</t>
</t>
</templates>
@@ -1,33 +0,0 @@
/** @odoo-module **/
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model';
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { LegacyComponent } from '@web/legacy/legacy_component';
export class Chatter extends LegacyComponent {
/**
* @override
*/
setup() {
super.setup();
useComponentToModel({ fieldName: 'component' });
useRefToModel({ fieldName: 'scrollPanelRef', refName: 'scrollPanel' });
}
/**
* @returns {Chatter}
*/
get chatter() {
return this.props.record;
}
}
Object.assign(Chatter, {
props: { record: Object },
template: 'mail.Chatter',
});
registerMessagingComponent(Chatter);
@@ -3,34 +3,34 @@
<t t-name="mail.Chatter" owl="1">
<div class="o_Chatter position-relative flex-grow-1 flex-column d-flex w-100 bg-view" t-attf-class="{{ className }}" t-ref="root">
<DropZoneView t-if="chatter.dropZoneView"
<DropZoneView t-if="dropZoneView"
className="'o_Chatter_dropZone'"
record="chatter.dropZoneView"
record="dropZoneView"
/>
<div class="o_Chatter_fixedPanel">
<ChatterTopbar
t-if="chatter.topbar"
t-if="topbar"
className="'o_Chatter_topbar'"
record="chatter.topbar"
record="topbar"
/>
<ComposerView t-if="chatter.composerView"
<ComposerView t-if="composerView"
className="'o_Chatter_composer border-bottom'"
classNameObj="{ 'o-bordered': chatter.hasExternalBorder }"
record="chatter.composerView"
classNameObj="{ 'o-bordered': hasExternalBorder }"
record="composerView"
/>
</div>
<div class="o_Chatter_scrollPanel overflow-auto" t-on-scroll="chatter.onScrollScrollPanel" t-ref="scrollPanel">
<AttachmentBoxView t-if="chatter.attachmentBoxView"
<div class="o_Chatter_scrollPanel overflow-auto" t-on-scroll="onScrollScrollPanel" t-ref="scrollPanel">
<AttachmentBoxView t-if="attachmentBoxView"
className="'o_Chatter_attachmentBox'"
record="chatter.attachmentBoxView"
record="attachmentBoxView"
/>
<ActivityBoxView t-if="chatter.activityBoxView"
<ActivityBoxView t-if="activityBoxView"
className="'o_Chatter_activityBox'"
record="chatter.activityBoxView"
record="activityBoxView"
/>
<ThreadView t-if="chatter.threadView"
<ThreadView t-if="threadView"
className="'o_Chatter_thread'"
record="chatter.threadView"
record="threadView"
/>
</div>
</div>
@@ -1,10 +1,7 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/chatter/chatter';
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { clear } from '@mail/model/model_field_command';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { Component, onWillDestroy, onWillUpdateProps } from '@odoo/owl';
@@ -30,7 +27,7 @@ export class ChatterContainer extends Component {
* @override
*/
setup() {
useModels();
useMessagingContainer();
super.setup();
this.localChatter = undefined;
this._insertFromProps(this.props);
@@ -105,7 +102,6 @@ export class ChatterContainer extends Component {
}
Object.assign(ChatterContainer, {
components: { Chatter: getMessagingComponent('Chatter') },
props: {
chatter: {
type: Object,
@@ -3,7 +3,9 @@
<t t-name="mail.ChatterContainer" owl="1">
<div class="o_ChatterContainer flex-grow-1 d-flex" t-att-class="{ 'o-isInFormSheetBg mx-auto': props.isInFormSheetBg }" t-attf-class="{{ props.className }}" data-command-category="mail" t-ref="root">
<Chatter t-if="chatter and chatter.thread" record="chatter"/>
<t t-if="isLoaded and chatter and chatter.thread">
<Chatter record="chatter"/>
</t>
<div t-else="" class="o_ChatterContainer_noChatter flex-grow-1 align-items-center justify-content-center d-flex"><i class="o_ChatterContainer_noChatterIcon fa fa-circle-o-notch fa-spin me-2"/>Please wait...</div>
</div>
</t>
@@ -1,27 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class Dialog extends Component {
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @returns {Dialog}
*/
get dialog() {
return this.props.record;
}
}
Object.assign(Dialog, {
props: { record: Object },
template: 'mail.Dialog',
});
registerMessagingComponent(Dialog);
@@ -2,12 +2,12 @@
<templates xml:space="preserve">
<t t-name="mail.Dialog" owl="1">
<div class="o_Dialog modal fixed-top bottom-0 d-flex justify-content-center" t-attf-class="{{ className }}" t-att-style="dialog.style" t-ref="root">
<div class="o_Dialog modal fixed-top bottom-0 d-flex justify-content-center" t-attf-class="{{ className }}" t-att-style="style" t-ref="root">
<t
t-component="constructor.components[dialog.componentName]"
t-component="constructor.components[componentName]"
t-props="{
className: `o_Dialog_component ${dialog.componentClassName}`,
record: dialog.record,
className: `o_Dialog_component ${componentClassName}`,
record: record,
}"
/>
</div>
@@ -1,28 +0,0 @@
/** @odoo-module **/
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class DialogManager extends Component {
/**
* @override
*/
setup() {
super.setup();
useUpdateToModel({ methodName: 'onComponentUpdate' });
}
get dialogManager() {
return this.props.record;
}
}
Object.assign(DialogManager, {
props: { record: Object },
template: 'mail.DialogManager',
});
registerMessagingComponent(DialogManager);
@@ -3,7 +3,7 @@
<t t-name="mail.DialogManager" owl="1">
<div class="o_DialogManager" t-attf-class="{{ className }}" t-ref="root">
<Dialog t-foreach="dialogManager.dialogs" t-as="dialog" t-key="dialog.localId"
<Dialog t-foreach="dialogs" t-as="dialog" t-key="dialog.localId"
className="'o_DialogManager_dialog'"
record="dialog"
/>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/dialog_manager/dialog_manager';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -12,9 +9,8 @@ export class DialogManagerContainer extends Component {
/**
* @override
*/
setup() {
useModels();
super.setup();
setup() {
useMessagingContainer();
}
get messaging() {
@@ -24,6 +20,5 @@ export class DialogManagerContainer extends Component {
DialogManagerContainer.props = {};
Object.assign(DialogManagerContainer, {
components: { DialogManager: getMessagingComponent('DialogManager') },
template: 'mail.DialogManagerContainer',
});
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="mail.DialogManagerContainer" owl="1">
<DialogManager t-if="messaging and messaging.dialogManager" record="messaging.dialogManager"/>
<t t-if="isLoaded">
<DialogManager t-if="messaging and messaging.dialogManager" record="messaging.dialogManager"/>
</t>
</t>
</templates>
@@ -1,26 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class DiscussView extends Component {
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @returns {DiscussView}
*/
get discussView() {
return this.props.record;
}
}
Object.assign(DiscussView, {
props: { record: Object },
template: 'mail.DiscussView',
});
registerMessagingComponent(DiscussView);
@@ -6,7 +6,7 @@
t-att-class="{ 'o-isDeviceSmall flex-column align-items-center bg-view': messaging.device.isSmall }"
t-ref="root"
>
<DiscussSidebarView t-if="discussView.sidebar" className="'o_DiscussView_sidebar flex-shrink-0 h-100 pt-3 border-end bg-light'" record="discussView.sidebar"/>
<DiscussSidebarView t-if="sidebar" className="'o_DiscussView_sidebar flex-shrink-0 h-100 pt-3 border-end bg-light'" record="sidebar"/>
<t t-if="messaging.device.isSmall" t-call="mail.DiscussView.content"/>
<div t-else="" class="o_DiscussView_content d-flex flex-column flex-grow-1 h-100 overflow-auto">
<t t-call="mail.DiscussView.content"/>
@@ -15,36 +15,36 @@
</t>
<t t-name="mail.DiscussView.content" owl="1">
<DiscussMobileMailboxSelectionView t-if="discussView.mobileMailboxSelectionView" className="'o_DiscussView_mobileMailboxSelection w-100 border-bottom'" record="discussView.mobileMailboxSelectionView"/>
<div t-if="discussView.mobileAddItemHeaderAutocompleteInputView" class="o_DiscussView_mobileAddItemHeader d-flex justify-content-center w-100 p-3 border-bottom bg-light">
<DiscussMobileMailboxSelectionView t-if="mobileMailboxSelectionView" className="'o_DiscussView_mobileMailboxSelection w-100 border-bottom'" record="mobileMailboxSelectionView"/>
<div t-if="mobileAddItemHeaderAutocompleteInputView" class="o_DiscussView_mobileAddItemHeader d-flex justify-content-center w-100 p-3 border-bottom bg-light">
<AutocompleteInputView
className="'o_DiscussView_mobileAddItemHeaderInput flex-grow-1 mb-3 p-2 rounded border'"
record="discussView.mobileAddItemHeaderAutocompleteInputView"
record="mobileAddItemHeaderAutocompleteInputView"
/>
</div>
<t t-if="discussView.discuss.threadView">
<t t-if="discuss.threadView">
<t name="beforeThread"/>
<ThreadView
className="'o_DiscussView_thread'"
classNameObj="{ 'o-isDeviceSmall w-100': messaging.device.isSmall }"
record="discussView.discuss.threadView"
record="discuss.threadView"
/>
</t>
<div t-if="!discussView.discuss.activeThread and (!messaging.device.isSmall or discussView.discuss.activeMobileNavbarTabId === 'mailbox')" class="o_DiscussView_noThread d-flex flex-grow-1 align-items-center justify-content-center w-100 bg-view">
<div t-if="!discuss.activeThread and (!messaging.device.isSmall or discuss.activeMobileNavbarTabId === 'mailbox')" class="o_DiscussView_noThread d-flex flex-grow-1 align-items-center justify-content-center w-100 bg-view">
<h4 class="text-muted"><b><i>No conversation selected.</i></b></h4>
</div>
<t t-if="messaging.device.isSmall and discussView.discuss.activeMobileNavbarTabId !== 'mailbox'">
<button t-if="discussView.discuss.activeMobileNavbarTabId === 'chat'" class="o_DiscussView_mobileNewChatButton w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click="discussView.onClickMobileNewChatButton">
<t t-if="messaging.device.isSmall and discuss.activeMobileNavbarTabId !== 'mailbox'">
<button t-if="discuss.activeMobileNavbarTabId === 'chat'" class="o_DiscussView_mobileNewChatButton w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click="onClickMobileNewChatButton">
Start a conversation
</button>
<button t-if="discussView.discuss.activeMobileNavbarTabId === 'channel'" class="o_DiscussView_mobileNewChannelButton w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click="discussView.onClickMobileNewChannelButton">
<button t-if="discuss.activeMobileNavbarTabId === 'channel'" class="o_DiscussView_mobileNewChannelButton w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click="onClickMobileNewChannelButton">
New Channel
</button>
</t>
<NotificationListView t-if="discussView.discuss.notificationListView" className="'o_DiscussView_notificationList flex-grow-1 w-100'" record="discussView.discuss.notificationListView"/>
<MobileMessagingNavbarView t-if="discussView.discuss.mobileMessagingNavbarView"
<NotificationListView t-if="discuss.notificationListView" className="'o_DiscussView_notificationList flex-grow-1 w-100'" record="discuss.notificationListView"/>
<MobileMessagingNavbarView t-if="discuss.mobileMessagingNavbarView"
className="'o_DiscussView_mobileNavbar w-100'"
record="discussView.discuss.mobileMessagingNavbarView"
record="discuss.mobileMessagingNavbarView"
/>
</t>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure component is registered before-hand
import '@mail/components/discuss/discuss';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component, onWillDestroy } from '@odoo/owl';
@@ -13,7 +10,7 @@ export class DiscussContainer extends Component {
* @override
*/
setup() {
useModels();
useMessagingContainer();
super.setup();
onWillDestroy(() => this._willDestroy());
this.env.services.messaging.modelManager.messagingCreatedPromise.then(async () => {
@@ -71,6 +68,5 @@ Object.assign(DiscussContainer, {
className: String,
globalState: { type: Object, optional: 1 },
},
components: { DiscussView: getMessagingComponent('DiscussView') },
template: 'mail.DiscussContainer',
});
@@ -3,7 +3,9 @@
<t t-name="mail.DiscussContainer" owl="1">
<div class="o_DiscussContainer h-100 d-flex flex-column">
<DiscussView t-if="messaging and messaging.discuss and messaging.discuss.discussView and messaging.isInitialized" className="'flex-grow-1'" record="messaging.discuss.discussView"/>
<t t-if="isLoaded and messaging and messaging.discuss and messaging.discuss.discussView and messaging.isInitialized">
<DiscussView className="'flex-grow-1'" record="messaging.discuss.discussView"/>
</t>
<div t-else="" class="o_DiscussContainer_spinner d-flex flex-grow-1 align-items-center justify-content-center">
<i class="o_DiscussContainer_spinnerIcon fa fa-circle-o-notch fa-spin me-2"/>Please wait...
</div>
@@ -1,22 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
class DiscussPublicView extends Component {
/**
* @returns {DiscussPublicView}
*/
get discussPublicView() {
return this.props.record;
}
}
Object.assign(DiscussPublicView, {
props: { record: Object },
template: 'mail.DiscussPublicView',
});
registerMessagingComponent(DiscussPublicView);
@@ -2,11 +2,11 @@
<templates xml:space="preserve">
<t t-name="mail.DiscussPublicView" owl="1">
<div class="o_DiscussPublicView d-flex flex-column h-100 w-100 position-absolute" t-attf-class="{{ className }}" t-ref="root">
<ThreadView t-if="discussPublicView.threadView"
record="discussPublicView.threadView"
<ThreadView t-if="threadView"
record="threadView"
/>
<WelcomeView t-if="discussPublicView.welcomeView"
record="discussPublicView.welcomeView"
<WelcomeView t-if="welcomeView"
record="welcomeView"
/>
</div>
</t>
@@ -1,8 +1,6 @@
/** @odoo-module **/
// ensure components are registered beforehand.
import '@mail/components/discuss_public_view/discuss_public_view';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -13,6 +11,7 @@ export class DiscussPublicViewContainer extends Component {
*/
setup() {
super.setup();
useMessagingContainer();
this.env.services.messaging.get().then(messaging => {
messaging.models['Thread'].insert(messaging.models['Thread'].convertData(this.props.data.channelData));
this.discussPublicView = messaging.models['DiscussPublicView'].insert(this.props.data.discussPublicViewData);
@@ -28,7 +27,6 @@ export class DiscussPublicViewContainer extends Component {
}
Object.assign(DiscussPublicViewContainer, {
components: { DiscussPublicView: getMessagingComponent('DiscussPublicView') },
template: 'mail.DiscussPublicViewContainer',
props: {
data: Object,
@@ -2,7 +2,9 @@
<templates xml:space="preserve">
<t t-name="mail.DiscussPublicViewContainer" owl="1">
<div class="o_DiscussPublicViewContainer position-absolute h-100 w-100">
<DiscussPublicView t-if="discussPublicView" record="discussPublicView"/>
<t t-if="isLoaded and discussPublicView">
<DiscussPublicView record="discussPublicView"/>
</t>
<div t-else="" class="h-100 d-flex justify-content-center align-items-center">
<i class="o_DiscussPublicViewContainer_spinner fa fa-circle-o-notch fa-spin mx-2" title="Please wait..."/>
</div>
@@ -1,36 +0,0 @@
/** @odoo-module **/
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class MessagingMenu extends Component {
/**
* @override
*/
setup() {
super.setup();
useComponentToModel({ fieldName: 'component' });
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @returns {MessagingMenu}
*/
get messagingMenu() {
return this.props.record;
}
}
Object.assign(MessagingMenu, {
props: { record: Object },
template: 'mail.MessagingMenu',
});
registerMessagingComponent(MessagingMenu);
@@ -2,31 +2,31 @@
<templates xml:space="preserve">
<t t-name="mail.MessagingMenu" owl="1">
<div class="o_MessagingMenu dropdown" t-att-class="{ 'show bg-black-15': messagingMenu.isOpen, 'o-isDeviceSmall': messaging.device.isSmall }" t-attf-class="{{ className }}" t-ref="root">
<a class="o_MessagingMenu_toggler dropdown-toggle o-no-caret o-dropdown--narrow" t-att-class="{ 'o-no-notification': !messagingMenu.counter }" href="#" title="Conversations" role="button" t-att-aria-expanded="messagingMenu.isOpen ? 'true' : 'false'" aria-haspopup="true" t-on-click="messagingMenu.onClickToggler">
<div class="o_MessagingMenu dropdown" t-att-class="{ 'show bg-black-15': isOpen, 'o-isDeviceSmall': messaging.device.isSmall }" t-attf-class="{{ className }}" t-ref="root">
<a class="o_MessagingMenu_toggler dropdown-toggle o-no-caret o-dropdown--narrow" t-att-class="{ 'o-no-notification': !counter }" href="#" title="Conversations" role="button" t-att-aria-expanded="isOpen ? 'true' : 'false'" aria-haspopup="true" t-on-click="onClickToggler">
<i class="o_MessagingMenu_icon fa fa-lg fa-comments" role="img" aria-label="Messages"/>
<i t-if="!messaging.isInitialized" class="o_MessagingMenu_loading fa fa-circle-o-notch fa-spin position-absolute bottom-50 end-0 small"/>
<span t-elif="messagingMenu.counter > 0" class="o_MessagingMenu_counter badge" t-esc="messagingMenu.counter"/>
<span t-elif="counter > 0" class="o_MessagingMenu_counter badge" t-esc="counter"/>
</a>
<div t-if="messagingMenu.isOpen" class="o_MessagingMenu_dropdownMenu o-dropdown-menu dropdown-menu-end d-flex flex-column mt-0 py-0 bg-view overflow-auto" t-att-class="{ 'o-isDeviceSmall position-fixed bottom-0 start-0 end-0 flex-grow-1 w-100 m-0 border-0': messaging.device.isSmall, 'border': !messaging.device.isSmall, 'o-messaging-not-initialized align-items-center justify-content-center': !messaging.isInitialized }" role="menu">
<div t-if="isOpen" class="o_MessagingMenu_dropdownMenu o-dropdown-menu dropdown-menu-end d-flex flex-column mt-0 py-0 bg-view overflow-auto" t-att-class="{ 'o-isDeviceSmall position-fixed bottom-0 start-0 end-0 flex-grow-1 w-100 m-0 border-0': messaging.device.isSmall, 'border': !messaging.device.isSmall, 'o-messaging-not-initialized align-items-center justify-content-center': !messaging.isInitialized }" role="menu">
<span t-if="!messaging.isInitialized"><i class="o_MessagingMenu_dropdownLoadingIcon fa fa-circle-o-notch fa-spin me-1"/>Please wait...</span>
<t t-else="">
<div class="o_MessagingMenu_dropdownMenuHeader border-bottom" t-attf-class="{{ messaging.device.isSmall ? 'o-isDeviceSmall p-2' : 'd-flex flex-shrink-0' }}">
<MessagingMenuTabView t-if="messagingMenu.allTab" record="messagingMenu.allTab"/>
<MessagingMenuTabView t-if="messagingMenu.chatTab" record="messagingMenu.chatTab"/>
<MessagingMenuTabView t-if="messagingMenu.channelTab" record="messagingMenu.channelTab"/>
<MessagingMenuTabView t-if="allTab" record="allTab"/>
<MessagingMenuTabView t-if="chatTab" record="chatTab"/>
<MessagingMenuTabView t-if="channelTab" record="channelTab"/>
<t t-if="messaging.device.isSmall" t-call="mail.MessagingMenu.newMessageButton"/>
<div class="flex-grow-1"/>
<t t-if="!messaging.device.isSmall and !messaging.discuss.discussView" t-call="mail.MessagingMenu.newMessageButton"/>
<AutocompleteInputView t-if="messagingMenu.mobileNewMessageAutocompleteInputView"
<AutocompleteInputView t-if="mobileNewMessageAutocompleteInputView"
className="'o_MessagingMenu_mobileNewMessageInput mt-2 p-2 rounded-3'"
record="messagingMenu.mobileNewMessageAutocompleteInputView"
record="mobileNewMessageAutocompleteInputView"
/>
</div>
<NotificationListView t-if="messagingMenu.notificationListView" className="'o_MessagingMenu_notificationList'" classNameObj="{ 'o-isDeviceSmall flex-grow-1 overflow-auto': messaging.device.isSmall }" record="messagingMenu.notificationListView"/>
<MobileMessagingNavbarView t-if="messagingMenu.mobileMessagingNavbarView"
<NotificationListView t-if="notificationListView" className="'o_MessagingMenu_notificationList'" classNameObj="{ 'o-isDeviceSmall flex-grow-1 overflow-auto': messaging.device.isSmall }" record="notificationListView"/>
<MobileMessagingNavbarView t-if="mobileMessagingNavbarView"
className="'o_MessagingMenu_mobileNavbar'"
record="messagingMenu.mobileMessagingNavbarView"
record="mobileMessagingNavbarView"
/>
</t>
</div>
@@ -39,7 +39,7 @@
'btn-link': !messaging.device.isSmall,
'btn-secondary': messaging.device.isSmall,
'o-isDeviceSmall': messaging.device.isSmall,
}" t-on-click="messagingMenu.onClickNewMessage" type="button"
}" t-on-click="onClickNewMessage" type="button"
>
New message
</button>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/messaging_menu/messaging_menu';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -13,8 +10,7 @@ export class MessagingMenuContainer extends Component {
* @override
*/
setup() {
useModels();
super.setup();
useMessagingContainer();
}
get messaging() {
@@ -24,6 +20,5 @@ export class MessagingMenuContainer extends Component {
MessagingMenuContainer.props = {};
Object.assign(MessagingMenuContainer, {
components: { MessagingMenu: getMessagingComponent('MessagingMenu') },
template: 'mail.MessagingMenuContainer',
});
@@ -3,7 +3,9 @@
<t t-name="mail.MessagingMenuContainer" owl="1">
<div class="MessagingMenuContainer">
<MessagingMenu t-if="messaging and messaging.messagingMenu" record="messaging.messagingMenu"/>
<t t-if="isLoaded and messaging and messaging.messagingMenu">
<MessagingMenu record="messaging.messagingMenu"/>
</t>
<i t-else="" class="o_MessagingMenuContainer_spinner fa fa-circle-o-notch fa-spin mx-2" title="Please wait..."/>
</div>
</t>
@@ -1,19 +0,0 @@
/** @odoo-module **/
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class PopoverManager extends Component {
get popoverManager() {
return this.props.record;
}
}
Object.assign(PopoverManager, {
props: { record: Object },
template: 'mail.PopoverManager',
});
registerMessagingComponent(PopoverManager);
@@ -3,7 +3,7 @@
<t t-name="mail.PopoverManager" owl="1">
<div class="o_PopoverManager" t-attf-class="{{ className }}" t-ref="root">
<PopoverView t-foreach="popoverManager.popoverViews" t-as="popoverView" t-key="popoverView.localId"
<PopoverView t-foreach="popoverViews" t-as="popoverView" t-key="popoverView.localId"
className="'o_PopoverManager_popover'"
record="popoverView"
/>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/popover_manager/popover_manager';
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component } from '@odoo/owl';
@@ -13,8 +10,7 @@ export class PopoverManagerContainer extends Component {
* @override
*/
setup() {
useModels();
super.setup();
useMessagingContainer();
}
get messaging() {
@@ -24,6 +20,5 @@ export class PopoverManagerContainer extends Component {
PopoverManagerContainer.props = {};
Object.assign(PopoverManagerContainer, {
components: { PopoverManager: getMessagingComponent('PopoverManager') },
template: 'mail.PopoverManagerContainer',
});
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="mail.PopoverManagerContainer" owl="1">
<PopoverManager t-if="messaging and messaging.popoverManager" record="messaging.popoverManager"/>
<t t-if="isLoaded">
<PopoverManager t-if="messaging and messaging.popoverManager" record="messaging.popoverManager"/>
</t>
</t>
</templates>
@@ -1,30 +0,0 @@
/** @odoo-module **/
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { Component } from '@odoo/owl';
export class WebClientViewAttachmentView extends Component {
/**
* @override
*/
setup() {
useRefToModel({ fieldName: 'iframeViewerPdfRef', refName: 'iframeViewerPdf' });
useUpdateToModel({ methodName: 'onComponentUpdate' });
}
/**
* @returns {WebClientViewAttachmentView}
*/
get webClientViewAttachmentView() {
return this.props.record;
}
}
Object.assign(WebClientViewAttachmentView, {
props: { record: Object },
template: 'mail.WebClientViewAttachmentView',
});
registerMessagingComponent(WebClientViewAttachmentView);
@@ -2,17 +2,17 @@
<templates>
<t t-name="mail.WebClientViewAttachmentView" owl="1">
<t t-if="webClientViewAttachmentView.thread.mainAttachment">
<h3 t-if="!webClientViewAttachmentView.thread.mainAttachment.isPdf" class="mt0 mb8 ps-2 text-muted float-end"><t t-esc="webClientViewAttachmentView.thread.mainAttachment.filename"/></h3>
<div t-if="webClientViewAttachmentView.thread.mainAttachment.isImage" class="o_attachment_preview_img">
<img id="attachment_img" class="img img-fluid d-block" t-attf-src="/web/image/#{webClientViewAttachmentView.thread.mainAttachment.id}?unique=1"/>
<t t-if="thread.mainAttachment">
<h3 t-if="!thread.mainAttachment.isPdf" class="mt0 mb8 ps-2 text-muted float-end"><t t-esc="thread.mainAttachment.filename"/></h3>
<div t-if="thread.mainAttachment.isImage" class="o_attachment_preview_img">
<img id="attachment_img" class="img img-fluid d-block" t-attf-src="/web/image/#{thread.mainAttachment.id}?unique=1"/>
</div>
<iframe t-if="webClientViewAttachmentView.thread.mainAttachment.isPdf" class="mb48" t-attf-src="/web/static/lib/pdfjs/web/viewer.html?file=/web/content/#{webClientViewAttachmentView.thread.mainAttachment.id}?filename%3D#{window.encodeURIComponent(webClientViewAttachmentView.thread.mainAttachment.name)}" t-ref="iframeViewerPdf"/>
<t t-if="webClientViewAttachmentView.thread.attachmentsInWebClientView.length > 1">
<a class="arrow o_move_previous text-center" href="#" t-on-click="webClientViewAttachmentView.onClickPrevious">
<iframe t-if="thread.mainAttachment.isPdf" class="mb48" t-attf-src="/web/static/lib/pdfjs/web/viewer.html?file=/web/content/#{thread.mainAttachment.id}?filename%3D#{window.encodeURIComponent(thread.mainAttachment.name)}" t-ref="iframeViewerPdf"/>
<t t-if="thread.attachmentsInWebClientView.length > 1">
<a class="arrow o_move_previous text-center" href="#" t-on-click="onClickPrevious">
<span class="fa fa-chevron-left"/>
</a>
<a class="arrow o_move_next text-center" href="#" t-on-click="webClientViewAttachmentView.onClickNext">
<a class="arrow o_move_next text-center" href="#" t-on-click="onClickNext">
<span class="fa fa-chevron-right"/>
</a>
</t>
@@ -1,9 +1,6 @@
/** @odoo-module **/
import { useModels } from '@mail/component_hooks/use_models';
// ensure components are registered beforehand.
import '@mail/components/web_client_view_attachment_view/web_client_view_attachment_view';
import { getMessagingComponent } from '@mail/utils/messaging_component';
import { useMessagingContainer } from '@mail/component_hooks/use_messaging_container';
import { Component, onWillDestroy, onWillUpdateProps } from '@odoo/owl';
@@ -30,7 +27,7 @@ export class WebClientViewAttachmentViewContainer extends Component {
* @override
*/
setup() {
useModels();
useMessagingContainer();
super.setup();
this.webClientViewAttachmentView = undefined;
this.webClientViewAttachmentViewId = getNextId();
@@ -78,7 +75,6 @@ export class WebClientViewAttachmentViewContainer extends Component {
}
Object.assign(WebClientViewAttachmentViewContainer, {
components: { WebClientViewAttachmentView: getMessagingComponent('WebClientViewAttachmentView') },
props: {
threadId: {
type: Number,
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="mail.WebClientViewAttachmentViewContainer" owl="1">
<div t-if="webClientViewAttachmentView and webClientViewAttachmentView.thread.attachmentsInWebClientView.length > 0" class="o_attachment_preview_container">
<div t-if="isLoaded and webClientViewAttachmentView and webClientViewAttachmentView.thread.attachmentsInWebClientView.length > 0" class="o_attachment_preview_container">
<WebClientViewAttachmentView record="webClientViewAttachmentView"/>
</div>
</t>
+4 -2
View File
@@ -411,6 +411,7 @@ function patchRecordMethods(patch) {
* @param {function} [definition.componentSetup]
* @param {Object} [definition.fields]
* @param {string} [definition.identifyingMode='and']
* @param {string} [definition.isLegacyComponent=false]
* @param {Object} [definition.lifecycleHooks]
* @param {Object} [definition.modelGetters] Deprecated; use fields instead.
* @param {Object} [definition.modelMethods]
@@ -420,14 +421,14 @@ function patchRecordMethods(patch) {
* @param {Object} [definition.recordMethods]
* @param {string} [definition.template]
*/
export function registerModel({ componentSetup, fields, identifyingMode = 'and', lifecycleHooks, modelGetters, modelMethods, name, onChanges, recordGetters, recordMethods, template }) {
export function registerModel({ componentSetup, fields, identifyingMode = 'and', isLegacyComponent = false, lifecycleHooks, modelGetters, modelMethods, name, onChanges, recordGetters, recordMethods, template }) {
if (!name) {
throw new Error("Model is lacking a name.");
}
if (registry.has(name)) {
throw new Error(`Cannot register model "${name}": model has already been registered.`);
}
const sectionNames = ['name', 'template', 'componentSetup', 'identifyingMode', 'lifecycleHooks', 'modelMethods', 'modelGetters', 'recordMethods', 'recordGetters', 'fields', 'onChanges'];
const sectionNames = ['name', 'template', 'componentSetup', 'identifyingMode', 'isLegacyComponent', 'lifecycleHooks', 'modelMethods', 'modelGetters', 'recordMethods', 'recordGetters', 'fields', 'onChanges'];
const invalidSectionNames = Object.keys(arguments[0]).filter(x => !sectionNames.includes(x));
if (invalidSectionNames.length > 0) {
throw new Error(`Cannot register model "${name}": model definition contains unknown key(s): ${invalidSectionNames.join(", ")}`);
@@ -435,6 +436,7 @@ export function registerModel({ componentSetup, fields, identifyingMode = 'and',
registry.set(name, new Map([
['name', name],
['identifyingMode', identifyingMode],
['isLegacyComponent', isLegacyComponent],
['lifecycleHooks', new Map()],
['modelMethods', new Map()],
['modelGetters', new Map()],
@@ -12,6 +12,8 @@ import { followRelations } from '@mail/model/model_utils';
import { makeDeferred } from '@mail/utils/deferred';
import { registerMessagingComponent, unregisterMessagingComponent } from '@mail/utils/messaging_component';
import { LegacyComponent } from '@web/legacy/legacy_component';
import { Component } from '@odoo/owl';
/**
@@ -396,7 +398,8 @@ export class ModelManager {
_applyModelDefinition(model) {
const definition = registry.get(model.name);
if (definition.get('template')) {
const ModelComponent = { [model.name]: class extends Component {} }[model.name];
const ComponentClass = definition.get('isLegacyComponent') ? LegacyComponent : Component;
const ModelComponent = { [model.name]: class extends ComponentClass {} }[model.name];
Object.assign(ModelComponent, {
props: { record: Object },
template: definition.get('template'),
@@ -6,6 +6,7 @@ import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'ActivityCellView',
template: 'mail.ActivityCellView',
recordMethods: {
onClick() {
this.update({ activityListPopoverView: this.activityListPopoverView ? clear() : {} });
@@ -28,7 +29,7 @@ registerModel({
}
},
}),
contentRef: attr(),
contentRef: attr({ ref: 'content' }),
filteredActivities: many('Activity', {
compute() {
return this.thread.activities.filter(activity => activity.type === this.activityType);
@@ -1,6 +1,5 @@
/** @odoo-module **/
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
import { registerModel } from '@mail/model/model_core';
import { attr, many, one } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
@@ -11,9 +10,6 @@ import { sprintf } from '@web/core/utils/strings';
registerModel({
name: 'ActivityView',
template: 'mail.ActivityView',
componentSetup() {
useRefToModel({ fieldName: 'markDoneButtonRef', refName: 'markDoneButton', });
},
recordMethods: {
/**
* Handles the click on a link inside the activity.
@@ -155,7 +151,7 @@ registerModel({
return this.activity.mailTemplates.map(mailTemplate => ({ mailTemplate }));
},
}),
markDoneButtonRef: attr(),
markDoneButtonRef: attr({ ref: 'markDoneButton' }),
markDonePopoverView: one('PopoverView', { inverse: 'activityViewOwnerAsMarkDone', }),
/**
* Label for mark as done. This is just for translations purpose.
@@ -8,6 +8,7 @@ import { sprintf } from '@web/core/utils/strings';
registerModel({
name: 'CallSystrayMenu',
template: 'mail.CallSystrayMenu',
fields: {
buttonTitle: attr({ default: '',
compute() {
@@ -1,5 +1,6 @@
/** @odoo-module **/
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerModel } from '@mail/model/model_core';
import { attr, one } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
@@ -8,6 +9,10 @@ import { isEventHandled, markEventHandled } from '@mail/utils/utils';
registerModel({
name: 'ChatWindow',
identifyingMode: 'xor',
template: 'mail.ChatWindow',
componentSetup() {
useUpdateToModel({ methodName: 'onComponentUpdate' });
},
recordMethods: {
/**
* Close this chat window.
@@ -44,6 +44,7 @@ export const BASE_VISUAL = {
registerModel({
name: 'ChatWindowManager',
template: 'mail.ChatWindowManager',
recordMethods: {
/**
* Close all chat windows.
+7 -1
View File
@@ -1,5 +1,6 @@
/** @odoo-module **/
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model';
import { registerModel } from '@mail/model/model_core';
import { attr, one } from '@mail/model/model_field';
import { clear, insert, link } from '@mail/model/model_field_command';
@@ -22,6 +23,11 @@ const getMessageNextTemporaryId = (function () {
registerModel({
name: 'Chatter',
template: 'mail.Chatter',
isLegacyComponent: true,
componentSetup() {
useComponentToModel({ fieldName: 'component' });
},
recordMethods: {
focus() {
if (this.composerView) {
@@ -345,7 +351,7 @@ registerModel({
},
}),
isShowingAttachmentsLoading: attr({ default: false }),
scrollPanelRef: attr(),
scrollPanelRef: attr({ ref: 'scrollPanel' }),
/**
* Determines whether the view should reload after file changed in this chatter,
* such as from a file upload.
+1
View File
@@ -7,6 +7,7 @@ import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'Dialog',
identifyingMode: 'xor',
template: 'mail.Dialog',
lifecycleHooks: {
_created() {
document.addEventListener('click', this._onClickGlobal, true);
@@ -1,10 +1,15 @@
/** @odoo-module **/
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerModel } from '@mail/model/model_core';
import { many } from '@mail/model/model_field';
registerModel({
name: 'DialogManager',
template: 'mail.DialogManager',
componentSetup() {
useUpdateToModel({ methodName: 'onComponentUpdate' });
},
recordMethods: {
onComponentUpdate() {
if (this.dialogs.length > 0) {
@@ -6,6 +6,7 @@ import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'DiscussPublicView',
template: 'mail.DiscussPublicView',
recordMethods: {
/**
* Creates and displays the thread view and clears the welcome view.
@@ -6,6 +6,7 @@ import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'DiscussView',
template: 'mail.DiscussView',
recordMethods: {
clearIsAddingItem() {
this.update({
@@ -5,6 +5,7 @@ import { attr, one } from '@mail/model/model_field';
registerModel({
name: 'KanbanFieldActivityView',
template: 'mail.KanbanFieldActivityView',
fields: {
activityButtonView: one('ActivityButtonView', { default: {}, inverse: 'kanbanFieldActivityViewOwner', required: true }),
id: attr({ identifying: true }),
@@ -6,6 +6,7 @@ import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'ListFieldActivityView',
template: 'mail.ListFieldActivityView',
fields: {
activityButtonView: one('ActivityButtonView', { default: {}, inverse: 'listFieldActivityViewOwner', required: true }),
id: attr({ identifying: true }),
@@ -1,11 +1,16 @@
/** @odoo-module **/
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model';
import { registerModel } from '@mail/model/model_core';
import { attr, many, one } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
registerModel({
name: 'MessagingMenu',
template: 'mail.MessagingMenu',
componentSetup() {
useComponentToModel({ fieldName: 'component' });
},
lifecycleHooks: {
_created() {
document.addEventListener('click', this._onClickCaptureGlobal, true);
@@ -5,6 +5,7 @@ import { many } from '@mail/model/model_field';
registerModel({
name: 'PopoverManager',
template: 'mail.PopoverManager',
fields: {
// FIXME: dependent on implementation that uses insert order in relations!!
popoverViews: many('PopoverView', { inverse: 'manager', isCausal: true }),
@@ -1,5 +1,6 @@
/** @odoo-module **/
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import { registerModel } from '@mail/model/model_core';
import { attr, one } from '@mail/model/model_field';
@@ -7,6 +8,10 @@ import { hidePDFJSButtons } from '@web/legacy/js/libs/pdfjs';
registerModel({
name: 'WebClientViewAttachmentView',
template: 'mail.WebClientViewAttachmentView',
componentSetup() {
useUpdateToModel({ methodName: 'onComponentUpdate' });
},
recordMethods: {
/**
* @param {MouseEvent} ev
@@ -48,7 +53,7 @@ registerModel({
},
fields: {
id: attr({ identifying: true }),
iframeViewerPdfRef: attr(),
iframeViewerPdfRef: attr({ ref: 'iframeViewerPdf' }),
thread: one('Thread', { required: true }),
},
onChanges: [
@@ -4,7 +4,7 @@ import { useModels } from '@mail/component_hooks/use_models';
import { useRef } from '@odoo/owl';
const componentRegistry = {};
export const componentRegistry = {};
/**
* Allows a component to lean on the messaging features: the component is