bzr revid: fp@tinyerp.com-20120820165615-iekhshkbxnksa73j
This commit is contained in:
Fabien Pinckaers 2012-08-20 18:56:15 +02:00
commit c264a4f05a
8 changed files with 207 additions and 330 deletions

View File

@ -104,9 +104,9 @@
/>
<record model="ir.ui.view" id="email_message_tree_view">
<field name="name">mail.mail.list.fetchmail</field>
<field name="name">mail.mail.form.fetchmail</field>
<field name="model">mail.mail</field>
<field name="inherit_id" ref="mail.view_email_message_form"/>
<field name="inherit_id" ref="mail.view_mail_form"/>
<field name="arch" type="xml">
<field name="references" position="after">
<field name="fetchmail_server_id"/>

View File

@ -73,6 +73,7 @@ class mail_notification(osv.Model):
context = context or {}
partner_obj = self.pool.get('res.partner')
msg_obj = self.pool.get('mail.message')
notification_obj = self.pool.get('mail.notification')
msg = msg_obj.browse(cr, uid, msg_id, context=context)
towrite = {

View File

@ -130,7 +130,7 @@ class mail_group(osv.Model):
# Create client action for this group and link the menu to it
ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'action_mail_group_feeds')
if ref:
search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search_wall')
search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search')
params = {
'search_view_id': search_ref and search_ref[1] or False,
'domain': [('model','=','mail.group'),('res_id','=',mail_group_id)],

View File

@ -5,7 +5,6 @@
<record id="action_mail_group_feeds" model="ir.actions.client">
<field name="name">Discussion Group</field>
<field name="tag">mail.wall</field>
<field name="params" eval="{'search_view_id': ref('view_message_search_wall')}"/>
</record>
<!-- Group Kanban View !-->
@ -17,6 +16,7 @@
<kanban>
<field name="message_follower_ids"/>
<field name="message_is_follower"/>
<field name="message_summary"/>
<templates>
<t t-name="kanban-description">
<div class="oe_group_description" t-if="record.description.raw_value">

View File

@ -127,7 +127,7 @@ class mail_message(osv.Model):
# Message loading for web interface
#------------------------------------------------------
_limit = 10
_limit = 3
def _message_dict_get(self, cr, uid, msg, context={}):
attachs = self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)
author = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id,], context=context)[0]

View File

