diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 296c212e0fb..f9406699190 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -886,9 +886,9 @@ class mail_thread(osv.AbstractModel): return mail_message.create(cr, uid, values, context=context) - def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, - attachment_ids=None, context=None, content_subtype='plaintext', - extra_email=[], **kwargs): + def message_post_user_api(self, cr, uid, thread_id, body='', parent_id=False, + attachment_ids=None, extra_emails=None, content_subtype='plaintext', + context=None, **kwargs): """ Wrapper on message_post, used for user input : - mail gateway - quick reply in Chatter (refer to mail.js), not @@ -902,30 +902,41 @@ class mail_thread(osv.AbstractModel): to the related document. Should only be set by Chatter. - extra_email: [ 'Fabien ', 'al@openerp.com' ] """ + partner_obj = self.pool.get('res.partner') + mail_message_obj = self.pool.get('mail.message') ir_attachment = self.pool.get('ir.attachment') + extra_emails = extra_emails or [] - # 1. Pre-processing: body, partner_ids, type and subtype - if content_subtype == 'plaintext': - body = tools.plaintext2html(body) + # 1.A.1: pre-process partners and incoming extra_emails + partner_ids = set([]) + for email in extra_emails: + partner_id = partner_obj.find_or_create(cr, uid, email, context=context) + # link mail with this from mail to the new partner id + partner_msg_ids = mail_message_obj.search(cr, SUPERUSER_ID, [('email_from', '=', email), ('author_id', '=', False)], context=context) + if partner_id and partner_msg_ids: + mail_message_obj.write(cr, SUPERUSER_ID, partner_msg_ids, {'email_from': None, 'author_id': partner_id}, context=context) + partner_ids.add((4, partner_id)) + if partner_ids: + self.message_subscribe(cr, uid, [thread_id], [item[1] for item in partner_ids], context=context) - for partner in extra_email: - part_ids = self.pool.get('res.partner').search(cr, uid, [('email', '=', partner)], context=context) - if not part_ids: - part_ids = [self.pool.get('res.partner').name_create(cr, uid, partner, context=context)[0]] - self.message_subscribe(cr, uid, [thread_id], part_ids, context=context) - - partner_ids = kwargs.pop('partner_ids', []) + # 1.A.2: add recipients of parent message if parent_id: - parent_message = self.pool.get('mail.message').browse(cr, uid, parent_id, context=context) - partner_ids += [(4, partner.id) for partner in parent_message.partner_ids] + parent_message = mail_message_obj.browse(cr, uid, parent_id, context=context) + partner_ids |= set([(4, partner.id) for partner in parent_message.partner_ids]) # TDE FIXME HACK: mail.thread -> private message if self._name == 'mail.thread' and parent_message.author_id.id: - partner_ids.append((4, parent_message.author_id.id)) + partner_ids.add((4, parent_message.author_id.id)) - message_type = kwargs.pop('type', 'comment') - message_subtype = kwargs.pop('subtype', 'mail.mt_comment') + # 1.A.3: add specified recipients + partner_ids |= set(kwargs.pop('partner_ids', [])) - # 2. Pre-processing: free attachments linked to the model + # 1.B: handle body, message_type and message_subtype + if content_subtype == 'plaintext': + body = tools.plaintext2html(body) + msg_type = kwargs.pop('type', 'comment') + msg_subtype = kwargs.pop('subtype', 'mail.mt_comment') + + # 2. Pre-processing: attachments # HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message if attachment_ids: # TDE FIXME (?): when posting a private message, we use mail.thread as a model @@ -943,13 +954,12 @@ class mail_thread(osv.AbstractModel): ir_attachment.write(cr, SUPERUSER_ID, attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context) else: attachment_ids = [] + attachment_ids = [(4, id) for id in attachment_ids] # 3. Post message - new_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=message_type, - subtype=message_subtype, parent_id=parent_id, attachment_ids=[(4, id) for id in attachment_ids], - context=context, partner_ids=partner_ids, **kwargs) - - return new_message_id + return self.message_post(cr, uid, thread_id=thread_id, body=body, + type=msg_type, subtype=msg_subtype, parent_id=parent_id, + attachment_ids=attachment_ids, partner_ids=partner_ids, context=context, **kwargs) #------------------------------------------------------ # Followers API @@ -969,7 +979,12 @@ class mail_thread(osv.AbstractModel): def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None): """ Add partners to the records followers. """ - self.check_access_rights(cr, uid, 'read') + user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] + if set(partner_ids) == set([user_pid]): + self.check_access_rights(cr, uid, 'read') + else: + self.check_access_rights(cr, uid, 'write') + self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) # if subtypes are not specified (and not set to a void list), fetch default ones if subtype_ids is None: @@ -991,7 +1006,11 @@ class mail_thread(osv.AbstractModel): def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None): """ Remove partners from the records followers. """ - self.check_access_rights(cr, uid, 'read') + user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] + if set(partner_ids) == set([user_pid]): + self.check_access_rights(cr, uid, 'read') + else: + self.check_access_rights(cr, uid, 'write') return self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context) def message_subscribe_from_parent(self, cr, uid, ids, updated_fields, context=None): diff --git a/addons/mail/res_partner.py b/addons/mail/res_partner.py index cf9a2272a98..cfcb1106afc 100644 --- a/addons/mail/res_partner.py +++ b/addons/mail/res_partner.py @@ -42,8 +42,7 @@ class res_partner_mail(osv.Model): 'notification_email_send': lambda *args: 'comment' } - def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', - subtype=None, parent_id=False, attachments=None, context=None, **kwargs): + def message_post(self, cr, uid, thread_id, **kwargs): """ Override related to res.partner. In case of email message, set it as private: - add the target partner in the message partner_ids @@ -58,7 +57,6 @@ class res_partner_mail(osv.Model): partner_ids.append((4, thread_id)) kwargs['partner_ids'] = partner_ids thread_id = False - return super(res_partner_mail, self).message_post(cr, uid, thread_id, body=body, subject=subject, - type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, **kwargs) + return super(res_partner_mail, self).message_post(cr, uid, thread_id, **kwargs) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py index 4c6bf6e150d..160335fba2a 100644 --- a/addons/mail/res_users.py +++ b/addons/mail/res_users.py @@ -116,32 +116,26 @@ class res_users(osv.Model): alias_pool.unlink(cr, uid, alias_ids, context=context) return res - def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, - attachment_ids=None, context=None, content_subtype='plaintext', **kwargs): - """ Redirect the posting of message on res.users to the related partner. - This is done because when giving the context of Chatter on the - various mailboxes, we do not have access to the current partner_id. - We therefore post on the user and redirect on its partner. """ + def _message_post_get_pid(self, cr, uid, thread_id, context=None): assert thread_id, "res.users does not support posting global messages" if context and 'thread_model' in context: context['thread_model'] = 'res.partner' if isinstance(thread_id, (list, tuple)): thread_id = thread_id[0] - partner_id = self.browse(cr, uid, thread_id).partner_id.id - return self.pool.get('res.partner').message_post_user_api(cr, uid, partner_id, body=body, subject=subject, - parent_id=parent_id, attachment_ids=attachment_ids, context=context, content_subtype=content_subtype, **kwargs) + return self.browse(cr, uid, thread_id).partner_id.id + + def message_post_user_api(self, cr, uid, thread_id, context=None, **kwargs): + """ Redirect the posting of message on res.users to the related partner. + This is done because when giving the context of Chatter on the + various mailboxes, we do not have access to the current partner_id. """ + partner_id = self._message_post_get_pid(cr, uid, thread_id, context=context) + return self.pool.get('res.partner').message_post_user_api(cr, uid, partner_id, context=context, **kwargs) def message_post(self, cr, uid, thread_id, context=None, **kwargs): """ Redirect the posting of message on res.users to the related partner. This is done because when giving the context of Chatter on the - various mailboxes, we do not have access to the current partner_id. - We therefore post on the user and redirect on its partner. """ - assert thread_id, "res.users does not support posting global messages" - if context and 'thread_model' in context: - context['thread_model'] = 'res.partner' - if isinstance(thread_id, (list, tuple)): - thread_id = thread_id[0] - partner_id = self.browse(cr, uid, thread_id).partner_id.id + various mailboxes, we do not have access to the current partner_id. """ + partner_id = self._message_post_get_pid(cr, uid, thread_id, context=context) return self.pool.get('res.partner').message_post(cr, uid, partner_id, context=context, **kwargs) def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None): diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index e154e285f39..54f97f448f4 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -253,6 +253,19 @@ .openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{ display: block; } +.openerp .oe_mail .oe_msg_composer .oe_emails_from{ + font-size: 12px; + margin-left: 20px; + margin-bottom: 2px; +} +.openerp .oe_mail .oe_msg_composer .oe_emails_from label{ + vertical-align: middle; + display: block; + line-height: 14px; +} +.openerp .oe_mail .oe_msg_composer .oe_emails_from input{ + vertical-align: middle; +} .openerp .oe_mail .oe_attachment{ display: inline-block; width: 100px; @@ -465,8 +478,8 @@ } .openerp .oe_mail .oe_msg_content .oe_mail_list_recipients{ font-size: 12px; - margin-top: 4px; - margin-bottom: 4px; + margin: 4px 0 4px 20px; + text-indent: -20px; } /* ---------------- HIDDEN MESSAGES ------------------ */ @@ -578,6 +591,14 @@ margin-right:4px; border-radius: 2px; } +.openerp .oe_followers .oe_remove_follower{ + cursor: pointer; + float: right; +} + +.openerp .oe_followers .oe_show_more{ + cursor: pointer; +} /* ---------------- MESSAGES BODY ------------------ */ .openerp .oe_mail .oe_msg_content .oe_blockquote, diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 03d13a5605b..29a2e076b19 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -369,6 +369,7 @@ openerp.mail = function (session) { this._super(parent, datasets, options); this.show_compact_message = false; this.show_delete_attachment = true; + this.emails_from = []; }, start: function () { @@ -478,9 +479,11 @@ openerp.mail = function (session) { this.$('.oe_cancel').on('click', _.bind( this.on_cancel, this) ); this.$('.oe_post').on('click', _.bind( this.on_message_post, this) ); this.$('.oe_full').on('click', _.bind( this.on_compose_fullmail, this, this.id ? 'reply' : 'comment') ); - + /* stack for don't close the compose form if the user click on a button */ - this.$('.oe_msg_footer').on('mousedown', _.bind( function () { this.stay_open = true; }, this)); + this.$('.oe_msg_left, .oe_msg_center').on('mousedown', _.bind( function () { this.stay_open = true; }, this)); + this.$('.oe_msg_left, .oe_msg_content').on('mouseup', _.bind( function () { this.$('textarea').focus(); }, this)); + var ev_stay = {}; ev_stay.mouseup = ev_stay.keydown = ev_stay.focus = function () { self.stay_open = false; }; this.$('textarea:not(.oe_compact)').on(ev_stay); @@ -491,6 +494,8 @@ openerp.mail = function (session) { // event: delete child attachments off the oe_msg_attachment_list box this.$(".oe_msg_attachment_list").on('click', '.oe_delete', this.on_attachment_delete); + + this.$(".oe_emails_from").on('change', 'input', this.on_checked_email_from); }, on_compose_fullmail: function (default_composition_mode) { @@ -559,46 +564,79 @@ openerp.mail = function (session) { } }, - /*post a message and fetch the message*/ + check_recipient_partners: function (emails) { + var self = this; + var deferreds = []; + var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); + _.each(emails, function (email) { + ds_partner.call('search', [[['email', '=', email]]]).then(function (partner_ids) { + if (!partner_ids.length) { + var deferred = $.Deferred(); + var pop = new session.web.form.FormOpenPopup(this); + pop.show_element( + 'res.partner', + 0, + { + 'default_email': email, + 'force_email': true, + 'ref': "compound_context", + }, + { + title: _t("Please complete partner's informations"), + } + ); + pop.on('write_completed, closed', self, function () { + deferred.resolve(); + }); + deferreds.push(deferred); + } + }); + }); + return $.when.apply( $, deferreds ); + }, + on_message_post: function (event) { var self = this; - - var comment_node = this.$('textarea'); - var body = comment_node.val(); - - if (this.do_check_attachment_upload() && (this.attachment_ids.length || body.match(/\S+/))) { - //session.web.blockUI(); - this.parent_thread.ds_thread.call('message_post_user_api', [ - this.context.default_res_id, - body, - false, - this.context.default_parent_id, - _.map(this.attachment_ids, function (file) {return file.id;}), - this.parent_thread.context - ]).done(function (record) { - var thread = self.parent_thread; - var root = thread == self.options.root_thread; - if (self.options.display_indented_thread < self.thread_level && thread.parent_message) { - var thread = thread.parent_message.parent_thread; - } - // create object and attach to the thread object - thread.message_fetch([['id', 'child_of', [self.id]]], false, [record], function (arg, data) { - var message = thread.create_message_object( data[0] ); - // insert the message on dom - thread.insert_message( message, root ? undefined : self.$el, root ); - }); - self.on_cancel(); - //session.web.unblockUI(); - }); - return true; + if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { + // create list of new partners + var extra_email = _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}); + this.check_recipient_partners(extra_email).done(function () { + self.do_send_message_post(); + }); } }, + /*do post a message and fetch the message*/ + do_send_message_post: function () { + var self = this; + this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], { + 'body': this.$('textarea').val(), + 'subject': false, + 'parent_id': this.context.default_parent_id, + 'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}), + 'extra_emails': _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}), + 'context': this.parent_thread.context, + }).done(function (message_id) { + var thread = self.parent_thread; + var root = thread == self.options.root_thread; + if (self.options.display_indented_thread < self.thread_level && thread.parent_message) { + var thread = thread.parent_message.parent_thread; + } + // create object and attach to the thread object + thread.message_fetch([["id", "=", message_id]], false, [message_id], function (arg, data) { + var message = thread.create_message_object( data[0] ); + // insert the message on dom + thread.insert_message( message, root ? undefined : self.$el, root ); + }); + self.on_cancel(); + }); + }, + /* convert the compact mode into the compose message */ on_compose_expandable: function (event) { - - if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/))) { + this.get_emails_from(); + if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/) && !this.attachment_ids.length)) { this.show_composer = !this.show_composer || this.stay_open; this.reinit(); } @@ -620,6 +658,41 @@ openerp.mail = function (session) { if (!this.show_composer) { this.reinit(); } + }, + + get_emails_from: function () { + var self = this; + var messages = []; + + if (this.parent_thread.parent_message) { + // go to the parented message + var message = this.parent_thread.parent_message; + var parent_message = message.parent_id ? message.parent_thread.parent_message : message; + var messages = [parent_message].concat(parent_message.get_childs()); + } else if (this.options.emails_from_on_composer) { + // get all wall messages if is not a mail.Wall + _.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());}); + } + + var emails_from = _.map(_.filter(messages, + function (thread) {return thread.author_id && !thread.author_id[0];}), + function (thread) {return thread.author_id[1];}); + + return _.each(emails_from, function (email_from) { + if (!_.find(self.emails_from, function (from) {return from[0] == email_from;})) { + self.emails_from.push([email_from, true]); + } + }); + }, + + on_checked_email_from: function (event) { + var $input = $(event.target); + var email = $input.attr("data"); + _.each(this.emails_from, function (email_from) { + if (email_from[0] == email) { + email_from[1] = $input.is(":checked"); + } + }); } }); @@ -982,9 +1055,11 @@ openerp.mail = function (session) { this.is_private = datasets.is_private || false; this.author_id = datasets.author_id || false; this.thread_level = (datasets.thread_level+1) || 0; - this.partner_ids = datasets.partner_ids || []; - if (datasets.author_id) - this.partner_ids.push(datasets.author_id); + datasets.partner_ids = datasets.partner_ids || []; + if (datasets.author_id && ! _.contains(datasets.partner_ids, datasets.author_id) && datasets.author_id[0]) { + datasets.partner_ids.push(datasets.author_id); + } + this.partner_ids = datasets.partner_ids; this.messages = []; this.options.flat_mode = !!(this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0); @@ -1450,6 +1525,7 @@ openerp.mail = function (session) { 'message_ids': undefined, 'compose_as_todo' : false, 'readonly' : false, + 'emails_from_on_composer': true, }, this.action.params); this.action.params.help = this.action.help || false; @@ -1490,7 +1566,7 @@ openerp.mail = function (session) { $(window).resize( _.bind(this.thread.on_scroll, this.thread) ); this.$el.resize( _.bind(this.thread.on_scroll, this.thread) ); window.setTimeout( _.bind(this.thread.on_scroll, this.thread), 500 ); - } + }, }); @@ -1527,6 +1603,10 @@ openerp.mail = function (session) { } this.domain = this.node.params && this.node.params.domain || []; + + if (!this.__parentedParent.is_action_enabled('edit')) { + this.node.params.show_link = false; + } }, start: function () { @@ -1615,6 +1695,7 @@ openerp.mail = function (session) { 'show_record_name': true, 'show_compact_message': this.action.params.view_mailbox ? false : 1, 'view_inbox': false, + 'emails_from_on_composer': false, }, this.action.params); }, diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 0645c2b9225..1e481271eda 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -26,12 +26,16 @@ openerp_mail_followers = function(session, mail) { this._super.apply(this, arguments); this.image = this.node.attrs.image || 'image_small'; this.comment = this.node.attrs.help || false; - this.displayed_nb = this.node.attrs.displayed_nb || 10; + this.displayed_limit = this.node.attrs.displayed_nb || 10; + this.displayed_nb = this.displayed_limit; this.ds_model = new session.web.DataSetSearch(this, this.view.model); this.ds_follow = new session.web.DataSetSearch(this, this.field.relation); this.ds_users = new session.web.DataSetSearch(this, 'res.users'); this.value = []; + this.followers = []; + + this.view_is_editable = this.__parentedParent.is_action_enabled('edit'); }, start: function() { @@ -69,29 +73,47 @@ openerp_mail_followers = function(session, mail) { // event: click on a subtype, that (un)subscribe for this subtype this.$el.on('click', '.oe_subtype_list input', self.do_update_subscription); // event: click on 'invite' button, that opens the invite wizard - this.$('.oe_invite').on('click', function (event) { - action = { - type: 'ir.actions.act_window', - res_model: 'mail.wizard.invite', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: { - 'default_res_model': self.view.dataset.model, - 'default_res_id': self.view.datarecord.id, - }, - } - self.do_action(action, { - on_close: function() { - self.read_value(); - }, - }); + this.$('.oe_invite').on('click', self.on_invite_follower); + this.$el.on('click', '.oe_remove_follower', self.on_remove_follower); + this.$el.on('click', '.oe_show_more', self.on_show_more_followers) + }, + + on_invite_follower: function (event) { + var self = this; + var action = { + type: 'ir.actions.act_window', + res_model: 'mail.wizard.invite', + view_mode: 'form', + view_type: 'form', + views: [[false, 'form']], + target: 'new', + context: { + 'default_res_model': this.view.dataset.model, + 'default_res_id': this.view.datarecord.id, + }, + } + this.do_action(action, { + on_close: function() { + self.read_value(); + }, }); }, + on_show_more_followers: function (event) { + this.displayed_nb += this.displayed_limit; + this.display_followers(false); + }, + + on_remove_follower: function (event) { + var partner_id = $(event.target).data('id'); + var context = new session.web.CompoundContext(this.build_context(), {}); + return this.ds_model.call('message_unsubscribe', [[this.view.datarecord.id], [partner_id], context]) + .then(this.proxy('read_value')); + }, + read_value: function () { var self = this; + this.displayed_nb = this.displayed_limit; return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).then(function (results) { self.value = results[0].message_follower_ids; self.render_value(); @@ -145,20 +167,20 @@ openerp_mail_followers = function(session, mail) { /** Display the followers */ display_followers: function (records) { var self = this; - records = records || []; - this.message_is_follower = this.set_is_follower(records); + this.followers = records || this.followers; + this.message_is_follower = this.set_is_follower(this.followers); // clean and display title var node_user_list = this.$('.oe_follower_list').empty(); - this.$('.oe_follower_title').html(this._format_followers(records.length)); + this.$('.oe_follower_title').html(this._format_followers(this.followers.length)); // truncate number of displayed followers - truncated = records.splice(0, this.displayed_nb); + var truncated = this.followers.slice(0, this.displayed_nb); _(truncated).each(function (record) { record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id); - $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list); + $(session.web.qweb.render('mail.followers.partner', {'record': record, 'widget': self})).appendTo(node_user_list); }); // FVA note: be sure it is correctly translated - if (truncated.length < records.length) { - $('
And ' + (records.length - truncated.length) + ' more.
').appendTo(node_user_list); + if (truncated.length < this.followers.length) { + $(session.web.qweb.render('mail.followers.show_more', {'number': (this.followers.length - truncated.length)} )).appendTo(node_user_list); } }, @@ -196,18 +218,23 @@ openerp_mail_followers = function(session, mail) { var subtype_list_ul = this.$('.oe_subtype_list'); subtype_list_ul.empty(); var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data; - _(records).each(function (record, record_name) { - record.name = record_name; - record.followed = record.followed || undefined; - $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') ); - }); + if (records.length > 1) { + _(records).each(function (record, record_name) { + record.name = record_name; + record.followed = record.followed || undefined; + $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') ); + }); + } }, do_follow: function () { - _(this.$('.oe_msg_subtype_check')).each(function (record) { + var context = new session.web.CompoundContext(this.build_context(), {}); + this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], undefined, context]) + .then(this.proxy('read_value')); + + _.each(this.$('.oe_subtype_list input'), function (record) { $(record).attr('checked', 'checked'); }); - this.do_update_subscription(); }, do_unfollow: function () { @@ -229,9 +256,13 @@ openerp_mail_followers = function(session, mail) { } }); - var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], this.message_is_follower ? checklist : undefined, context]) - .then(this.proxy('read_value')); + if (!checklist.length) { + this.do_unfollow(); + } else { + var context = new session.web.CompoundContext(this.build_context(), {}); + return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], checklist, context]) + .then(this.proxy('read_value')); + } }, }); }; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 3c510813029..4b3c31525d4 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -79,7 +79,7 @@
-
[
+
[
uploading
@@ -91,7 +91,7 @@
-
[
+
[
uploading
@@ -113,19 +113,28 @@ this document - and + and - + - + + - - , others... + + , others... <<< +
+ + + +