[IMP] mail: new attachment button in the chatter
- Added a new button to the chatter that displays the amount of
attachments on the current record and when clicked, all the attachments
attached to the current record
- added mail.FormView (includes), used by the chatter attachment
button to fetch the field value of attachment_count.
- added a computed field "attachment_count" to mail.thread that
contains the amount of attachment attached to the record.
- changed the followers div, it is now sharing a "right side"
area with the attachment button.
task: 1860031
This commit is contained in:
@@ -110,6 +110,7 @@ class MailThread(models.AbstractModel):
|
|||||||
message_has_error_counter = fields.Integer(
|
message_has_error_counter = fields.Integer(
|
||||||
'Number of error', compute='_compute_message_has_error',
|
'Number of error', compute='_compute_message_has_error',
|
||||||
help="Number of messages with delivery error")
|
help="Number of messages with delivery error")
|
||||||
|
related_attachment_count = fields.Integer('Attachment Count', compute='_compute_related_attachment_count')
|
||||||
|
|
||||||
@api.one
|
@api.one
|
||||||
@api.depends('message_follower_ids')
|
@api.depends('message_follower_ids')
|
||||||
@@ -145,6 +146,12 @@ class MailThread(models.AbstractModel):
|
|||||||
# using read() below is much faster than followers.mapped('res_id')
|
# using read() below is much faster than followers.mapped('res_id')
|
||||||
return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
|
return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _compute_related_attachment_count(self):
|
||||||
|
for record in self:
|
||||||
|
domain = [('res_id', '=', record.id), ('res_model', '=', self._name)]
|
||||||
|
record.related_attachment_count = self.env['ir.attachment'].search_count(domain)
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.depends('message_follower_ids')
|
@api.depends('message_follower_ids')
|
||||||
def _compute_is_follower(self):
|
def _compute_is_follower(self):
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
odoo.define('mail.AttachmentBox', function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var core = require('web.core');
|
||||||
|
var Widget = require('web.Widget');
|
||||||
|
|
||||||
|
var DocumentViewer = require('mail.DocumentViewer');
|
||||||
|
|
||||||
|
var QWeb = core.qweb;
|
||||||
|
|
||||||
|
var AttachmentBox = Widget.extend({
|
||||||
|
template: 'mail.chatter.AttachmentBox',
|
||||||
|
events: {
|
||||||
|
"click .o_attachment_download": "_onAttachmentDownload",
|
||||||
|
"click .o_attachment_view": "_onAttachmentView",
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* @param {string} record.model
|
||||||
|
* @param {Number} record.res_id
|
||||||
|
*/
|
||||||
|
init: function (parent, record) {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.currentResID = record.res_id;
|
||||||
|
this.currentResModel = record.model;
|
||||||
|
this.attachmentIDs = {};
|
||||||
|
this.imageList = {};
|
||||||
|
this.otherList = {};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
willStart: function () {
|
||||||
|
var self = this;
|
||||||
|
var domain = [
|
||||||
|
['res_id', '=', this.currentResID],
|
||||||
|
['res_model', '=', this.currentResModel],
|
||||||
|
];
|
||||||
|
return $.when(this._super.apply(this, arguments), this._rpc({
|
||||||
|
model: 'ir.attachment',
|
||||||
|
method: 'search_read',
|
||||||
|
domain: domain,
|
||||||
|
}).then(function (result) {
|
||||||
|
self.attachmentIDs = result;
|
||||||
|
_.each(result, function (attachment) {
|
||||||
|
attachment.url = '/web/content/' + attachment.id + '?download=true';
|
||||||
|
// required for compatibility with the chatter templates.
|
||||||
|
attachment.filename = attachment.datas_fname || 'unnamed';
|
||||||
|
});
|
||||||
|
var sortedAttachments = _.partition(result, function (att) {
|
||||||
|
return att.mimetype && att.mimetype.split('/')[0] === 'image';
|
||||||
|
});
|
||||||
|
self.imageList = sortedAttachments[0];
|
||||||
|
self.otherList = sortedAttachments[1];
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Public
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} record
|
||||||
|
*/
|
||||||
|
update: function (record) {
|
||||||
|
this.currentResID = record.res_id;
|
||||||
|
this.currentResModel = record.model;
|
||||||
|
},
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Handlers
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {MouseEvent} ev
|
||||||
|
* used to prevent the click from opening the document viewer.
|
||||||
|
*/
|
||||||
|
_onAttachmentDownload: function (ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {MouseEvent} ev
|
||||||
|
*/
|
||||||
|
_onAttachmentView: function (ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
var activeAttachmentID = $(ev.currentTarget).data('id');
|
||||||
|
if (activeAttachmentID) {
|
||||||
|
var attachmentViewer = new DocumentViewer(this, this.attachmentIDs, activeAttachmentID);
|
||||||
|
attachmentViewer.appendTo($('body'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return AttachmentBox;
|
||||||
|
|
||||||
|
});
|
||||||
@@ -2,6 +2,7 @@ odoo.define('mail.Chatter', function (require) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var Activity = require('mail.Activity');
|
var Activity = require('mail.Activity');
|
||||||
|
var AttachmentBox = require('mail.AttachmentBox');
|
||||||
var ChatterComposer = require('mail.composer.Chatter');
|
var ChatterComposer = require('mail.composer.Chatter');
|
||||||
var Followers = require('mail.Followers');
|
var Followers = require('mail.Followers');
|
||||||
var ThreadField = require('mail.ThreadField');
|
var ThreadField = require('mail.ThreadField');
|
||||||
@@ -30,6 +31,7 @@ var Chatter = Widget.extend({
|
|||||||
events: {
|
events: {
|
||||||
'click .o_chatter_button_new_message': '_onOpenComposerMessage',
|
'click .o_chatter_button_new_message': '_onOpenComposerMessage',
|
||||||
'click .o_chatter_button_log_note': '_onOpenComposerNote',
|
'click .o_chatter_button_log_note': '_onOpenComposerNote',
|
||||||
|
'click .o_chatter_button_attachment': '_onOpenAttachments',
|
||||||
'click .o_chatter_button_schedule_activity': '_onScheduleActivity',
|
'click .o_chatter_button_schedule_activity': '_onScheduleActivity',
|
||||||
},
|
},
|
||||||
supportedFieldTypes: ['one2many'],
|
supportedFieldTypes: ['one2many'],
|
||||||
@@ -69,21 +71,23 @@ var Chatter = Widget.extend({
|
|||||||
this.hasLogButton = options.display_log_button || nodeOptions.display_log_button;
|
this.hasLogButton = options.display_log_button || nodeOptions.display_log_button;
|
||||||
this.postRefresh = nodeOptions.post_refresh || 'never';
|
this.postRefresh = nodeOptions.post_refresh || 'never';
|
||||||
}
|
}
|
||||||
|
this.attachmentBoxOpened = false;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
start: function () {
|
start: function () {
|
||||||
this._$topbar = this.$('.o_chatter_topbar');
|
this._$topbar = this.$('.o_chatter_topbar');
|
||||||
|
this.$('.o_topbar_right_area').append(QWeb.render('mail.chatter.Attachment.Button', {
|
||||||
|
count: this.record.data.related_attachment_count || 0,
|
||||||
|
}));
|
||||||
// render and append the buttons
|
// render and append the buttons
|
||||||
this._$topbar.append(QWeb.render('mail.chatter.Buttons', {
|
this._$topbar.prepend(QWeb.render('mail.chatter.Buttons', {
|
||||||
newMessageButton: !!this.fields.thread,
|
newMessageButton: !!this.fields.thread,
|
||||||
logNoteButton: this.hasLogButton,
|
logNoteButton: this.hasLogButton,
|
||||||
scheduleActivityButton: !!this.fields.activity,
|
scheduleActivityButton: !!this.fields.activity,
|
||||||
isMobile: config.device.isMobile,
|
isMobile: config.device.isMobile,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// start and append the widgets
|
// start and append the widgets
|
||||||
var fieldDefs = _.invoke(this.fields, 'appendTo', $('<div>'));
|
var fieldDefs = _.invoke(this.fields, 'appendTo', $('<div>'));
|
||||||
var def = this._dp.add($.when.apply($, fieldDefs));
|
var def = this._dp.add($.when.apply($, fieldDefs));
|
||||||
@@ -107,6 +111,7 @@ var Chatter = Widget.extend({
|
|||||||
// close the composer if we switch to another record as it is record dependent
|
// close the composer if we switch to another record as it is record dependent
|
||||||
if (this.record.res_id !== record.res_id) {
|
if (this.record.res_id !== record.res_id) {
|
||||||
this._closeComposer(true);
|
this._closeComposer(true);
|
||||||
|
this._closeAttachments();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the state
|
// update the state
|
||||||
@@ -138,12 +143,24 @@ var Chatter = Widget.extend({
|
|||||||
self.$el.height('auto');
|
self.$el.height('auto');
|
||||||
self._updateMentionSuggestions();
|
self._updateMentionSuggestions();
|
||||||
});
|
});
|
||||||
|
this._updateAttachmentCounter();
|
||||||
},
|
},
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Private
|
// Private
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {boolean} force
|
||||||
|
*/
|
||||||
|
_closeAttachments: function () {
|
||||||
|
if (this.fields.attachments) {
|
||||||
|
this.$('.o_chatter_button_attachment').removeClass('o_active_attach');
|
||||||
|
this.fields.attachments.destroy();
|
||||||
|
this.attachmentBoxOpened = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {boolean} force
|
* @param {boolean} force
|
||||||
@@ -199,6 +216,23 @@ var Chatter = Widget.extend({
|
|||||||
_enableChatter: function () {
|
_enableChatter: function () {
|
||||||
this.$('.btn').prop('disabled', false); // enable buttons
|
this.$('.btn').prop('disabled', false); // enable buttons
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_openAttachments: function () {
|
||||||
|
var self = this;
|
||||||
|
this.fields.attachments = new AttachmentBox(this, this.record);
|
||||||
|
|
||||||
|
var $anchor = this.$('.o_chatter_topbar');
|
||||||
|
if (this._composer) {
|
||||||
|
$anchor = this.$('.o_thread_composer');
|
||||||
|
}
|
||||||
|
this.fields.attachments.insertAfter($anchor).then(function () {
|
||||||
|
self.$el.addClass('o_chatter_composer_active');
|
||||||
|
self.$('.o_chatter_button_attachment').addClass('o_active_attach');
|
||||||
|
});
|
||||||
|
this.attachmentBoxOpened = true;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
@@ -235,6 +269,8 @@ var Chatter = Widget.extend({
|
|||||||
self._closeComposer(true);
|
self._closeComposer(true);
|
||||||
if (self._reloadAfterPost(messageData)) {
|
if (self._reloadAfterPost(messageData)) {
|
||||||
self.trigger_up('reload');
|
self.trigger_up('reload');
|
||||||
|
} else if (messageData.attachment_ids.length) {
|
||||||
|
self.trigger_up('reload', {fieldNames: ['related_attachment_count']});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -290,7 +326,7 @@ var Chatter = Widget.extend({
|
|||||||
self.fields.activity.$el.appendTo(self.$el);
|
self.fields.activity.$el.appendTo(self.$el);
|
||||||
}
|
}
|
||||||
if (self.fields.followers) {
|
if (self.fields.followers) {
|
||||||
self.fields.followers.$el.appendTo(self._$topbar);
|
self.fields.followers.$el.insertBefore(self.$('.o_chatter_button_attachment'));
|
||||||
}
|
}
|
||||||
if (self.fields.thread) {
|
if (self.fields.thread) {
|
||||||
self.fields.thread.$el.appendTo(self.$el);
|
self.fields.thread.$el.appendTo(self.$el);
|
||||||
@@ -324,6 +360,14 @@ var Chatter = Widget.extend({
|
|||||||
this.record = record;
|
this.record = record;
|
||||||
this.recordName = record.data.display_name;
|
this.recordName = record.data.display_name;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_updateAttachmentCounter: function () {
|
||||||
|
var count = this.record.data.related_attachment_count || 0;
|
||||||
|
this.$('.o_chatter_attachment_button_count').html(' ('+ count +')');
|
||||||
|
this.$('.o_chatter_button_attachment').toggleClass('o_hidden', !count);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@@ -363,6 +407,16 @@ var Chatter = Widget.extend({
|
|||||||
// Handlers
|
// Handlers
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onOpenAttachments: function () {
|
||||||
|
if (this.attachmentBoxOpened) {
|
||||||
|
this._closeAttachments();
|
||||||
|
} else {
|
||||||
|
this._openAttachments();
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Discard changes on the record.
|
* Discard changes on the record.
|
||||||
* This is notified by the composer, when opening the full-composer.
|
* This is notified by the composer, when opening the full-composer.
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ FormRenderer.include({
|
|||||||
*/
|
*/
|
||||||
confirmChange: function (state, id, fields) {
|
confirmChange: function (state, id, fields) {
|
||||||
if (this.chatter) {
|
if (this.chatter) {
|
||||||
var updatedMailFields = _.intersection(fields, _.values(this.mailFields));
|
var chatterFields = ['related_attachment_count'].concat(_.values(this.mailFields));
|
||||||
|
var updatedMailFields = _.intersection(fields, chatterFields);
|
||||||
if (updatedMailFields.length) {
|
if (updatedMailFields.length) {
|
||||||
this.chatter.update(state, updatedMailFields);
|
this.chatter.update(state, updatedMailFields);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
odoo.define('mail.FormView', function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var FormView = require('web.FormView');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is used to add "related_attachment_count" to fieldsInfo so we can fetch its value for the
|
||||||
|
* chatter's attachment button without having it explicitly declared in the form view template.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
FormView.include({
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
if ('message_ids' in this.fieldsInfo[this.viewType]) {
|
||||||
|
this.fieldsInfo[this.viewType].related_attachment_count = {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
.oe_chatter {
|
||||||
|
.btn.o_active_attach {
|
||||||
|
color: #875A7B;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
.o_chatter_attachment {
|
||||||
|
padding: 3px;
|
||||||
|
|
||||||
|
.o_border_dashed {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-bottom: 1px dashed gray('300');
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.o_attach_title {
|
||||||
|
position: relative;
|
||||||
|
top: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,20 +16,30 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
> .o_topbar_right_area {
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
.o_chatter_button_attachment {
|
||||||
|
height: 2.3em;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.o_followers {
|
||||||
|
height: $o-statusbar-height + 1;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
> .btn {
|
> .btn {
|
||||||
height: $o-statusbar-height + 1;
|
height: $o-statusbar-height + 1;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .o_followers {
|
|
||||||
height: $o-statusbar-height + 1;
|
|
||||||
border-bottom: 1px solid transparent;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.o_chatter_composer_active .o_chatter_topbar {
|
&.o_chatter_composer_active .o_chatter_topbar {
|
||||||
> .btn, > .o_followers{
|
> .btn, > .o_followers, > .o_topbar_right_area{
|
||||||
border-radius: $border-radius-sm $border-radius-sm 0 0;
|
border-radius: $border-radius-sm $border-radius-sm 0 0;
|
||||||
border-width: 0 0 1px;
|
border-width: 0 0 1px;
|
||||||
border-bottom-color: gray('300');
|
border-bottom-color: gray('300');
|
||||||
|
|||||||
@@ -1,11 +1,34 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<templates>
|
<templates>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Chatter attachment tab
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div t-name="mail.chatter.AttachmentBox" class="o_mail_chatter_attachments">
|
||||||
|
<div class="o_chatter_attachment">
|
||||||
|
<div class="o_border_dashed">
|
||||||
|
<span class="o_attach_title">Attachments</span>
|
||||||
|
</div>
|
||||||
|
<div t-if="widget.imageList.length > 0" class="o_attachments_previews">
|
||||||
|
<t t-foreach="widget.imageList" t-as="attachment">
|
||||||
|
<t t-call="mail.AttachmentPreview"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
<div t-if="widget.otherList.length > 0" class="o_attachments_list">
|
||||||
|
<t t-foreach="widget.otherList" t-as="attachment">
|
||||||
|
<t t-call="mail.Attachment"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Chatter composer
|
Chatter composer
|
||||||
|
|
||||||
@param {mail.composer.Chatter} widget
|
@param {mail.composer.Chatter} widget
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<t t-name="mail.chatter.Composer" t-extend="mail.Composer">
|
<t t-name="mail.chatter.Composer" t-extend="mail.Composer">
|
||||||
<!-- Insert information before the composer -->
|
<!-- Insert information before the composer -->
|
||||||
<t t-jquery=".o_composer_container" t-operation="before">
|
<t t-jquery=".o_composer_container" t-operation="before">
|
||||||
@@ -69,6 +92,18 @@
|
|||||||
<button t-if="scheduleActivityButton" class="btn btn-link o_chatter_button_schedule_activity" title="Log or schedule an activity" disabled="disabled">
|
<button t-if="scheduleActivityButton" class="btn btn-link o_chatter_button_schedule_activity" title="Log or schedule an activity" disabled="disabled">
|
||||||
<i class="fa fa-clock-o" role="img" aria-label="Dates" title="Dates"/> <t t-if="isMobile">Activity</t><t t-else="">Schedule activity</t>
|
<i class="fa fa-clock-o" role="img" aria-label="Dates" title="Dates"/> <t t-if="isMobile">Activity</t><t t-else="">Schedule activity</t>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
</t>
|
||||||
|
|
||||||
|
<t t-name="mail.chatter.Attachment.Button">
|
||||||
|
<button t-attf-class="btn btn-sm btn-link o_chatter_button_attachment #{!count and 'o_hidden' or ''}" title="View all the attachments of the current record">
|
||||||
|
<span>
|
||||||
|
<i class="fa fa-paperclip"/>
|
||||||
|
<span class="o_chatter_attachment_button_count">
|
||||||
|
<t t-esc="' ('+count+')'"/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -76,7 +111,9 @@
|
|||||||
-->
|
-->
|
||||||
<t t-name="mail.Chatter">
|
<t t-name="mail.Chatter">
|
||||||
<aside class="o_chatter">
|
<aside class="o_chatter">
|
||||||
<div class="o_chatter_topbar"/>
|
<div class="o_chatter_topbar">
|
||||||
|
<div class="o_topbar_right_area"/>
|
||||||
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
odoo.define('mail.chatter_tests', function (require) {
|
odoo.define('mail.chatter_tests', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var AttachmentBox = require('mail.AttachmentBox');
|
||||||
var mailTestUtils = require('mail.testUtils');
|
var mailTestUtils = require('mail.testUtils');
|
||||||
|
|
||||||
var concurrency = require('web.concurrency');
|
var concurrency = require('web.concurrency');
|
||||||
@@ -34,7 +35,7 @@ QUnit.module('Chatter', {
|
|||||||
string: "Followers",
|
string: "Followers",
|
||||||
type: "one2many",
|
type: "one2many",
|
||||||
relation: 'mail.followers',
|
relation: 'mail.followers',
|
||||||
relation_field: "res_id"
|
relation_field: "res_id",
|
||||||
},
|
},
|
||||||
message_ids: {
|
message_ids: {
|
||||||
string: "messages",
|
string: "messages",
|
||||||
@@ -53,9 +54,14 @@ QUnit.module('Chatter', {
|
|||||||
type: 'selection',
|
type: 'selection',
|
||||||
selection: [['overdue', 'Overdue'], ['today', 'Today'], ['planned', 'Planned']],
|
selection: [['overdue', 'Overdue'], ['today', 'Today'], ['planned', 'Planned']],
|
||||||
},
|
},
|
||||||
|
related_attachment_count: {
|
||||||
|
string: 'Attachment count',
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
records: [{
|
records: [{
|
||||||
id: 2,
|
id: 2,
|
||||||
|
related_attachment_count: 3,
|
||||||
display_name: "first partner",
|
display_name: "first partner",
|
||||||
foo: "HELLO",
|
foo: "HELLO",
|
||||||
message_follower_ids: [],
|
message_follower_ids: [],
|
||||||
@@ -134,6 +140,25 @@ QUnit.module('Chatter', {
|
|||||||
},
|
},
|
||||||
records: [],
|
records: [],
|
||||||
},
|
},
|
||||||
|
'ir.attachment': {
|
||||||
|
fields:{
|
||||||
|
name:{type:'char', string:"attachment name", required:true},
|
||||||
|
res_model:{type:'char', string:"res model"},
|
||||||
|
res_id:{type:'integer', string:"res id"},
|
||||||
|
url:{type:'char', string:'url'},
|
||||||
|
type:{ type:'selection', selection:[['url',"URL"],['binary',"BINARY"]]},
|
||||||
|
mimetype:{type:'char', string:"mimetype"},
|
||||||
|
datas_fname:{type:'char', string:"filename"},
|
||||||
|
},
|
||||||
|
records:[
|
||||||
|
{id:1, name:"name1", type:'url', mimetype:'image/png', datas_fname:'filename.jpg',
|
||||||
|
res_id: 7, res_model: 'partner'},
|
||||||
|
{id:2, name:"name2", type:'binary', mimetype:"application/x-msdos-program",
|
||||||
|
datas_fname:"file2.txt", res_id: 7, res_model: 'partner'},
|
||||||
|
{id:3, name:"name2", type:'binary', mimetype:"application/x-msdos-program",
|
||||||
|
datas_fname:"file2.txt", res_id: 5, res_model: 'partner'},
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
afterEach: function () {
|
afterEach: function () {
|
||||||
@@ -144,7 +169,7 @@ QUnit.module('Chatter', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('basic rendering', function (assert) {
|
QUnit.test('basic rendering', function (assert) {
|
||||||
assert.expect(8);
|
assert.expect(9);
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var unwanted_read_count = 0;
|
var unwanted_read_count = 0;
|
||||||
@@ -187,6 +212,7 @@ QUnit.test('basic rendering', function (assert) {
|
|||||||
"there should be a followers widget, moved inside the chatter's topbar");
|
"there should be a followers widget, moved inside the chatter's topbar");
|
||||||
assert.ok(form.$('.o_chatter').length, "there should be a chatter widget");
|
assert.ok(form.$('.o_chatter').length, "there should be a chatter widget");
|
||||||
assert.ok(form.$('.o_mail_thread').length, "there should be a mail thread");
|
assert.ok(form.$('.o_mail_thread').length, "there should be a mail thread");
|
||||||
|
assert.strictEqual(form.$('.o_chatter_button_attachment').length, 1, "should have one attachment button");
|
||||||
assert.ok(!form.$('.o_chatter_topbar .o_chatter_button_log_note').length,
|
assert.ok(!form.$('.o_chatter_topbar .o_chatter_button_log_note').length,
|
||||||
"log note button should not be available");
|
"log note button should not be available");
|
||||||
|
|
||||||
@@ -196,6 +222,53 @@ QUnit.test('basic rendering', function (assert) {
|
|||||||
form.destroy();
|
form.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('attachmentBox basic rendering', function (assert) {
|
||||||
|
assert.expect(11);
|
||||||
|
this.data.partner.records.push({
|
||||||
|
id: 7,
|
||||||
|
display_name: "attachment_test",
|
||||||
|
});
|
||||||
|
|
||||||
|
var form = createView({
|
||||||
|
View: FormView,
|
||||||
|
model: 'partner',
|
||||||
|
data: this.data,
|
||||||
|
services: this.services,
|
||||||
|
arch: '<form string="Partners">' +
|
||||||
|
'<sheet>' +
|
||||||
|
'<field name="foo"/>' +
|
||||||
|
'</sheet>' +
|
||||||
|
'<div class="oe_chatter">' +
|
||||||
|
'</div>' +
|
||||||
|
'</form>',
|
||||||
|
res_id: 7,
|
||||||
|
});
|
||||||
|
var $button = form.$('.o_chatter_button_attachment');
|
||||||
|
assert.strictEqual($button.length, 1, "should have one attachment button");
|
||||||
|
$button.click();
|
||||||
|
assert.strictEqual(form.$('.o_mail_chatter_attachments').length, 1,
|
||||||
|
"attachment widget should exist after a first click on the button");
|
||||||
|
assert.strictEqual(form.$('.o_attachment_image').length, 1, "there should be an image preview");
|
||||||
|
assert.strictEqual(form.$('.o_attachments_previews').length, 1, "there should be a list of previews");
|
||||||
|
assert.strictEqual(form.$('.o_attachments_list').length, 1, "there should be a list of non previewable attachments");
|
||||||
|
assert.strictEqual(form.$('.o_attachment_title').text(), 'name1',
|
||||||
|
"the image name should be correct");
|
||||||
|
// since there are two elements "Download name2"; one "name" and the other "txt" as text content, the following test
|
||||||
|
// asserts both at the same time.
|
||||||
|
assert.strictEqual(form.$('a[title = "Download name2"]').text().trim(), 'name2txt',
|
||||||
|
"the attachment name should be correct");
|
||||||
|
assert.ok(form.$('.o_attachment_image').css('background-image').indexOf('/web/image/1/160x160/?crop=true') >= 0,
|
||||||
|
"the attachment image URL should be correct");
|
||||||
|
assert.strictEqual(form.$('.o_attachment_download').eq(0).attr('href'), '/web/content/1?download=true',
|
||||||
|
"the download URL of name1 must be correct");
|
||||||
|
assert.strictEqual(form.$('.o_attachment_download').eq(1).attr('href'), '/web/content/2?download=true',
|
||||||
|
"the download URL of name2 must be correct");
|
||||||
|
$button.click();
|
||||||
|
assert.strictEqual(form.$('.o_mail_chatter_attachments').length, 0,
|
||||||
|
"attachment widget should de destroyed after we reclick the button");
|
||||||
|
form.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('chatter in create mode', function (assert) {
|
QUnit.test('chatter in create mode', function (assert) {
|
||||||
assert.expect(9);
|
assert.expect(9);
|
||||||
|
|
||||||
@@ -1496,7 +1569,7 @@ QUnit.test('form activity widget: mark as done and remove', function (assert) {
|
|||||||
} else if (route === '/web/dataset/call_kw/partner/read') {
|
} else if (route === '/web/dataset/call_kw/partner/read') {
|
||||||
nbReads++;
|
nbReads++;
|
||||||
if (nbReads === 1) { // first read
|
if (nbReads === 1) { // first read
|
||||||
assert.strictEqual(args.args[1].length, 4, 'should read all fiels the first time');
|
assert.strictEqual(args.args[1].length, 5, 'should read all fiels the first time');
|
||||||
} else if (nbReads === 2) { // second read: after the unlink
|
} else if (nbReads === 2) { // second read: after the unlink
|
||||||
assert.ok(_.isEqual(args.args[1], ['activity_ids', 'display_name']),
|
assert.ok(_.isEqual(args.args[1], ['activity_ids', 'display_name']),
|
||||||
'should only read the activities (+ display_name) after an unlink');
|
'should only read the activities (+ display_name) after an unlink');
|
||||||
|
|||||||
@@ -55,23 +55,26 @@
|
|||||||
<script type="text/javascript" src="/mail/static/src/js/chatter.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/chatter.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/followers.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/followers.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/form_controller.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/form_controller.js"></script>
|
||||||
|
<script type="text/javascript" src="/mail/static/src/js/form_view.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/form_renderer.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/form_renderer.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/basic_model.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/basic_model.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/basic_view.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/basic_view.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/thread_field.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/thread_field.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/thread_widget.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/thread_widget.js"></script>
|
||||||
<!-- systray -->
|
<!-- systray -->
|
||||||
<script type="text/javascript" src="/mail/static/src/js/systray/systray_activity_menu.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/systray/systray_activity_menu.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/systray/systray_messaging_menu.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/systray/systray_messaging_menu.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/tour.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/tour.js"></script>
|
||||||
<!-- utils -->
|
<!-- utils -->
|
||||||
<script type="text/javascript" src="/mail/static/src/js/utils.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/utils.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/activity.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/activity.js"></script>
|
||||||
<!-- Activity view type -->
|
<!-- Activity view type -->
|
||||||
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_view.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_view.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_model.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_model.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_controller.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_controller.js"></script>
|
||||||
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_renderer.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/views/activity/activity_renderer.js"></script>
|
||||||
|
<!-- Attachment box -->
|
||||||
|
<script type="text/javascript" src="/mail/static/src/js/attachment_box.js"></script>
|
||||||
<!-- Others -->
|
<!-- Others -->
|
||||||
<script type="text/javascript" src="/mail/static/src/js/emojis.js"></script>
|
<script type="text/javascript" src="/mail/static/src/js/emojis.js"></script>
|
||||||
|
|
||||||
@@ -87,6 +90,7 @@
|
|||||||
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/mail_activity.scss"/>
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/mail_activity.scss"/>
|
||||||
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/activity_view.scss"/>
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/activity_view.scss"/>
|
||||||
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/kanban_view.scss"/>
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/kanban_view.scss"/>
|
||||||
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/attachment_box.scss"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user