[IMP] mail: improve attachment box model

Before this PR, attachment box event handlers where stored inside the attachment box component.
This PR move the handlers inside a dedicated model.

part of task-2579306

closes odoo/odoo#79464

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Didier (did)
2021-11-15 15:54:39 +00:00
committed by Sébastien Theys
parent fe22d14821
commit 20758a8d16
6 changed files with 95 additions and 54 deletions
@@ -1,7 +1,9 @@
/** @odoo-module **/
import { useDragVisibleDropZone } from '@mail/component_hooks/use_drag_visible_dropzone/use_drag_visible_dropzone';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model/use_component_to_model';
import { useDragVisibleDropZone } from '@mail/component_hooks/use_drag_visible_dropzone/use_drag_visible_dropzone';
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model/use_ref_to_model';
const { Component } = owl;
const { useRef } = owl.hooks;
@@ -11,14 +13,16 @@ export class AttachmentBox extends Component {
/**
* @override
*/
constructor(...args) {
super(...args);
setup() {
super.setup();
this.isDropZoneVisible = useDragVisibleDropZone();
/**
* Reference of the file uploader.
* Useful to programmatically prompts the browser file uploader.
*/
this._fileUploaderRef = useRef('fileUploader');
useComponentToModel({ fieldName: 'component', modelName: 'mail.attachment_box_view', propNameAsRecordLocalId: 'attachmentBoxViewLocalId' });
useRefToModel({ fieldName: 'fileUploaderRef', modelName: 'mail.attachment_box_view', propNameAsRecordLocalId: 'attachmentBoxViewLocalId', refName: 'fileUploader' });
}
//--------------------------------------------------------------------------
@@ -26,44 +30,16 @@ export class AttachmentBox extends Component {
//--------------------------------------------------------------------------
/**
* @returns {mail.chatter|undefined}
* @returns {mail.attachement_box_view|undefined}
*/
get chatter() {
return this.messaging && this.messaging.models['mail.chatter'].get(this.props.chatterLocalId);
get attachmentBoxView() {
return this.messaging && this.messaging.models['mail.attachment_box_view'].get(this.props.attachmentBoxViewLocalId);
}
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {Event} ev
*/
_onAttachmentCreated(ev) {
// FIXME Could be changed by spying attachments count (task-2252858)
this.trigger('o-attachments-changed');
}
/**
* @private
* @param {Event} ev
*/
_onAttachmentRemoved(ev) {
// FIXME Could be changed by spying attachments count (task-2252858)
this.trigger('o-attachments-changed');
}
/**
* @private
* @param {Event} ev
*/
_onClickAdd(ev) {
ev.preventDefault();
ev.stopPropagation();
this._fileUploaderRef.comp.openBrowserFileUploader();
}
/**
* @private
* @param {CustomEvent} ev
@@ -80,7 +56,7 @@ export class AttachmentBox extends Component {
Object.assign(AttachmentBox, {
props: {
chatterLocalId: String,
attachmentBoxViewLocalId: String,
},
template: 'mail.AttachmentBox',
});
@@ -3,7 +3,7 @@
<t t-name="mail.AttachmentBox" owl="1">
<div class="o_AttachmentBox">
<t t-if="chatter">
<t t-if="attachmentBoxView">
<div class="o_AttachmentBox_title">
<hr class="o_AttachmentBox_dashedLine"/>
<span class="o_AttachmentBox_titleText">
@@ -19,21 +19,21 @@
t-ref="dropzone"
/>
</t>
<t t-if="chatter.attachmentList">
<t t-if="attachmentBoxView.chatter.attachmentList">
<AttachmentList
class="o_attachmentBox_attachmentList"
attachmentListLocalId="chatter.attachmentList.localId"
t-on-o-attachment-removed="_onAttachmentRemoved"
attachmentListLocalId="attachmentBoxView.chatter.attachmentList.localId"
t-on-o-attachment-removed="attachmentBoxView.onAttachmentRemoved"
/>
</t>
<button class="o_AttachmentBox_buttonAdd btn btn-link" type="button" t-on-click="_onClickAdd">
<button class="o_AttachmentBox_buttonAdd btn btn-link" type="button" t-on-click="attachmentBoxView.onClickAddAttachment">
<i class="fa fa-plus-square"/>
Add attachments
</button>
</div>
<FileUploader
threadLocalId="chatter.thread.localId"
t-on-o-attachment-created="_onAttachmentCreated"
threadLocalId="attachmentBoxView.chatter.thread.localId"
t-on-o-attachment-created="attachmentBoxView.onAttachmentCreated"
t-ref="fileUploader"
/>
</t>
@@ -25,11 +25,12 @@ QUnit.module('attachment_box_tests.js', {
this.createAttachmentBoxComponent = async (thread, otherProps) => {
const chatter = this.messaging.models['mail.chatter'].insert({
id: 1,
isAttachmentBoxVisibleInitially: true,
threadId: thread.id,
threadModel: thread.model,
});
const props = {
chatterLocalId: chatter.localId,
attachmentBoxViewLocalId: chatter.attachmentBoxView.localId,
...otherProps,
};
await createRootMessagingComponent(this, "AttachmentBox", {
@@ -23,10 +23,10 @@
</t>
</div>
<div class="o_Chatter_scrollPanel" t-on-scroll="chatter.onScrollScrollPanel" t-ref="scrollPanel">
<t t-if="chatter.isAttachmentBoxVisible">
<t t-if="chatter.attachmentBoxView">
<AttachmentBox
class="o_Chatter_attachmentBox"
chatterLocalId="chatter.localId"
attachmentBoxViewLocalId="chatter.attachmentBoxView.localId"
/>
</t>
<t t-if="chatter.thread and chatter.hasActivities and chatter.thread.activities.length > 0">
@@ -0,0 +1,66 @@
/** @odoo-module **/
import { registerNewModel } from '@mail/model/model_core';
import { attr, one2one } from '@mail/model/model_field';
function factory(dependencies) {
class AttachmentBoxView extends dependencies['mail.model'] {
_created() {
this.onAttachmentCreated = this.onAttachmentCreated.bind(this);
this.onAttachmentRemoved = this.onAttachmentRemoved.bind(this);
this.onClickAddAttachment = this.onClickAddAttachment.bind(this);
}
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
/**
* Handles attachment created event.
*/
onAttachmentCreated() {
// FIXME Could be changed by spying attachments count (task-2252858)
this.component.trigger('o-attachments-changed');
}
/**
* Handles attachment removed event.
*/
onAttachmentRemoved() {
// FIXME Could be changed by spying attachments count (task-2252858)
this.component.trigger('o-attachments-changed');
}
/**
* Handles click on the "add attachment" button.
*/
onClickAddAttachment() {
this.fileUploaderRef.comp.openBrowserFileUploader();
}
}
AttachmentBoxView.fields = {
chatter: one2one('mail.chatter', {
inverse: 'attachmentBoxView',
readonly: true,
required: true,
}),
/**
* States the OWL component displaying this attachment box.
*/
component: attr(),
/**
* States the OWL ref of the "fileUploader" of this attachment box.
*/
fileUploaderRef: attr(),
};
AttachmentBoxView.identifyingFields = ['chatter'];
AttachmentBoxView.modelName = 'mail.attachment_box_view';
return AttachmentBoxView;
}
registerNewModel('mail.attachment_box_view', factory);
@@ -74,7 +74,7 @@ function factory(dependencies) {
* @param {MouseEvent} ev
*/
onClickButtonAttachments(ev) {
this.update({ isAttachmentBoxVisible: !this.isAttachmentBoxVisible });
this.update({ attachmentBoxView: this.attachmentBoxView ? clear() : insertAndReplace() });
}
/**
@@ -232,7 +232,7 @@ function factory(dependencies) {
this.thread.delete();
}
this.update({
isAttachmentBoxVisible: this.isAttachmentBoxVisibleInitially,
attachmentBoxView: this.isAttachmentBoxVisibleInitially ? insertAndReplace() : clear(),
thread: insert({
// If the thread was considered to have the activity
// mixin once, it will have it forever.
@@ -261,7 +261,7 @@ function factory(dependencies) {
});
const nextId = getThreadNextTemporaryId();
this.update({
isAttachmentBoxVisible: false,
attachmentBoxView: clear(),
thread: insert({
areAttachmentsLoaded: true,
id: nextId,
@@ -311,6 +311,10 @@ function factory(dependencies) {
}
Chatter.fields = {
attachmentBoxView: one2one('mail.attachment_box_view', {
inverse: 'chatter',
isCausal: true,
}),
/**
* Determines the attachment list that will be used to display the attachments.
*/
@@ -386,12 +390,6 @@ function factory(dependencies) {
isActivityBoxVisible: attr({
default: true,
}),
/**
* Determiners whether the attachment box is currently visible.
*/
isAttachmentBoxVisible: attr({
default: false,
}),
/**
* Determiners whether the attachment box is visible initially.
*/