[IMP]mail: js

bzr revid: chm@openerp.com-20121002105235-pxap9qmfht35mc7z
This commit is contained in:
Christophe Matthieu 2012-10-02 12:52:35 +02:00
parent eaf0b9da2f
commit b6bb3fbde1
4 changed files with 97 additions and 118 deletions

View File

@ -303,44 +303,45 @@ class mail_message(osv.Model):
:return list: list of trees of messages :return list: list of trees of messages
""" """
message_loaded = context and context.get('message_loaded') or [0]
# don't read the message display by .js, in context message_loaded list # don't read the message display by .js, in context message_loaded list
if context and context.get('message_loaded'): if context and context.get('message_loaded'):
domain += [ ['id','not in',context.get('message_loaded')] ]; domain += [ ['id','not in',message_loaded] ];
limit = limit or self._message_read_limit limit = limit or self._message_read_limit
context = context or {} context = context or {}
if not ids: if not ids:
ids = self.search(cr, SUPERUSER_ID, domain, context=context, limit=limit) ids = self.search(cr, SUPERUSER_ID, domain, context=context, limit=limit)
# if the user can read a message, he can read all the thread # if the user can read a message, he can read all the thread
ids = ids + self.search(cr, SUPERUSER_ID, [['parent_id','in',ids]], None, limit=limit) ids = ids + self.search(cr, SUPERUSER_ID, [['parent_id','in',ids],['id','not in',message_loaded]], None, limit=limit)
messages = self.browse(cr, uid, ids, context=context) messages = self.browse(cr, uid, ids, context=context)
add_expandable = (len(messages) >= limit) add_expandable = (len(messages) >= limit)
# key: ID, value: record # key: ID, value: record
tree = {} tree = []
result = [] result = []
for msg in messages: for msg in messages:
record = self._message_dict_get(cr, uid, msg, context=context)
while msg.parent_id and msg.parent_id.id != parent_id:
if msg.parent_id.id in tree:
record_parent = tree[msg.parent_id.id]
else:
record_parent = self._message_dict_get(cr, uid, msg.parent_id, context=context)
if msg.parent_id.parent_id:
tree[msg.parent_id.id] = record_parent
if record['id'] not in [x['id'] for x in record_parent['child_ids']]:
record_parent['child_ids'].append(record)
record = record_parent
msg = msg.parent_id
# if not in record and not in message_loded list # if not in record and not in message_loded list
if msg.id not in tree and not(context and context.get('message_loaded') and msg.id in context.get('message_loaded')) : if msg.id not in tree and msg.id not in message_loaded :
record = self._message_dict_get(cr, uid, msg, context=context)
tree.append(msg.id)
result.append(record) result.append(record)
tree[msg.id] = record
while msg.parent_id and msg.parent_id.id != parent_id:
parent_id = msg.parent_id.id
if msg.parent_id.id not in tree:
msg = msg.parent_id
tree.append(msg.id)
# if not in record and not in message_loded list
if msg.id not in message_loaded :
record = self._message_dict_get(cr, uid, msg, context=context)
result.append(record)
# Flatten the result # Flatten the result
result2 = self.message_read_tree_flatten(cr, uid, None, result, [], level, context=context, limit=limit, add_expandable=add_expandable) #result2 = self.message_read_tree_flatten(cr, uid, None, result, [], level, context=context, limit=limit, add_expandable=add_expandable)
return result2 return result
#------------------------------------------------------ #------------------------------------------------------
# Email api # Email api

View File