@ -2,8 +2,8 @@
<openerp>
<data>
<!-- mail.message tree: short view !-->
<record model="ir.ui.view" id="view_message_tree_short">
<field name="name">mail.message.tree.short</field>
<record model="ir.ui.view" id="view_message_tree">
<field name="name">mail.message.tree</field>
<field name="model">mail.message</field>
<field name="priority">20</field>
<field name="arch" type="xml">
@ -18,8 +18,8 @@
</record>
<!-- mail.message form: short view !-->
<record model="ir.ui.view" id="view_message_form_short">
<field name="name">mail.message.form.short</field>
<record model="ir.ui.view" id="view_message_form">
<field name="name">mail.message.form</field>
<field name="model">mail.message</field>
<field name="priority">20</field>
<field name="arch" type="xml">
@ -45,28 +45,16 @@
</field>
</record>
<!-- mail.message search: short view !-->
<record model="ir.ui.view" id="view_message_search_short">
<field name="name">mail.message.search.short</field>
<field name="model">mail.message</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<search string="Messages Search">
<field name="body" string="Message"/>
<field name="author_id"/>
</search>
</field>
</record>
<!-- mail.message search: wall view !-->
<record model="ir.ui.view" id="view_message_search_wall">
<field name="name">mail.message.search.wall</field>
<record model="ir.ui.view" id="view_message_search">
<field name="name">mail.message.search</field>
<field name="model">mail.message</field>
<field name="priority">25</field>
<field name="arch" type="xml">
<search string="Messages Search">
<field name="subject" string="Content" filter_domain="['|', ('subject', 'ilike', self), ('body', 'ilike', self)]" />
<field name="type"/>
<field name="author_id"/>
<filter icon="terp-personal+" string="Comments"
name="comments" help="Comments"
domain="[('type', '=', 'comment')]"/>
@ -81,7 +69,7 @@
</field>
</record>
<record model="ir.ui.view" id="view_email_message_form">
<record model="ir.ui.view" id="view_mail_form">
<field name="name">mail.mail.form</field>
<field name="model">mail.mail</field>
<field name="arch" type="xml">
@ -142,9 +130,9 @@
</field>
</record>
<record model="ir.ui.view" id="view_email_message_tree">
<record model="ir.ui.view" id="view_mail_tree">
<field name="name">mail.message.tree</field>
<field name="model">mail.message</field>
<field name="model">mail.mail</field>
<field name="arch" type="xml">
<tree string="Emails" colors="grey:state in ('sent', 'cancel');blue:state=='outgoing';red:state=='exception';black:state=='received'">
<field name="date"/>
@ -154,6 +142,9 @@
<field name="partner_ids" invisible="1"/>
<field name="model" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="email_from" invisible="1"/>
<field name="state" invisible="1"/>
<field name="type" invisible="1"/>
<button name="send" string="Send Now" type="object" icon="gtk-media-play" states='outgoing'/>
<button name="mark_outgoing" string="Retry" type="object" icon="gtk-redo" states='exception,cancel'/>
<button name="cancel" string="Cancel" type="object" icon="terp-gtk-stop" states='outgoing'/>
@ -161,7 +152,7 @@
</field>
</record>
<record model="ir.ui.view" id="view_email_message_search">
<record model="ir.ui.view" id="view_mail_search">
<field name="name">mail.mail.search</field>
<field name="model">mail.mail</field>
<field name="arch" type="xml">
@ -193,22 +184,21 @@
</field>
</record>
<record id="action_view_all_messages_short" model="ir.actions.act_window">
<field name="name">Messages</field>
<field name="res_model">mail.message</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'tree_view_ref': 'mail.view_message_tree_short', 'form_view_ref': 'mail.view_message_form_short'}</field>
<field name="search_view_id" ref="view_message_search_short"/>
</record>
<record id="action_view_mail_message" model="ir.actions.act_window">
<field name="name">Messages</field>
<field name="res_model">mail.message</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_message_search"/>
</record>
<record id="action_view_mail_mail" model="ir.actions.act_window">
<field name="name">Messages</field>
<field name="res_model">mail.mail</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_received': 1, 'search_default_type_email': 1}</field>
<field name="search_view_id" ref="view_email_message_search"/>
<field name="search_view_id" ref="view_mail_search"/>
</record>
<act_window domain="[('partner_id', '=', active_id), ('email_from', '!=', False)]"
@ -216,18 +206,19 @@
id="act_res_partner_emails" name="Emails"
res_model="mail.message"
src_model="res.partner"
view_id="view_email_message_tree"/>
view_id="view_message_tree"/>
<!-- Add menu entry in Settings/Email -->
<menuitem name="Messages" id="menu_email_message" parent="base.menu_email" action="action_view_mail_message" />
<menuitem name="Mails" id="menu_mail_mail" parent="base.menu_email" action="action_view_mail_mail" />
<!-- Add menu entry in Settings/Email -->
<menuitem name="Feeds" id="menu_email_message_all" parent="base.menu_email" action="action_view_all_messages_short" groups="base.group_no_one"/>
<menuitem name="Messages" id="menu_mail_message" parent="base.menu_email" action="action_view_mail_message"/>
<record id="action_mail_all_feeds" model="ir.actions.client">
<field name="name">News Feed</field>
<field name="tag">mail.wall</field>
<field name="params" eval="{'domain': [('notification_ids.partner_id.user_ids', 'in', '[uid]')] }"/>
<field name="params" eval=""/>
<!-- <field name="params" eval="{'domain': [('notification_ids.partner_id.user_ids', 'in', '[uid]')] }"/> -->
</record>
<record id="action_mail_my_feeds" model="ir.actions.client">

View File

@ -99,14 +99,16 @@ class res_users(osv.Model):
data.pop('alias_name', None) # prevent errors during copy()
# create user that follows its related partner
user_id = super(res_users, self).create(cr, uid, data, context=context)
self.pool.get('res.partner').message_subscribe_users(cr, uid, [user_id], [user_id], context=context)
# alias
mail_alias.write(cr, SUPERUSER_ID, [alias_id], {"alias_force_thread_id": user_id}, context)
# create a welcome message
self._create_welcome_message(cr, uid, user, context=context)
self._create_welcome_message(cr, uid, user_id, context=context)
return user_id
def _create_welcome_message(self, cr, uid, user, context=None):
def _create_welcome_message(self, cr, uid, user_id, context=None):
user = self.browse(cr, uid, user_id, context=context)
company_name = user.company_id.name if user.company_id else _('the company')
body = '''%s has joined %s.''' % (user.name, company_name)
# TODO change 1 into user.id but catch errors

View File

@ -38,30 +38,25 @@ openerp.mail = function(session) {
*
* This class holds a few tools method that will be used by
* the various Chatter widgets.
*
* Some regular expressions not used anymore, kept because I want to
* - (^|\s)@((\w|@|\.)*): @login@log.log, supports inner '@' for
* logins that are emails
* 1. '(void)'
* 2. login@log.log
* - (^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]: [ir.attachment,3|My Label],
* for internal links to model ir.attachment, id=3, and with
* optional label 'My Label'. Note that having a '|Label' is not
* mandatory, because the regex should still be correct.
* 1. '(void)'
* 2. 'ir'
* 3. 'attachment'
* 4. '3'
* 5. 'My Label'
*/
mail.ChatterUtils = {
/* generic chatter events binding */
bind_events: function(widget) {
// event: click on an internal link to a document: model, login
widget.$element.delegate('a.oe_mail_internal_link', 'click', function (event) {
event.preventDefault();
// lazy implementation: fetch data and try to redirect
if (! event.srcElement.dataset.resModel) return false;
else var res_model = event.srcElement.dataset.resModel;
var res_login = event.srcElement.dataset.resLogin;
if (! res_login) return false;
var ds = new session.web.DataSet(widget, res_model);
var defer = ds.call('search', [[['login', '=', res_login]]]).pipe(function (records) {
if (records[0]) {
widget.do_action({ type: 'ir.actions.act_window', res_model: res_model, res_id: parseInt(records[0]), views: [[false, 'form']]});
}
else return false;
});
});
},
/** get an image in /web/binary/image?... */
get_image: function(session_prefix, session_id, model, field, id) {
return session_prefix + '/web/binary/image?session_id=' + session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
@ -72,91 +67,7 @@ openerp.mail = function(session) {
return (widget.session && widget.session.uid != 0 && widget.session.uid == message_user_id);
},
/**
* Add records to comments_structure array
* @param {Array} records records from mail.message sorted by date desc
* @returns {Object} cs comments_structure: dict
* cs.model_to_root_ids = {model: [root_ids], }
* cs.new_root_ids = [new_root_ids]
* cs.root_ids = [root_ids]
* cs.msgs = {record.id: record,}
* cs.tree_struct = {record.id: {
* 'level': record_level in hierarchy, 0 is root,
* 'msg_nbr': number of childs,
* 'direct_childs': [msg_ids],
* 'all_childs': [msg_ids],
* 'for_thread_msgs': [records],
* 'ancestors': [msg_ids], } }
*/
// records_struct_add_records: function(cs, records, parent_id) {
// var cur_iter = 0; var max_iter = 10; var modif = true;
// while ( modif && (cur_iter++) < max_iter) {
// modif = false;
// _(records).each(function (record) {
// // root and not yet recorded
// if ( (record.parent_id == false || record.parent_id[0] == parent_id) && ! cs['msgs'][record.id]) {
// // add to model -> root_list ids
// if (! cs['model_to_root_ids'][record.model]) cs['model_to_root_ids'][record.model] = [record.id];
// else cs['model_to_root_ids'][record.model].push(record.id);
// // add root data
// cs['new_root_ids'].push(record.id);
// // add record
// cs['tree_struct'][record.id] = {'level': 0, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [record], 'msg_nbr': -1, 'ancestors': []};
// cs['msgs'][record.id] = record;
// modif = true;
// }
// // not yet recorded, but parent is recorded
// else if (! cs['msgs'][record.id] && cs['msgs'][record.parent_id[0]]) {
// var parent_level = cs['tree_struct'][record.parent_id[0]]['level'];
// // update parent structure
// cs['tree_struct'][record.parent_id[0]]['direct_childs'].push(record.id);
// cs['tree_struct'][record.parent_id[0]]['for_thread_msgs'].push(record);
// // update ancestors structure
// for (ancestor_id in cs['tree_struct'][record.parent_id[0]]['ancestors']) {
// cs['tree_struct'][ancestor_id]['all_childs'].push(record.id);
// }
// // add record
// cs['tree_struct'][record.id] = {'level': parent_level+1, 'direct_childs': [], 'all_childs': [], 'for_thread_msgs': [], 'msg_nbr': -1, 'ancestors': []};
// cs['msgs'][record.id] = record;
// modif = true;
// }
// });
// }
// return cs;
// },
/* copy cs.new_root_ids into cs.root_ids */
// records_struct_update_after_display: function(cs) {
// // update TODO
// cs['root_ids'] = _.union(cs['root_ids'], cs['new_root_ids']);
// cs['new_root_ids'] = [];
// return cs;
// },
/**
* CONTENT MANIPULATION
*
* Regular expressions
* - (^|\s)@((\w|@|\.)*): @login@log.log, supports inner '@' for
* logins that are emails
* 1. '(void)'
* 2. login@log.log
* - (^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]: [ir.attachment,3|My Label],
* for internal links to model ir.attachment, id=3, and with
* optional label 'My Label'. Note that having a '|Label' is not
* mandatory, because the regex should still be correct.
* 1. '(void)'
* 2. 'ir'
* 3. 'attachment'
* 4. '3'
* 5. 'My Label'
*/
/**
* Replaces some expressions
* - @login - shorcut to link to a res.user, given its login
* - [ir.attachment,3|My Label] - shortcut to an internal
* document
/** Replaces some expressions
* - :name - shortcut to an image
*/
do_replace_expressions: function (string) {
@ -173,7 +84,6 @@ openerp.mail = function(session) {
}
return string;
},
};
@ -192,33 +102,33 @@ openerp.mail = function(session) {
/**
* @param {Object} parent parent
* @param {Object} [params]
* @param {String} [params.res_model] res_model of document [REQUIRED]
* @param {Number} [params.res_id] res_id of record [REQUIRED]
* @param {Number} [params.email_mode] true/false, tells whether
* @param {Object} [options]
* @param {String} [options.res_model] res_model of document [REQUIRED]
* @param {Number} [options.res_id] res_id of record [REQUIRED]
* @param {Number} [options.email_mode] true/false, tells whether
* we are in email sending mode
* @param {Number} [params.formatting] true/false, tells whether
* @param {Number} [options.formatting] true/false, tells whether
* we are in advance formatting mode
* @param {String} [params.model] mail.compose.message.mode (see
* @param {String} [options.model] mail.compose.message.mode (see
* composition wizard)
* @param {Number} [params.msg_id] id of a message in case we are in
* @param {Number} [options.msg_id] id of a message in case we are in
* reply mode
*/
init: function(parent, params) {
init: function(parent, options) {
var self = this;
this._super(parent);
// options
this.params = params || {};
this.params.context = params.context || {};
this.params.email_mode = params.email_mode || false;
this.params.formatting = params.formatting || false;
this.params.mode = params.mode || 'comment';
this.params.form_xml_id = params.form_xml_id || 'email_compose_message_wizard_form_chatter';
this.params.form_view_id = false;
if (this.params.mode == 'reply') {
this.params.active_id = this.params.msg_id;
this.options = options || {};
this.options.context = options.context || {};
this.options.email_mode = options.email_mode || false;
this.options.formatting = options.formatting || false;
this.options.mode = options.mode || 'comment';
this.options.form_xml_id = options.form_xml_id || 'email_compose_message_wizard_form_chatter';
this.options.form_view_id = false;
if (this.options.mode == 'reply') {
this.options.active_id = this.options.msg_id;
} else {
this.params.active_id = this.params.res_id;
this.options.active_id = this.options.res_id;
}
this.email_mode = false;
this.formatting = false;
@ -258,17 +168,17 @@ openerp.mail = function(session) {
this.$element.find('div.oe_mail_msg_content').empty();
// create a context for the default_get of the compose form
var widget_context = {
'active_model': this.params.res_model,
'active_id': this.params.active_id,
'mail.compose.message.mode': this.params.mode,
'active_model': this.options.res_model,
'active_id': this.options.active_id,
'mail.compose.message.mode': this.options.mode,
};
var context = _.extend({}, this.params.context, widget_context);
var context = _.extend({}, this.options.context, widget_context);
this.ds_compose = new session.web.DataSetSearch(this, 'mail.compose.message', context);
// find the id of the view to display in the chatter form
var data_ds = new session.web.DataSetSearch(this, 'ir.model.data');
var deferred_form_id =data_ds.call('get_object_reference', ['mail', this.params.form_xml_id]).then( function (result) {
var deferred_form_id =data_ds.call('get_object_reference', ['mail', this.options.form_xml_id]).then( function (result) {
if (result) {
self.params.form_view_id = result[1];
self.options.form_view_id = result[1];
}
}).pipe(this.proxy('create_form_view'));
return deferred_form_id;
@ -281,7 +191,7 @@ openerp.mail = function(session) {
// destroy previous form_view if any
if (this.form_view) { this.form_view.destroy(); }
// create the FormView
this.form_view = new session.web.FormView(this, this.ds_compose, this.params.form_view_id, {
this.form_view = new session.web.FormView(this, this.ds_compose, this.options.form_view_id, {
action_buttons: false,
pager: false,
initial_mode: 'edit',
@ -292,8 +202,8 @@ openerp.mail = function(session) {
return $.when(this.form_view.appendTo(msg_node)).pipe(function() {
self.bind_events();
self.form_view.do_show();
if (self.params.email_mode) { self.toggle_email_mode(); }
if (self.params.formatting) { self.toggle_formatting_mode(); }
if (self.options.email_mode) { self.toggle_email_mode(); }
if (self.options.formatting) { self.toggle_formatting_mode(); }
});
},
@ -343,7 +253,7 @@ openerp.mail = function(session) {
var self = this;
this.formatting = ! this.formatting;
// calls onchange
var call_defer = this.ds_compose.call('onchange_formatting', [[], this.formatting, this.params.res_model, this.params.res_id]).then(
var call_defer = this.ds_compose.call('onchange_formatting', [[], this.formatting, this.options.res_model, this.options.res_id]).then(
function (result) {
self.form_view.on_processed_onchange(result, []);
});
@ -361,7 +271,7 @@ openerp.mail = function(session) {
var self = this;
this.email_mode = ! this.email_mode;
// calls onchange
var call_defer = this.ds_compose.call('onchange_email_mode', [[], this.email_mode, this.params.res_model, this.params.res_id]).then(
var call_defer = this.ds_compose.call('onchange_email_mode', [[], this.email_mode, this.options.res_model, this.options.res_id]).then(
function (result) {
self.form_view.on_processed_onchange(result, []);
});
@ -410,63 +320,58 @@ openerp.mail = function(session) {
/**
* @param {Object} parent parent
* @param {Object} [params]
* @param {String} [params.res_model] res_model of document [REQUIRED]
* @param {Number} [params.res_id] res_id of record [REQUIRED]
* @param {Number} [params.uid] user id [REQUIRED]
* @param {Bool} [params.parent_id=false] parent_id of message
* @param {Number} [params.thread_level=0] number of levels in the thread
* @param {Object} [options]
* @param {String} [options.res_model] res_model of document [REQUIRED]
* @param {Number} [options.res_id] res_id of record [REQUIRED]
* @param {Number} [options.uid] user id [REQUIRED]
* @param {Bool} [options.parent_id=false] parent_id of message
* @param {Number} [options.thread_level=0] number of levels in the thread
* (only 0 or 1 currently)
* @param {Bool} [params.is_wall=false] thread is displayed in the wall
* @param {Number} [params.msg_more_limit=150] number of character to
* @param {Bool} [options.is_wall=false] thread is displayed in the wall
* @param {Number} [options.msg_more_limit=150] number of character to
* display before having a "show more" link; note that the text
* will not be truncated if it does not have 110% of the parameter
* (ex: 110 characters needed to be truncated and be displayed as
* a 100-characters message)
* @param {Number} [params.limit=100] maximum number of messages to fetch
* @param {Number} [params.offset=0] offset for fetching messages
* @param {Number} [params.records=null] records to show instead of fetching messages
* @param {Number} [options.limit=100] maximum number of messages to fetch
* @param {Number} [options.offset=0] offset for fetching messages
* @param {Number} [options.records=null] records to show instead of fetching messages
*/
init: function(parent, params) {
init: function(parent, options) {
this._super(parent);
// options
this.params = params;
this.params.parent_id = this.params.parent_id || false;
this.params.thread_level = this.params.thread_level || 0;
this.params.is_wall = this.params.is_wall || (this.params.records != undefined) || false;
this.params.msg_more_limit = this.params.msg_more_limit || 250;
this.params.limit = this.params.limit || 100;
// this.params.limit = 3; // tmp for testing
this.params.offset = this.params.offset || 0;
this.params.records = this.params.records || null;
this.options = options || {};
this.options.parent_id = this.options.parent_id || false;
this.options.thread_level = this.options.thread_level || 0;
this.options.fetch_limit = this.options.fetch_limit || 100;
this.options.records = this.options.records || null;
// datasets and internal vars
this.ds = new session.web.DataSetSearch(this, this.params.res_model);
this.ds = new session.web.DataSetSearch(this, this.options.res_model);
this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
// display customization vars
this.display = {};
this.display.show_post_comment = this.params.show_post_comment || false;
this.display.show_reply = (this.params.thread_level > 0 && this.params.is_wall);
this.display.show_delete = ! this.params.is_wall;
this.display.show_hide = this.params.is_wall;
this.display.show_reply_by_email = ! this.params.is_wall;
this.display.show_more = (this.params.thread_level == 0);
this.display.truncate_limit = this.options.truncate_limit || 250;
this.display.show_header_compose = this.options.show_header_compose || false; // only for thread record
this.display.show_reply = this.options.show_reply || true;
this.display.show_delete = this.options.show_delete || true;
this.display.show_hide = this.options.show_hide || true;
this.display.show_reply_by_email = this.options.show_reply_by_email || true;
this.display.show_more = this.options.show_more || true;
},
start: function() {
this._super.apply(this, arguments);
// add events
// bind events
this.bind_events();
// display user, fetch comments
this.display_current_user();
if (this.params.records) var display_done = this.display_comments_from_parameters(this.params.records);
if (this.options.records) var display_done = this.display_comments_from_parameters(this.options.records);
else var display_done = this.init_comments();
// customize display
$.when(display_done).then(this.proxy('do_customize_display'));
// add message composition form view
if (this.display.show_post_comment) {
if (this.display.show_header_compose) {
var compose_done = this.instantiate_composition_form();
}
return display_done && compose_done;
@ -488,8 +393,8 @@ openerp.mail = function(session) {
this.compose_message_widget.destroy();
}
this.compose_message_widget = new mail.ComposeMessage(this, {
'extended_mode': false, 'uid': this.params.uid, 'res_model': this.params.res_model,
'res_id': this.params.res_id, 'mode': mode || 'comment', 'msg_id': msg_id,
'extended_mode': false, 'uid': this.options.uid, 'res_model': this.options.res_model,
'res_id': this.options.res_id, 'mode': mode || 'comment', 'msg_id': msg_id,
'email_mode': email_mode || false, 'formatting': formatting || false,
'context': context || false } );
var composition_node = this.$element.find('div.oe_mail_thread_action');
@ -507,8 +412,6 @@ openerp.mail = function(session) {
* in the function. */
bind_events: function() {
var self = this;
// generic events from Chatter Mixin
mail.ChatterUtils.bind_events(this);
// event: click on 'more' at bottom of thread
this.$element.find('button.oe_mail_button_more').click(function () {
self.do_more();
@ -568,24 +471,22 @@ openerp.mail = function(session) {
});
},
destroy: function () {
this._super.apply(this, arguments);
},
init_comments: function() {
var self = this;
this.params.offset = 0;
this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
// TDE: not necessary
// this.params.offset = 0;
// this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
this.$element.find('div.oe_mail_thread_display').empty();
var domain = this.get_fetch_domain(this.comments_structure);
return this.fetch_comments(this.params.limit, this.params.offset, domain).then();
// var domain = this.get_fetch_domain(this.comments_structure);
return this.fetch_comments(this.options.limit, this.options.offset, domain).then();
},
fetch_comments: function (limit, offset, domain) {
var self = this;
var defer = this.ds.call('message_read', [[this.params.res_id], (this.params.thread_level > 0), (this.comments_structure['root_ids']),
(limit+1) || (this.params.limit+1), offset||this.params.offset, domain||undefined ]).then(function (records) {
if (records.length <= self.params.limit) self.display.show_more = false;
var defer = this.ds.call('message_read', [[this.options.res_id], (this.options.thread_level > 0), (this.comments_structure['root_ids']),
(limit+1) || (this.options.limit+1), offset||this.options.offset, domain||undefined ]).then(function (records) {
if (records.length <= self.options.limit) self.display.show_more = false;
// else { self.display.show_more = true; records.pop(); }
// else { self.display.show_more = true; records.splice(0, 1); }
else { self.display.show_more = true; }
@ -624,7 +525,7 @@ openerp.mail = function(session) {
}
_(records).each(function (record) {
var sub_msgs = [];
if ((record.parent_id == undefined || record.parent_id == false || record.parent_id[0] == self.params.parent_id) && self.params.thread_level > 0 ) {
if ((record.parent_id == undefined || record.parent_id == false || record.parent_id[0] == self.options.parent_id) && self.options.thread_level > 0 ) {
// var sub_list = self.comments_structure['tree_struct'][record.id]['direct_childs'];
// _(records).each(function (record) {
// //if (record.parent_id == false || record.parent_id[0] == self.params.parent_id) return;
@ -633,19 +534,19 @@ openerp.mail = function(session) {
// }
// });
self.display_comment(record);
self.thread = new mail.Thread(self, {'res_model': self.params.res_model, 'res_id': self.params.res_id, 'uid': self.params.uid,
'records': sub_msgs, 'thread_level': (self.params.thread_level-1), 'parent_id': record.id,
'is_wall': self.params.is_wall});
self.thread = new mail.Thread(self, {'res_model': self.options.res_model, 'res_id': self.options.res_id, 'uid': self.options.uid,
'records': record.child_ids, 'thread_level': (self.options.thread_level-1), 'parent_id': record.id,
'is_wall': self.options.is_wall});
self.$element.find('li.oe_mail_thread_msg:last').append('<div class="oe_mail_thread_subthread"/>');
self.thread.appendTo(self.$element.find('div.oe_mail_thread_subthread:last'));
}
else if (self.params.thread_level == 0) {
else if (self.options.thread_level == 0) {
self.display_comment(record);
}
});
// mail.ChatterUtils.records_struct_update_after_display(this.comments_structure);
// update offset for "More" buttons
if (this.params.thread_level == 0) this.params.offset += records.length;
if (this.options.thread_level == 0) this.options.offset += records.length;
},
/** Displays a record, performs text/link formatting */
@ -662,11 +563,11 @@ openerp.mail = function(session) {
// is the user the author ?
record.is_author = mail.ChatterUtils.is_author(this, record.author_id[0]);
// render
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'params': this.params, 'display': this.display});
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'params': this.options, 'display': this.display});
// expand feature
$(rendered).appendTo(this.$element.children('div.oe_mail_thread_display:first'));
this.$element.find('div.oe_mail_msg_record_body').expander({
slicePoint: this.params.msg_more_limit,
slicePoint: this.options.msg_more_limit,
expandText: 'read more',
userCollapseText: '[^]',
detailClass: 'oe_mail_msg_tail',
@ -676,7 +577,7 @@ openerp.mail = function(session) {
},
display_current_user: function () {
var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', this.params.uid);
var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', this.options.uid);
return this.$element.find('img.oe_mail_icon').attr('src', avatar);
},
@ -684,7 +585,7 @@ openerp.mail = function(session) {
var comment_node = this.$element.find('textarea');
var body = comment_node.val();
comment_node.val('');
return this.ds.call('message_post', [[this.params.res_id], body], {parent_id: this.params.parent_id, mtype: 'comment'}).then(
return this.ds.call('message_post', [[this.options.res_id], body], {parent_id: this.options.parent_id, mtype: 'comment'}).then(
this.proxy('init_comments'));
},
@ -699,13 +600,13 @@ openerp.mail = function(session) {
var ids = comments_structure.root_ids.slice();
var ids2 = [];
// must be child of current parent
if (this.params.parent_id) { domain.push(['id', 'child_of', this.params.parent_id]); }
if (this.options.parent_id) { domain.push(['id', 'child_of', this.options.parent_id]); }
_(comments_structure.root_ids).each(function (id) { // each record
ids.push(id);
ids2.push(id);
});
if (this.params.parent_id != false) {
ids2.push(this.params.parent_id);
if (this.options.parent_id != false) {
ids2.push(this.options.parent_id);
}
// must not be children of already fetched messages
if (ids.length > 0) {
@ -721,7 +622,7 @@ openerp.mail = function(session) {
do_more: function () {
domain = this.get_fetch_domain(this.comments_structure);
return this.fetch_comments(this.params.limit, this.params.offset, domain);
return this.fetch_comments(this.options.limit, this.options.offset, domain);
},
});
@ -754,7 +655,6 @@ openerp.mail = function(session) {
// any other method to know if the view is in create mode anymore
this.view.on("change:actual_mode", this, this._check_visibility);
this._check_visibility();
mail.ChatterUtils.bind_events(this);
},
_check_visibility: function() {
@ -807,49 +707,37 @@ openerp.mail = function(session) {
*/
init: function (parent, options) {
this._super(parent);
// console.log(options);
this.options = options || {};
this.options.domain = options.domain || [];
this.options.context = options.context || {};
// FP Note: do we need this ? --> not sure, use mail.message create instead ?
// Should be in domain/context instead ?
this.options.context.res_model = options.res_model || 'mail.thread';
this.options.context.res_id = options.res_id || false;
this.options.thread_level = options.thread_level || 1;
this.thread_list = [];
this.ds_msg = new session.web.DataSet(this, 'mail.message');
// for search view
this.search = {'domain': [], 'context': {}, 'groupby': {}}
this.search_results = {'domain': [], 'context': {}, 'groupby': {}}
// datasets
this.ds_msg = new session.web.DataSet(this, 'mail.message');
// this.ds_post = new session.web.DataSet(this, this.options.context.res_model);
},
start: function () {
this._super.apply(this, arguments);
// add events
this.add_event_handlers();
this.bind_events();
// load mail.message search view
var search_view_ready = this.load_search_view({}, false);
// load composition form
var compose_done = this.instantiate_composition_form();
// fetch first threads
var comments_ready = this.init_and_fetch_comments(this.options.limit, 0);
return (search_view_ready && comments_ready && compose_done);
},
/**
* Override-hack of do_action: automatically reload the chatter.
* Normally it should be called only when clicking on 'Post/Send'
* in the composition form. */
do_action: function(action, on_close) {
this.init_and_fetch_comments();
if (this.compose_message_widget) {
this.compose_message_widget.reinit(); }
return this._super(action, on_close);
var messages_fetched = this.message_fetch();
return (search_view_ready && compose_done && messages_fetched);
},
destroy: function () {
this._super.apply(this, arguments);
if (this.thread_list) {
// #TODO: destroy threads
}
},
instantiate_composition_form: function(mode, msg_id) {
@ -865,24 +753,36 @@ openerp.mail = function(session) {
return compose_done;
},
/** Add events */
add_event_handlers: function () {
/**
* Override-hack of do_action: automatically reload the chatter.
* Normally it should be called only when clicking on 'Post/Send'
* in the composition form. */
do_action: function(action, on_close) {
if (this.compose_message_widget) {
this.compose_message_widget.reinit(); }
this.message_clean();
this.message_fetch();
return this._super(action, on_close);
},
/** Bind events */
bind_events: function () {
var self = this;
// display more threads
this.$element.find('button.oe_mail_wall_button_more').click(function () { return self.do_more(); });
// Click on 'show more'
this.$element.find('button.oe_mail_wall_button_more').click(function () {
return self.do_fetch_more();
});
},
/**
* Loads the mail.message search view
* @param {Number} view_id id of the search view to load
* Load the mail.message search view
* @param {Object} defaults ??
* @param {Boolean} hidden some kind of trick we do not care here
*/
load_search_view: function (defaults, hidden) {
var self = this;
this.searchview = new session.web.SearchView(this, this.ds_msg, false, defaults || {}, hidden || false);
var search_view_loaded = this.searchview.appendTo(this.$element.find('.oe_view_manager_view_search'));
return $.when(search_view_loaded).then(function () {
return this.searchview.appendTo(this.$element.find('.oe_view_manager_view_search')).then(function () {
self.searchview.on_search.add(self.do_searchview_search);
});
},
@ -905,86 +805,70 @@ openerp.mail = function(session) {
self.search_results['context'] = results.context;
self.search_results['domain'] = results.domain;
self.search_results['groupby'] = results.group_by;
return self.init_and_fetch_comments();
self.message_clean();
return self.message_fetch();
});
},
/**
* Initializes the wall and calls fetch_comments
* @param {Number} limit: number of notifications to fetch
* @param {Number} offset: offset in notifications search
* @param {Array} domain
* @param {Array} context
*/
init_and_fetch_comments: function() {
this.search['domain'] = _.union(this.options.domain, this.search_results.domain);
this.search['context'] = _.extend(this.options.context, this.search_results.context);
// this.comments_structure = {'root_ids': [], 'new_root_ids': [], 'msgs': {}, 'tree_struct': {}, 'model_to_root_ids': {}};
/** Clean the wall */
message_clean: function() {
this.$element.find('ul.oe_mail_wall_threads').empty();
return this.fetch_comments(this.options.limit);
},
/**
* Fetches wall messages
* @param {Number} limit: number of notifications to fetch
* @param {Number} offset: offset in notifications search
/** Fetch messages
* @param {Array} domain
* @param {Array} context
*/
fetch_comments: function (limit, additional_domain, additional_context) {
var self = this;
message_fetch: function (additional_domain, additional_context) {
this.search['domain'] = _.union(this.options.domain, this.search_results.domain);
this.search['context'] = _.extend(this.options.context, this.search_results.context);
if (additional_domain) var fetch_domain = this.search['domain'].concat(additional_domain);
else var fetch_domain = this.search['domain'];
if (additional_context) var fetch_context = _.extend(this.search['context'], additional_context);
else var fetch_context = this.search['context'];
// FP Note: call to review
return this.ds_msg.call('message_read',
[[this.session.uid], false, [] ]).then(this.proxy('display_comments'));
return this.ds_msg.call('message_read',
[false, fetch_domain, this.options.thread_level, fetch_context]
).then(this.proxy('display_comments'));
},
/**
* @param {Array} records records to show in threads
/** Display comments
* @param {Array} records tree structure of records
*/
display_comments: function (records) {
console.log(records);
// debugger
var self = this;
this.do_update_show_more(records.length >= self.options.limit);
var _expendable = false;
_(records).each(function (root_record) {
console.log(root_record);
var render_res = session.web.qweb.render('mail.wall_thread_container', {});
$('<li class="oe_mail_wall_thread">').html(render_res).appendTo(self.$element.find('ul.oe_mail_wall_threads'));
var thread = new mail.Thread(self, {
'res_model': root_record.model, 'res_id': root_record.res_id, 'uid': self.session.uid, 'records': [root_record],
'parent_id': false, 'thread_level': self.options.thread_level, 'show_hide': true, 'is_wall': true}
/* expandable type: add a 'Show more button' */
if (root_record.type == 'expandable') {
_expendable = true;
self.update_fetch_more(true);
self.fetch_more_domain = root_record.domain;
self.fetch_more_context = root_record.context;
}
// display classic root record
else {
var render_res = session.web.qweb.render('mail.wall_thread_container', {});
$('<li class="oe_mail_wall_thread">').html(render_res).appendTo(self.$element.find('ul.oe_mail_wall_threads'));
var thread = new mail.Thread(self, {
'res_model': root_record.model, 'res_id': root_record.res_id,
'uid': self.session.uid, 'records': [root_record],
'parent_id': false, 'thread_level': self.options.thread_level,
'show_hide': true, 'is_wall': true
}
);
self.thread_list.push(thread);
return thread.appendTo(self.$element.find('li.oe_mail_wall_thread:last'));
self.thread_list.push(thread);
thread.appendTo(self.$element.find('li.oe_mail_wall_thread:last'));
}
});
},
/**
* Create a domain to fetch new comments according to
* comments already present in comments_structure
* - for each model:
* -- should not be child of already displayed ids
* @returns {Array} fetch_domain (OpenERP domain style)
*/
get_fetch_domain: function () {
var self = this;
var model_to_root = {};
var fetch_domain = [];
// _(this.comments_structure['model_to_root_ids']).each(function (sc_model, model_name) {
// fetch_domain.push('|', ['model', '!=', model_name], '!', ['id', 'child_of', sc_model]);
// });
return fetch_domain;
if (! _expendable) {
self.update_fetch_more(false);
}
},
/** Display update: show more button */
do_update_show_more: function (new_value) {
/** Display 'show more' button */
update_fetch_more: function (new_value) {
if (new_value) {
this.$element.find('div.oe_mail_wall_more:last').show();
} else {
@ -992,10 +876,9 @@ openerp.mail = function(session) {
}
},
/** Action: Shows more discussions */
do_more: function () {
var domain = this.get_fetch_domain();
return this.fetch_comments(this.params.limit, 0, domain);
/** Action: 'shows more' to fetch new messages */
do_fetch_more: function () {
return this.message_fetch(this.fetch_more_domain, this.fetch_more_context);
},
});
};