@ -22,8 +22,9 @@ openerp.mail = function(session) {
action.context && action.context.redirect == true && action.context && action.context.redirect == true &&
this.fields && this.fields.message_ids && this.fields.message_ids.view.get("actual_mode") != 'create') { this.fields && this.fields.message_ids && this.fields.message_ids.view.get("actual_mode") != 'create') {
var thread = this.fields.message_ids.thread; var thread = this.fields.message_ids.thread;
thread.refresh(action.context); thread.refresh(action.context);
return true; return false;
} }
else { else {
return this._super(action, on_close); return this._super(action, on_close);
@ -194,6 +195,7 @@ openerp.mail = function(session) {
* the widget without having to rebuild a complete form view. * the widget without having to rebuild a complete form view.
* @param {Object} new_context: context of the refresh */ * @param {Object} new_context: context of the refresh */
refresh: function (new_context) { refresh: function (new_context) {
console.log("refresh");
if (! this.form_view) return; if (! this.form_view) return;
var self = this; var self = this;
this.attachments = []; this.attachments = [];
@ -204,12 +206,21 @@ openerp.mail = function(session) {
'use_template', 'template_id', 'model', 'res_id', 'parent_id', 'content_subtype'], 'use_template', 'template_id', 'model', 'res_id', 'parent_id', 'content_subtype'],
this.ds_compose.get_context(), this.ds_compose.get_context(),
]).then( function (result) { ]).then( function (result) {
console.log("refresh",result);
self.form_view.on_processed_onchange({'value': result}, []); self.form_view.on_processed_onchange({'value': result}, []);
self.attachment_ids = []; self.attachment_ids = [];
self.display_attachments(); self.display_attachments();
}); });
}, },
/*
empty: function(){
var self=this;
self.form_view.on_processed_onchange({'value': {
}}, []);
},*/
/** /**
* Bind events in the widget. Each event is slightly described * Bind events in the widget. Each event is slightly described
* in the function. */ * in the function. */
@ -228,6 +239,7 @@ openerp.mail = function(session) {
this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete); this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete);
}, },
}), }),
/** /**
* ------------------------------------------------------------ * ------------------------------------------------------------
@ -243,7 +255,24 @@ openerp.mail = function(session) {
* - - sub message (parent_id = root message) * - - sub message (parent_id = root message)
* - - - sub thread * - - - sub thread
*/ */
mail.ThreadMessage = session.web.Widget.extend({
});
/**
* ------------------------------------------------------------
* Thread Message Widget
* ------------------------------------------------------------
*
* This widget handles the display of a messages in a thread. The
* [thread_level] parameter sets the thread level number:
* - root thread
* - - sub message (parent_id = root message)
* - - - sub thread
* - - - - sub sub message (parent id = sub thread)
* - - sub message (parent_id = root message)
* - - - sub thread
*/
mail.ThreadMessage = session.web.Widget.extend({ mail.ThreadMessage = session.web.Widget.extend({
template: 'mail.thread.message', template: 'mail.thread.message',
@ -294,8 +323,6 @@ openerp.mail = function(session) {
this.parent_thread= parent.messages!= undefined ? parent : options.options.thread._parents[0] ; this.parent_thread= parent.messages!= undefined ? parent : options.options.thread._parents[0] ;
var param = options.parameters; var param = options.parameters;
// child messages
this.child_ids= param.child_ids;
// record parameters // record parameters
this.id = param.id || -1; this.id = param.id || -1;
this.model = param.model || false; this.model = param.model || false;
@ -330,7 +357,6 @@ openerp.mail = function(session) {
formating_data: function(){ formating_data: function(){
//formating and add some fields for render //formating and add some fields for render
this.timestamp = Date.parse(this._date).getTime();
this.date = session.web.format_value(this._date, {type:"datetime"}); this.date = session.web.format_value(this._date, {type:"datetime"});
this.timerelative = $.timeago(this.date); this.timerelative = $.timeago(this.date);
if (this.type == 'email') { if (this.type == 'email') {
@ -350,8 +376,6 @@ openerp.mail = function(session) {
this.$el.hide().fadeIn(750); this.$el.hide().fadeIn(750);
this.bind_events(); this.bind_events();
this.create_thread(); this.create_thread();
this.parent_thread.when_insert_message();
}, },
/** /**
@ -428,7 +452,6 @@ openerp.mail = function(session) {
'parameters':{ 'parameters':{
'model': self.model, 'model': self.model,
'id': self.id, 'id': self.id,
'child_ids': self.child_ids,
'parent_id': self.id 'parent_id': self.id
} }
} }
@ -443,13 +466,10 @@ openerp.mail = function(session) {
if(options.fadeTime) { if(options.fadeTime) {
self.$el.fadeOut(options.fadeTime, function(){ self.$el.fadeOut(options.fadeTime, function(){
self.destroy(); self.destroy();
self.parent_thread.when_message_destroy();
}); });
} else { } else {
self.destroy(); self.destroy();
self.parent_thread.when_message_destroy();
} }
for(var i in this.thread.messages){ for(var i in this.thread.messages){
this.thread.messages[i].animated_destroy({fadeTime:0}); this.thread.messages[i].animated_destroy({fadeTime:0});
} }
@ -580,7 +600,6 @@ openerp.mail = function(session) {
* - - - sub sub message (parent id = sub message) * - - - sub sub message (parent id = sub message)
* - - sub message (parent_id = root message) * - - sub message (parent_id = root message)
*/ */
mail.Thread = session.web.Widget.extend({ mail.Thread = session.web.Widget.extend({
template: 'mail.thread', template: 'mail.thread',
@ -632,8 +651,6 @@ openerp.mail = function(session) {
this.parent_linked_message= parent.thread!= undefined ? parent : false ; this.parent_linked_message= parent.thread!= undefined ? parent : false ;
var param = options.parameters var param = options.parameters
// child messages
this.child_ids=param.child_ids || [];
// datasets and internal vars // datasets and internal vars
this.id= param.id || false; this.id= param.id || false;
this.model= param.model || false; this.model= param.model || false;
@ -664,8 +681,6 @@ openerp.mail = function(session) {
this.bind_events(); this.bind_events();
this.switch_new_message(this.child_ids);
return display_done && compose_done; return display_done && compose_done;
}, },
@ -674,9 +689,8 @@ openerp.mail = function(session) {
* Normally it should be called only when clicking on 'Post/Send' * Normally it should be called only when clicking on 'Post/Send'
* in the composition form. */ * in the composition form. */
do_action: function(action, on_close) { do_action: function(action, on_close) {
var self=this; this.instantiate_composition_form();
self.instantiate_composition_form(); this.message_fetch();
self.message_fetch();
return this._super(action, on_close); return this._super(action, on_close);
}, },
@ -719,25 +733,12 @@ openerp.mail = function(session) {
return res; return res;
}, },
/* this method is call when we insert a message in the thread
* and object is create and started
*/
when_insert_message: function(){
this.display_expandable();
},
/* this method is call when we destroy a message of the thread
*/
when_message_destroy: function(){
this.display_expandable();
},
/** browse thread /** browse thread
* @param {object}{int} option.id * @param {object}{int} option.id
* @param {object}{string} option.model * @param {object}{string} option.model
* @param {object}{boolean} option._go_thread_wall * @param {object}{boolean} option._go_thread_wall
* private for check the top thread * private for check the top thread
* @param {object}{boolean} option.top_thread * @param {object}{boolean} option.default_return_top_thread
* return the top thread (wall) if no thread found * return the top thread (wall) if no thread found
* @return thread object * @return thread object
*/ */
@ -748,7 +749,7 @@ openerp.mail = function(session) {
return this.options.thread._parents[0].browse_thread(options); return this.options.thread._parents[0].browse_thread(options);
} }
if(options.id && options.model){ if(options.id && options.model){
if(this.id==options.id && this.model==options.model) if(this.id==options.id)
return this; return this;
for(var i in this.messages){ for(var i in this.messages){
@ -757,9 +758,9 @@ openerp.mail = function(session) {
} }
} }
//if option top_thread, return the top if no found thread //if option default_return_top_thread, return the top if no found thread
if(options.top_thread){ if(options.default_return_top_thread){
return this; return this.options.thread._parents[0];
} }
return false; return false;
@ -790,10 +791,8 @@ openerp.mail = function(session) {
this.$("textarea:first").val(""); this.$("textarea:first").val("");
return false; return false;
} }
var self=this;
if (this.compose_message_widget) { if (this.compose_message_widget) {
this.compose_message_widget.$("textarea, input").val(""); this.compose_message_widget.refresh();
} else { } else {
var context = _.extend(context || {}, this.context); var context = _.extend(context || {}, this.context);
this.compose_message_widget = new mail.ComposeMessage(this, {'context': context}); this.compose_message_widget = new mail.ComposeMessage(this, {'context': context});
@ -820,8 +819,9 @@ openerp.mail = function(session) {
}, },
refresh: function (action_context) { refresh: function (action_context) {
_(this.messages).each(function(){ this.destroy(); }); var self=this;
this.message_fetch(); _(this.messages).each(function(){ self.destroy(); });
self.message_fetch();
}, },
/*post a message and fletch the message*/ /*post a message and fletch the message*/
@ -853,8 +853,6 @@ openerp.mail = function(session) {
message_fetch: function (initial_mode, additional_domain, additional_context) { message_fetch: function (initial_mode, additional_domain, additional_context) {
var self = this; var self = this;
console.log("message_fetch", self);
// initial mode: try to use message_data or message_ids // initial mode: try to use message_data or message_ids
if (initial_mode && this.options.thread.message_data) { if (initial_mode && this.options.thread.message_data) {
return this.create_message_object(this.options.message_data); return this.create_message_object(this.options.message_data);
@ -872,43 +870,24 @@ openerp.mail = function(session) {
/* create record object and linked him /* create record object and linked him
*/ */
create_message_object: function (record) { create_message_object: function (message) {
var self = this; var self = this;
if(record.id < 0){ if(message.type=='expandable'){
return false; return false;
} }
// chck if the message is already read // check if the message is already create
for(var i in this.messages){ for(var i in this.messages){
if(this.messages[i].id==record.id && this.messages[i].model==record.model) if(this.messages[i].id==message.id){
return false; this.messages[i].destroy();
this.messages[i]=self.insert_message(message);
return true;
}
} }
// delete child no read self.messages.push( self.insert_message(message) );
var child_ids=[];
for(var i in this.child_ids){
if(this.child_ids[i]!=record.id)
child_ids.push( this.child_ids[i] );
}
this.child_ids=child_ids;
/*create message*/
var message = new mail.ThreadMessage(self, {
'domain': record.domain,
'context': {
'default_model': record.model,
'default_res_id': record.res_id,
'default_parent_id': record.id },
'options':{
'thread': self.options.thread,
'message': self.options.message
},
'parameters': record
});
self.insert_message(message);
self.messages.push(message);
}, },
/** Displays a record and performs some formatting on the record : /** Displays a record and performs some formatting on the record :
@ -918,15 +897,30 @@ openerp.mail = function(session) {
* - record.attachment_ids[].url: url of each attachment */ * - record.attachment_ids[].url: url of each attachment */
insert_message: function (message) { insert_message: function (message) {
var self=this; var self=this;
/*create message*/
var message = new mail.ThreadMessage(self, {
'domain': message.domain,
'context': {
'default_model': message.model,
'default_res_id': message.res_id,
'default_parent_id': message.id },
'options':{
'thread': self.options.thread,
'message': self.options.message
},
'parameters': message
});
// check older and newer message for insert // check older and newer message for insert
var parent_newer = false; var parent_newer = false;
var parent_older = false; var parent_older = false;
for(var i in this.messages){ for(var i in this.messages){
if(this.messages[i].timestamp > message.timestamp){ if(this.messages[i].id > message.id){
if(!parent_newer || parent_newer.timestamp>this.messages[i].timestamp) if(!parent_newer || parent_newer.id>this.messages[i].id)
parent_newer = this.messages[i]; parent_newer = this.messages[i];
} else if(this.messages[i].timestamp>0 && this.messages[i].timestamp < message.timestamp) { } else if(this.messages[i].id>0 && this.messages[i].id < message.id) {
if(!parent_older || parent_older.timestamp<this.messages[i].timestamp) if(!parent_older || parent_older.id<this.messages[i].id)
parent_older = this.messages[i]; parent_older = this.messages[i];
} }
} }
@ -937,6 +931,8 @@ openerp.mail = function(session) {
message.insertBefore(parent_older.$el); message.insertBefore(parent_older.$el);
else else
message.prependTo(this.list_ul); message.prependTo(this.list_ul);
return message
}, },
/* Hide messages if they are more message that _expandable_max /* Hide messages if they are more message that _expandable_max
@ -950,9 +946,6 @@ openerp.mail = function(session) {
this.list_ul.find('>li').show(); this.list_ul.find('>li').show();
this.more_msg.hide(); this.more_msg.hide();
} }
if(this.child_ids>0){
this.more_msg.show();
}
}, },
display_user_avatar: function () { display_user_avatar: function () {
@ -960,23 +953,11 @@ openerp.mail = function(session) {
return this.$('img.oe_mail_icon').attr('src', avatar); return this.$('img.oe_mail_icon').attr('src', avatar);
}, },
/* Display the message if if the msg_id don't exists. /* Send the records to his parent thread */
* If the record have a parent, insert parent or inside parent */
switch_new_message: function(records) { switch_new_message: function(records) {
var self=this; var self=this;
_(records.reverse()).each(function (record) { _(records).each(function(record){
if(!self.options.thread.display_on_flat){ self.browse_thread({'id': (self.options.thread.display_on_flat ? record.parent_id : false), 'default_return_top_thread':true}).create_message_object( record );
if(record.parent_id==self.id && record.model==self.model){
return self.create_message_object( record );
} else if(record.parent_id){
var thread=self.browse_thread({'id':record.parent_id, 'model':record.model});
if(thread) {
return thread.create_message_object( record );
}
}
}
var thread=self.browse_thread({'top_thread':true});
return thread.create_message_object( record );
}); });
}, },

View File

@ -114,8 +114,8 @@
<ul class="oe_header"> <ul class="oe_header">
<li class="placeholder-mail-vote"><t t-call="mail.thread.message.vote"/></li> <li class="placeholder-mail-vote"><t t-call="mail.thread.message.vote"/></li>
<t t-if="!widget.options.thread.display_on_flat"> <t t-if="!widget.options.thread.display_on_flat">
<li t-if="widget.options.thread._parents.length&lt;=widget.options.thread.thread_level and widget.unread" title="Read"><a class="oe_read oe_e">W</a></li> <li t-if="widget.unread" title="Read"><a class="oe_read oe_e">W</a></li>
<li t-if="widget.options.thread._parents.length&lt;=widget.options.thread.thread_level and !widget.unread" title="Set back to unread"><a class="oe_unread oe_e">h</a></li> <li t-if="!widget.unread" title="Set back to unread"><a class="oe_unread oe_e">h</a></li>
<li t-if="widget.options.thread._parents.length&lt;=widget.options.thread.thread_level and widget.options.message.show_reply" title="Reply"><a class="oe_reply oe_e">)</a></li> <li t-if="widget.options.thread._parents.length&lt;=widget.options.thread.thread_level and widget.options.message.show_reply" title="Reply"><a class="oe_reply oe_e">)</a></li>
<li t-if="widget.options.message.show_reply_by_email"><a class="oe_reply_by_email oe_e" title="Reply by mail">)</a></li> <li t-if="widget.options.message.show_reply_by_email"><a class="oe_reply_by_email oe_e" title="Reply by mail">)</a></li>
</t> </t>

View File

@ -254,10 +254,7 @@ class mail_compose_message(osv.TransientModel):
self.pool.get('ir.attachment').write(cr, uid, [attach.id for attach in wizard.attachment_ids], { self.pool.get('ir.attachment').write(cr, uid, [attach.id for attach in wizard.attachment_ids], {
'res_id': wizard.id, 'res_model': wizard.model or False}, context=context) 'res_id': wizard.id, 'res_model': wizard.model or False}, context=context)
if context.get('mail_action_wizard_close'): return {'type': 'ir.actions.act_window_close', 'res_model':'mail.compose.message'}
return {'type': 'ir.actions.act_window_close'}
else:
return {}
def render_message(self, cr, uid, wizard, res_id, context=None): def render_message(self, cr, uid, wizard, res_id, context=None):
""" Generate an email from the template for given (wizard.model, res_id) """ Generate an email from the template for given (wizard.model, res_id)