From 4afb6563908d4071c32e9a19fc20c25ac086be2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 29 Oct 2012 15:57:29 +0100 Subject: [PATCH 01/82] [IMP] css: better design for 'likes'. previous one was meh bzr revid: fva@openerp.com-20121029145729-bo35rt2dvedf1f6g --- addons/mail/static/src/css/mail.css | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index af3cc3ed359..86fcd7832dc 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -80,18 +80,21 @@ .openerp .oe_mail .oe_msg.oe_msg_indented .oe_msg_content{ padding-top:2px; } + /* b) Votes (likes) */ + .openerp .oe_mail .oe_mail_vote_count{ display: inline; position: relative; - background: #7C7BAD; - color: white; + background: white; + box-shadow: 0px 0px 0px 1px rgba(124, 123, 173, 0.36) inset; + color: #7c7bad; text-shadow: none; border-radius: 3px; margin: 0px; padding-left: 3px; - padding-right: 18px; - margin-right: 3px; + padding-right: 15px; + margin-right: 5px; } .openerp .oe_mail .oe_mail_vote_count .oe_e{ position: absolute; From 2447ed07a75bde52ec644c8236242ac6cb15ea8f Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 29 Oct 2012 16:13:27 +0100 Subject: [PATCH 02/82] [FIX] mail: display vote bzr revid: chm@openerp.com-20121029151327-cptuukjtkrh06bij --- addons/mail/static/src/js/mail.js | 19 +++++++++---------- addons/mail/static/src/xml/mail.xml | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 9133e5de257..86211c589bb 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -800,12 +800,12 @@ openerp.mail = function (session) { */ on_vote: function (event) { event.stopPropagation(); - var self=this; - return this.ds_message.call('vote_toggle', [[self.id]]).pipe(function (vote) { - self.has_voted = vote; - self.vote_nb += self.has_voted ? 1 : -1; - self.display_vote(); - }); + return this.ds_message.call('vote_toggle', [[this.id]]).pipe( + _.bind(function (vote) { + this.has_voted = vote; + this.vote_nb += this.has_voted ? 1 : -1; + this.display_vote(); + }, this)); return false; }, @@ -813,10 +813,9 @@ openerp.mail = function (session) { * Display the render of this message's vote */ display_vote: function () { - var self = this; - var vote_element = session.web.qweb.render('mail.thread.message.vote', {'widget': self}); - self.$(".oe_msg_vote:first").remove(); - self.$(".oe_mail_vote_count:first").replaceWith(vote_element); + var vote_element = session.web.qweb.render('mail.thread.message.vote', {'widget': this}); + this.$(".oe_msg_footer:first .oe_mail_vote_count").remove(); + this.$(".oe_msg_footer:first .oe_msg_vote").replaceWith(vote_element); }, /** diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index caa85cd3deb..1a40fbc61ac 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -257,12 +257,11 @@ Template used to display Like/Unlike in a mail.message --> - 8 - + like unlike From c25c94b8d9fdedaa97776307939b890e3b051864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 29 Oct 2012 17:52:11 +0100 Subject: [PATCH 03/82] [IMP] css: global mail compose button is beautifuller and better integrated bzr revid: fva@openerp.com-20121029165211-dzd1najj6btorzi9 --- addons/mail/static/src/css/mail.css | 29 ++++++++++++++++++++++++++++- addons/mail/static/src/js/mail.js | 17 ++++++++++------- addons/mail/static/src/xml/mail.xml | 4 ++-- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 86fcd7832dc..6de8ca5e249 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -1,3 +1,30 @@ +/* ------------ TOPBAR MAIL BUTTON --------------- */ + +/* FIXME this css is not very pretty because it uses a + * 'button' element wich comes with a lot of inappropriate + * styling. Entypo is also a headache to center properly + * */ + +.openerp .oe_topbar_item.oe_topbar_compose_full_email{ + padding: 0px; + width: 32px; + height: 32px; +} +.openerp .oe_topbar_item.oe_topbar_compose_full_email button{ + position: relative; + top: -3px; /* centering entypo ... urgh */ + box-sizing: border-box; + border: none; + box-shadow: none; + color: white; + background: none; + text-shadow: 0px 1px 2px black; + width: 32px; + height: 32px; + padding: 0px; + margin: 0px + border-radius: 0px; +} /* ------------ MAIL WIDGET --------------- */ .openerp .oe_mail, .openerp .oe_mail *{ @@ -158,7 +185,7 @@ } .openerp .oe_mail .oe_msg .oe_msg_content textarea{ width: 100%; - height: 32px; + height: 64px; margin: 0px; padding: 0px; resize: vertical; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 9133e5de257..258f85f12f3 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1681,13 +1681,16 @@ openerp.mail = function (session) { }, }); - - session.web.UserMenu = session.web.UserMenu.extend({ - start: function (parent, params) { - var render = new session.web.ComposeMessageTopButton(); - render.insertAfter(this.$el); - this._super(parent, params); - } + + session.web.UserMenu.include({ + do_update: function(){ + var self = this; + this._super.apply(this, arguments); + this.update_promise.then(function() { + var mail_button = new session.web.ComposeMessageTopButton(); + mail_button.appendTo(session.webclient.$el.find('.oe_systray')); + }); + }, }); }; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index caa85cd3deb..a34538e1248 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -248,8 +248,8 @@ render of the button on the user bar for open wizard compose message --> -
- +
+
From 566d7dd3afc38efb2171e829b9aadaf7cd064852 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 11:03:18 +0100 Subject: [PATCH 04/82] [IMP] mail: activate default value for the search view bzr revid: chm@openerp.com-20121030100318-pnvgcm2id034na93 --- addons/mail/mail_message_view.xml | 10 +-- addons/mail/static/src/js/mail.js | 94 +++++++++++++---------------- addons/mail/static/src/xml/mail.xml | 13 ++-- 3 files changed, 55 insertions(+), 62 deletions(-) diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 93b35797fd5..e265fc76afe 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -59,21 +59,24 @@ + - + @@ -84,7 +87,6 @@ form tree,form - {'search_default_to_read_message':True} diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 86211c589bb..2062c2ce615 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -948,16 +948,14 @@ openerp.mail = function (session) { */ on_scroll: function (event) { if (event)event.stopPropagation(); - this.$('.oe_msg_expandable:last'); - - var message = this.messages[this.messages.length-1]; - if (message && message.type=="expandable" && message.max_limit) { - var pos = message.$el.position(); + $last = this.$('> .oe_msg_expandable:last'); + if ($last.hasClass('oe_max_limit')) { + var pos = $last.position(); if (pos.top) { /* bottom of the screen */ var bottom = $(window).scrollTop()+$(window).height()+200; if (bottom > pos.top) { - message.on_expandable(); + $last.find('.oe_msg_fetch_more').click(); } } } @@ -1451,9 +1449,10 @@ openerp.mail = function (session) { bind_events: function () { if (this.context['typeof_thread']!='other') { - $(document).scroll( this.thread.on_scroll ); - $(window).resize( this.thread.on_scroll ); - window.setTimeout( this.thread.on_scroll, 500 ); + $(document).scroll( _.bind(this.thread.on_scroll, this.thread) ); + $(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 ); } } }); @@ -1556,17 +1555,23 @@ openerp.mail = function (session) { this.options = options || {}; this.options.domain = options.domain || []; this.options.context = options.context || {}; - this.search_results = {'domain': [], 'context': {}, 'groupby': {}} - this.ds_msg = new session.web.DataSetSearch(this, 'mail.message'); + + this.options.defaults = {}; + for (var key in options.context) { + if(key.match(/^search_default_/)) { + this.options.defaults[key.replace(/^search_default_/, '')] = options.context[key]; + } + } }, start: function () { this._super.apply(this, arguments); - var searchview_ready = this.load_searchview({}, false); - var thread_displayed = this.message_render(); - this.options.domain = this.options.domain.concat(this.search_results['domain']); + this.load_searchview(this.options.defaults, false); this.bind_events(); - return $.when(searchview_ready, thread_displayed); + + if(!this.searchview.has_defaults) { + this.message_render(); + } }, /** @@ -1576,10 +1581,14 @@ openerp.mail = function (session) { */ load_searchview: function (defaults, hidden) { var self = this; - this.searchview = new session.web.SearchView(this, this.ds_msg, false, defaults || {}, hidden || false); - return this.searchview.appendTo(this.$('.oe_view_manager_view_search')).then(function () { - self.searchview.on('search_data', self, self.do_searchview_search); - }); + var ds_msg = new session.web.DataSetSearch(self, 'mail.message'); + self.searchview = new session.web.SearchView(self, ds_msg, false, defaults || {}, hidden || false); + self.searchview.appendTo(self.$('.oe_view_manager_view_search')) + .then(function () { self.searchview.on('search_data', self, self.do_searchview_search); }); + if (this.searchview.has_defaults) { + this.searchview.ready.then(this.searchview.do_search); + } + return self.searchview }, /** @@ -1596,10 +1605,11 @@ openerp.mail = function (session) { contexts: contexts || [], group_by_seq: groupbys || [] }).then(function (results) { - self.search_results['context'] = results.context; - self.search_results['domain'] = results.domain; - self.root.destroy(); - return self.message_render(); + if(self.root) { + $('').insertAfter(self.root.$el); + self.root.destroy(); + } + return self.message_render(results); }); }, @@ -1607,13 +1617,12 @@ openerp.mail = function (session) { /** *Create the root thread widget and display this object in the DOM */ - message_render: function (search) { - var domain = this.options.domain.concat(this.search_results['domain']); - var context = _.extend(this.options.context, search&&search.search_results['context'] ? search.search_results['context'] : {}); + message_render: function ( search ) { + var domain = this.options.domain.concat(search && search['domain'] ? search['domain'] : []); + var context = _.extend(this.options.context, search && search['context'] ? search['context'] : {}); this.root = new mail.Widget(this, { 'domain' : domain, 'context' : context, - 'typeof_thread': context['typeof_thread'] || 'other', 'display_indented_thread': 1, 'show_reply_button': 10, 'show_read_unread_button': 11, @@ -1641,23 +1650,11 @@ openerp.mail = function (session) { * Add a link on the top user bar for write a full mail */ session.web.ComposeMessageTopButton = session.web.Widget.extend({ - template:'mail.compose_message.button_top_bar', + template:'mail.ComposeMessageTopButton', - init: function (parent, options) { - this._super.apply(this, options); - this.options = this.options || {}; - this.options.domain = this.options.domain || []; - this.options.context = { - 'default_model': false, - 'default_res_id': 0, - 'default_content_subtype': 'html', - }; - }, - - start: function (parent, params) { - var self = this; - this.$el.on('click', 'button', self.on_compose_message ); - this._super(parent, params); + start: function () { + this.$el.on('click', 'button', this.on_compose_message ); + this._super(); }, on_compose_message: function (event) { @@ -1667,14 +1664,9 @@ openerp.mail = function (session) { res_model: 'mail.compose.message', view_mode: 'form', view_type: 'form', - action_from: 'mail.ThreadComposeMessage', views: [[false, 'form']], target: 'new', - context: _.extend(this.options.context, { - 'default_model': this.context.default_model, - 'default_res_id': this.context.default_res_id, - 'default_content_subtype': 'html', - }), + context: { 'default_content_subtype': 'html' }, }; session.client.action_manager.do_action(action); }, @@ -1682,10 +1674,10 @@ openerp.mail = function (session) { }); session.web.UserMenu = session.web.UserMenu.extend({ - start: function (parent, params) { + start: function () { var render = new session.web.ComposeMessageTopButton(); render.insertAfter(this.$el); - this._super(parent, params); + this._super(); } }); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 1a40fbc61ac..179d6aae421 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -140,9 +140,7 @@

- News Feed - / - + Email box

@@ -234,11 +232,12 @@ -
+ @@ -247,9 +246,9 @@ mail.compose_message.button_top_bar render of the button on the user bar for open wizard compose message --> - +
- +
From b8a9b420e837cd37aa31fae4fb03ba32cba5bab8 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 11:56:58 +0100 Subject: [PATCH 05/82] [IMP] mail: -typof_thread option, +check_for_destroy method bzr revid: chm@openerp.com-20121030105658-j5k6zctwmx7wwyfu --- addons/mail/mail_thread_view.xml | 10 ++++---- addons/mail/static/src/js/mail.js | 40 ++++++++++++++----------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index 07b24725b05..70a0d7a96aa 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -5,35 +5,35 @@ Inbox mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid} }""/> To: me mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid} }""/> Favorites mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid} }""/> Archives mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid} }""/> Sent mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid} }""/> diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 2062c2ce615..0ee6d155ca0 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -731,6 +731,15 @@ openerp.mail = function (session) { return false; }, + /* Check if the message must be destroy and detroy it + * @param {callback} apply function + */ + check_for_destroy: function () { + var domain = mail.ChatterUtils.expand_domain( this.parent_thread.domain ).concat([["id", "=", this.id]]); + this.parent_thread.ds_message.call('message_read', [undefined, domain, [], 0, this.context, this.parent_thread.id]) + .then( _.bind(function (record) { if (!record || !record.length) this.animated_destroy(150); }, this) ); + }, + /*The selected thread and all childs (messages/thread) became read * @param {object} mouse envent */ @@ -738,15 +747,12 @@ openerp.mail = function (session) { event.stopPropagation(); var self=this; - if ( (this.to_read && this.options.typeof_thread == 'inbox') || - (!this.to_read && this.options.typeof_thread == 'archives')) { - this.animated_destroy(150); - } - // if this message is read, all childs message display is read this.ds_notification.call('set_message_read', [ [this.id].concat( this.get_child_ids() ) , this.to_read, this.context]).pipe(function () { self.$el.removeClass(self.to_read ? 'oe_msg_unread':'oe_msg_read').addClass(self.to_read ? 'oe_msg_read':'oe_msg_unread'); self.to_read = !self.to_read; + // check if the message must be display + self.check_for_destroy(); }); return false; }, @@ -831,9 +837,8 @@ openerp.mail = function (session) { button.addClass('oe_starred'); } else { button.removeClass('oe_starred'); - if ( self.options.typeof_thread == 'stared' ) { - self.animated_destroy(150); - } + // check if the message must be display + self.check_for_destroy(); } }); return false; @@ -879,9 +884,6 @@ openerp.mail = function (session) { * @param {Object} [thread] * @param {int} [display_indented_thread] number thread level to indented threads. * other are on flat mode - * @param {Select} [typeof_thread] inbox/archives/stared/sent - * type of thread and option for user application like animate - * destroy for read/unread * @param {Array} [parents] liked with the parents thread * use with browse, fetch... [O]= top parent */ @@ -1108,7 +1110,7 @@ openerp.mail = function (session) { var thread_level = this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0; return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, thread_level, fetch_context, this.context.default_parent_id || undefined]) - .then(callback ? _.bind(callback, this, arguments) : this.proxy('switch_new_message')); + .then(callback ? _.bind(callback, this) : this.proxy('switch_new_message')); }, /** @@ -1364,8 +1366,6 @@ openerp.mail = function (session) { * @param {Object} [context] context of the thread. It should * contain at least default_model, default_res_id. Please refer to * the compose_message widget for more information about it. - * ... @param {Select} [typeof_thread=(mail|stared|archives|send|other)] - * options for destroy message when the user click on a button * @param {Object} [options] *... @param {Number} [truncate_limit=250] number of character to * display before having a "show more" link; note that the text @@ -1389,7 +1389,6 @@ openerp.mail = function (session) { this.search_results = {'domain': [], 'context': {}, 'groupby': {}}; this.options = _.extend({ - 'typeof_thread' : 'inbox', 'display_indented_thread' : -1, 'show_reply_button' : -1, 'show_read_unread_button' : -1, @@ -1448,12 +1447,10 @@ openerp.mail = function (session) { }, bind_events: function () { - if (this.context['typeof_thread']!='other') { - $(document).scroll( _.bind(this.thread.on_scroll, this.thread) ); - $(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 ); - } + $(document).scroll( _.bind(this.thread.on_scroll, this.thread) ); + $(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 ); } }); @@ -1514,7 +1511,6 @@ openerp.mail = function (session) { this.root = new mail.Widget(this, { 'domain' : domain, 'context' : this.options.context, - 'typeof_thread': this.options.context['typeof_thread'] || 'other', 'display_indented_thread': -1, 'show_reply_button': 0, 'show_read_unread_button': -1, From 49325c24d2730147c18541a7cca1968445b9f863 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 12:33:56 +0100 Subject: [PATCH 06/82] [IMP] mail: reduce options on js bzr revid: chm@openerp.com-20121030113356-374gjb6zanw4xtsw --- addons/mail/static/src/js/mail.js | 57 ++++++++++++----------------- addons/mail/static/src/xml/mail.xml | 6 +-- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 0ee6d155ca0..d11e610064e 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -145,15 +145,16 @@ openerp.mail = function (session) { this.show_compact_message = false; // data of this compose message - this.attachment_ids = []; this.id = datasets.id; this.model = datasets.model; this.res_model = datasets.res_model; this.is_private = datasets.is_private || false; this.partner_ids = datasets.partner_ids || []; - this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); this.thread_level = datasets.thread_level; + + this.attachment_ids = []; this.parent_thread= parent.messages!= undefined ? parent : false; + this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); this.ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment'); this.show_delete_attachment = true; @@ -439,7 +440,7 @@ openerp.mail = function (session) { this.type = 'expandable', this.max_limit = this.id < 0 || false, this.flag_used = false, - this.parent_thread= parent.messages!= undefined ? parent : this.options._parents[0]; + this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; }, @@ -529,8 +530,8 @@ openerp.mail = function (session) { * display before having a "show more" link; note that the text * will not be truncated if it does not have 110% of the parameter * @param {Boolean} [show_record_name] - *... @param {int} [show_reply_button] number thread level to display the reply button - *... @param {int} [show_read_unread_button] number thread level to display the read/unread button + *... @param {boolean} [show_reply_button] display the reply button + *... @param {boolean} [show_read_unread_button] display the read/unread button */ init: function (parent, datasets, context) { this._super(parent); @@ -543,7 +544,7 @@ openerp.mail = function (session) { default_parent_id: false }, context || {}); // record options - this.options = datasets.options; + this.options = datasets.options || {}; // data of this message this.id = datasets.id || -1, @@ -566,12 +567,8 @@ openerp.mail = function (session) { this.attachment_ids = datasets.attachment_ids || [], this._date = datasets.date; - - this.show_reply_button = this.options.show_compose_message && this.options.show_reply_button > this.thread_level; - this.show_read_unread_button = this.options.show_read_unread_button > this.thread_level; - // record options and data - this.parent_thread= parent.messages!= undefined ? parent : this.options._parents[0]; + this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; this.thread = false; if ( this.id > 0 ) { @@ -735,7 +732,7 @@ openerp.mail = function (session) { * @param {callback} apply function */ check_for_destroy: function () { - var domain = mail.ChatterUtils.expand_domain( this.parent_thread.domain ).concat([["id", "=", this.id]]); + var domain = mail.ChatterUtils.expand_domain( this.options.root_thread.domain ).concat([["id", "=", this.id]]); this.parent_thread.ds_message.call('message_read', [undefined, domain, [], 0, this.context, this.parent_thread.id]) .then( _.bind(function (record) { if (!record || !record.length) this.animated_destroy(150); }, this) ); }, @@ -770,8 +767,8 @@ openerp.mail = function (session) { // goto the wall thread for launch browse if (!options._go_thread_wall) { options._go_thread_wall = true; - for (var i in this.options._parents[0].messages) { - var res=this.options._parents[0].messages[i].browse_message(options); + for (var i in this.options.root_thread.messages) { + var res=this.options.root_thread.messages[i].browse_message(options); if (res) return res; } } @@ -896,7 +893,7 @@ openerp.mail = function (session) { default_parent_id: false }, options.context || {}); this.options = options.options; - this.options._parents = (options.options._parents != undefined ? options.options._parents : []).concat( [this] ); + this.options.root_thread = (options.options.root_thread != undefined ? options.options.root_thread : this); // record options and data this.parent_message= parent.thread!= undefined ? parent : false ; @@ -1031,7 +1028,7 @@ openerp.mail = function (session) { // goto the wall thread for launch browse if (!options._go_thread_wall) { options._go_thread_wall = true; - return this.options._parents[0].browse_thread(options); + return this.options.root_thread.browse_thread(options); } if (this.id==options.id) { @@ -1065,8 +1062,8 @@ openerp.mail = function (session) { * @return message object */ browse_message: function (options) { - if (this.options._parents[0].messages[0]) - return this.options._parents[0].messages[0].browse_message(options); + if (this.options.root_thread.messages[0]) + return this.options.root_thread.messages[0].browse_message(options); }, /** @@ -1110,7 +1107,7 @@ openerp.mail = function (session) { var thread_level = this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0; return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, thread_level, fetch_context, this.context.default_parent_id || undefined]) - .then(callback ? _.bind(callback, this) : this.proxy('switch_new_message')); + .then(callback ? _.bind(callback, this, arguments) : this.proxy('switch_new_message')); }, /** @@ -1371,8 +1368,8 @@ openerp.mail = function (session) { * display before having a "show more" link; note that the text * will not be truncated if it does not have 110% of the parameter *... @param {Boolean} [show_record_name] display the name and link for do action - *... @param {int} [show_reply_button] number thread level to display the reply button - *... @param {int} [show_read_unread_button] number thread level to display the read/unread button + *... @param {boolean} [show_reply_button] display the reply button + *... @param {boolean} [show_read_unread_button] display the read/unread button *... @param {int} [display_indented_thread] number thread level to indented threads. * other are on flat mode *... @param {Boolean} [show_compose_message] allow to display the composer @@ -1390,8 +1387,8 @@ openerp.mail = function (session) { this.options = _.extend({ 'display_indented_thread' : -1, - 'show_reply_button' : -1, - 'show_read_unread_button' : -1, + 'show_reply_button' : false, + 'show_read_unread_button' : false, 'truncate_limit' : 250, 'show_record_name' : false, 'show_compose_message' : false, @@ -1403,12 +1400,6 @@ openerp.mail = function (session) { if (this.display_indented_thread === false) { this.display_indented_thread = -1; } - if (this.show_reply_button === false) { - this.show_reply_button = -1; - } - if (this.show_read_unread_button === false) { - this.show_read_unread_button = -1; - } }, @@ -1512,8 +1503,8 @@ openerp.mail = function (session) { 'domain' : domain, 'context' : this.options.context, 'display_indented_thread': -1, - 'show_reply_button': 0, - 'show_read_unread_button': -1, + 'show_reply_button': false, + 'show_read_unread_button': false, 'show_compose_message': show_compose_message, 'message_ids': message_ids, 'show_compact_message': true, @@ -1620,8 +1611,8 @@ openerp.mail = function (session) { 'domain' : domain, 'context' : context, 'display_indented_thread': 1, - 'show_reply_button': 10, - 'show_read_unread_button': 11, + 'show_reply_button': true, + 'show_read_unread_button': true, 'show_compose_message': true, 'show_compact_message': false, } diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 179d6aae421..c22a71dde30 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -195,9 +195,9 @@
- X - v - ( + X + v + ( 7
From f5dead290e47cbabd14f883e035fa5a966e2d7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 30 Oct 2012 13:39:46 +0100 Subject: [PATCH 07/82] [IMP] made the chatter in formview narrower bzr revid: fva@openerp.com-20121030123946-egyj48s2p5ywxqqy --- addons/mail/static/src/css/mail.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 6de8ca5e249..821b7468802 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -328,6 +328,7 @@ padding-top: 5px; width: 160px; float: right; + margin-right: 16px; } /* a) THE FOLLOW BUTTON */ @@ -401,7 +402,8 @@ .openerp .oe_record_thread{ display: block; - margin-right: 180px; + margin-left: 16px; + margin-right: 212px; } /* ----------- INBOX INTEGRATION ----------- */ From f30097c2026d43514b6825eb6ab3b5ff5b030d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 30 Oct 2012 13:47:06 +0100 Subject: [PATCH 08/82] [IMP] mail css: narrower threads bzr revid: fva@openerp.com-20121030124706-x2q3ocynjo72orr7 --- addons/mail/static/src/css/mail.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 821b7468802..49d88776572 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -410,5 +410,5 @@ .openerp .oe_mail_wall .oe_mail{ margin: 16px; - width: 720px; + width: 600px; } From f18b5723f6c67a9aed34adca9097534af2962e69 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 13:48:22 +0100 Subject: [PATCH 09/82] [IMP] mail: review and reduce mail.RecordThread bzr revid: chm@openerp.com-20121030124822-c551kk1krvdtp6vh --- addons/mail/static/src/js/mail.js | 39 +++++++++++-------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index d11e610064e..5372a3fca44 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1031,14 +1031,14 @@ openerp.mail = function (session) { return this.options.root_thread.browse_thread(options); } - if (this.id==options.id) { + if (this.id == options.id) { return this; } if (options.id) { for (var i in this.messages) { if (this.messages[i].thread) { - var res=this.messages[i].thread.browse_thread({'id':options.id, '_go_thread_wall':true}); + var res = this.messages[i].thread.browse_thread({'id':options.id, '_go_thread_wall':true}); if (res) return res; } } @@ -1460,12 +1460,6 @@ openerp.mail = function (session) { mail.RecordThread = session.web.form.AbstractField.extend({ template: 'mail.record_thread', - init: function () { - this._super.apply(this, arguments); - this.options.domain = this.options.domain || []; - this.options.context = {'default_model': 'mail.thread', 'default_res_id': false}; - }, - start: function () { this._super.apply(this, arguments); // NB: check the actual_mode property on view to know if the view is in create mode anymore @@ -1476,37 +1470,30 @@ openerp.mail = function (session) { _check_visibility: function () { this.$el.toggle(this.view.get("actual_mode") !== "create"); }, + render_value: function () { var self = this; if (! this.view.datarecord.id || session.web.BufferedDataSet.virtual_id_regex.test(this.view.datarecord.id)) { this.$('oe_mail_thread').hide(); return; } - // update context - _.extend(this.options.context, { - default_res_id: this.view.datarecord.id, - default_model: this.view.model, - default_is_private: false }); - // update domain - var domain = this.options.domain.concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]); - - var show_compose_message = this.view.is_action_enabled('edit') || - (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()); - - var message_ids = this.getParent().fields.message_ids && this.getParent().fields.message_ids.get_value(); if (this.root) { this.root.destroy(); } // create and render Thread widget this.root = new mail.Widget(this, { - 'domain' : domain, - 'context' : this.options.context, + 'domain' : (this.options.domain || []).concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]), + 'context' : { + 'default_res_id': this.view.datarecord.id || false, + 'default_model': this.view.model || 'mail.thread', + 'default_is_private': false + }, 'display_indented_thread': -1, 'show_reply_button': false, 'show_read_unread_button': false, - 'show_compose_message': show_compose_message, - 'message_ids': message_ids, + 'show_compose_message': this.view.is_action_enabled('edit') || (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()), + 'message_ids': this.getParent().fields.message_ids ? this.getParent().fields.message_ids.get_value() : undefined, 'show_compact_message': true, 'no_message': this.node.attrs.help } @@ -1539,6 +1526,7 @@ openerp.mail = function (session) { */ init: function (parent, options) { this._super(parent); + console.log(arguments); this.options = options || {}; this.options.domain = options.domain || []; this.options.context = options.context || {}; @@ -1552,7 +1540,7 @@ openerp.mail = function (session) { }, start: function () { - this._super.apply(this, arguments); + this._super.apply(this); this.load_searchview(this.options.defaults, false); this.bind_events(); @@ -1657,7 +1645,6 @@ openerp.mail = function (session) { }; session.client.action_manager.do_action(action); }, - }); session.web.UserMenu = session.web.UserMenu.extend({ From fbc46c5b2dee4bd09ed96764653bdc6d97fb89ec Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 14:11:36 +0100 Subject: [PATCH 10/82] [IMP] mail: review and reduce of js bzr revid: chm@openerp.com-20121030131136-e72mj13a408m2bwx --- addons/mail/static/src/js/mail.js | 80 ++++++++++++++++--------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 11f8a95aebb..d4917d829df 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -745,12 +745,13 @@ openerp.mail = function (session) { var self=this; // if this message is read, all childs message display is read - this.ds_notification.call('set_message_read', [ [this.id].concat( this.get_child_ids() ) , this.to_read, this.context]).pipe(function () { - self.$el.removeClass(self.to_read ? 'oe_msg_unread':'oe_msg_read').addClass(self.to_read ? 'oe_msg_read':'oe_msg_unread'); - self.to_read = !self.to_read; - // check if the message must be display - self.check_for_destroy(); - }); + this.ds_notification.call('set_message_read', [ [this.id].concat( this.get_child_ids() ) , this.to_read, this.context]) + .then(function () { + self.$el.removeClass(self.to_read ? 'oe_msg_unread':'oe_msg_read').addClass(self.to_read ? 'oe_msg_read':'oe_msg_unread'); + self.to_read = !self.to_read; + // check if the message must be display + self.check_for_destroy(); + }); return false; }, @@ -803,12 +804,13 @@ openerp.mail = function (session) { */ on_vote: function (event) { event.stopPropagation(); - return this.ds_message.call('vote_toggle', [[this.id]]).pipe( - _.bind(function (vote) { - this.has_voted = vote; - this.vote_nb += this.has_voted ? 1 : -1; - this.display_vote(); - }, this)); + return this.ds_message.call('vote_toggle', [[this.id]]) + .then( + _.bind(function (vote) { + this.has_voted = vote; + this.vote_nb += this.has_voted ? 1 : -1; + this.display_vote(); + }, this)); return false; }, @@ -828,16 +830,17 @@ openerp.mail = function (session) { event.stopPropagation(); var self=this; var button = self.$('.oe_star:first'); - return this.ds_message.call('favorite_toggle', [[self.id]]).pipe(function (star) { - self.is_favorite=star; - if (self.is_favorite) { - button.addClass('oe_starred'); - } else { - button.removeClass('oe_starred'); - // check if the message must be display - self.check_for_destroy(); - } - }); + return this.ds_message.call('favorite_toggle', [[self.id]]) + .then(function (star) { + self.is_favorite=star; + if (self.is_favorite) { + button.addClass('oe_starred'); + } else { + button.removeClass('oe_starred'); + // check if the message must be display + self.check_for_destroy(); + } + }); return false; }, @@ -894,6 +897,7 @@ openerp.mail = function (session) { this.options = options.options; this.options.root_thread = (options.options.root_thread != undefined ? options.options.root_thread : this); + this.options.show_compose_message = this.options.show_compose_message && (this.options.display_indented_thread >= this.thread_level || !this.thread_level); // record options and data this.parent_message= parent.thread!= undefined ? parent : false ; @@ -907,8 +911,7 @@ openerp.mail = function (session) { this.thread_level = (datasets.thread_level+1) || 0, this.partner_ids = _.filter(datasets.partner_ids, function (partner) { return partner[0]!=datasets.author_id[0]; } ) this.messages = []; - this.show_compose_message = this.options.show_compose_message && (this.options.show_reply_button > this.thread_level || !this.thread_level); - + // object compose message this.compose_message = false; @@ -1096,18 +1099,20 @@ openerp.mail = function (session) { * @param {Array} ids read (if the are some ids, the method don't use the domain) */ message_fetch: function (replace_domain, replace_context, ids, callback) { - var self = this; - - // domain and context: options + additional - fetch_domain = replace_domain ? replace_domain : this.domain; - fetch_context = replace_context ? replace_context : this.context; - var message_loaded_ids = this.id ? [this.id].concat( self.get_child_ids() ) : self.get_child_ids(); - - // CHM note : option for sending in flat mode by server - var thread_level = this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0; - - return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, thread_level, fetch_context, this.context.default_parent_id || undefined]) - .then(callback ? _.bind(callback, this, arguments) : this.proxy('switch_new_message')); + return this.ds_message.call('message_read', [ + // ids force to read + ids, + // domain + additional + (replace_domain ? replace_domain : this.domain), + // ids allready loaded + (this.id ? [this.id].concat( this.get_child_ids() ) : this.get_child_ids()), + // option for sending in flat mode by server + (this.options.display_indented_thread > this.thread_level ? this.options.display_indented_thread - this.thread_level : 0), + // context + additional + (replace_context ? replace_context : this.context), + // parent_id + this.context.default_parent_id || undefined + ]).done(callback ? _.bind(callback, this, arguments) : this.proxy('switch_new_message')); }, /** @@ -1159,7 +1164,7 @@ openerp.mail = function (session) { insert_message: function (message, dom_insert_after) { var self=this; - if (this.show_compose_message && this.options.show_compact_message) { + if (this.options.show_compact_message) { this.instantiate_compose_message(); this.compose_message.do_show_compact(); } @@ -1526,7 +1531,6 @@ openerp.mail = function (session) { */ init: function (parent, options) { this._super(parent); - console.log(arguments); this.options = options || {}; this.options.domain = options.domain || []; this.options.context = options.context || {}; From aa900c135d7d1537004b1ba456986a52ef48471c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 30 Oct 2012 14:43:42 +0100 Subject: [PATCH 11/82] [IMP] see more message clickable on entire line, and correctly centered bzr revid: fva@openerp.com-20121030134342-cddrzs8vyc8d3gr2 --- addons/mail/static/src/css/mail.css | 3 ++- addons/mail/static/src/js/mail.js | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 49d88776572..8936f5c3a3c 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -299,6 +299,7 @@ .openerp .oe_mail .oe_msg_content.oe_msg_more_message{ text-align: right; + cursor: pointer; } .openerp .oe_mail .oe_msg_content.oe_msg_more_message .oe_separator{ height: 0; @@ -310,7 +311,7 @@ } .openerp .oe_mail .oe_msg_more_message .oe_msg_fetch_more { background: white; - margin-right: 280px; + margin-right: 210px; padding-left: 8px; padding-right: 8px; text-decoration: none; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 11f8a95aebb..3dfb59e10e9 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -460,7 +460,7 @@ openerp.mail = function (session) { * Bind events in the widget. Each event is slightly described * in the function. */ bind_events: function () { - this.$el.on('click', 'a.oe_msg_fetch_more', this.on_expandable); + this.$el.on('click', '.oe_msg_more_message', this.on_expandable); }, animated_destroy: function (fadeTime) { @@ -669,10 +669,10 @@ openerp.mail = function (session) { this.$('.oe_msg_body:first').expander({ slicePoint: this.options.truncate_limit, expandText: 'read more', - userCollapseText: '[^]', + userCollapseText: 'ã', detailClass: 'oe_msg_tail', moreClass: 'oe_mail_expand', - lessClass: 'oe_mail_reduce', + lessClass: 'oe_mail_reduce oe_e', }); }, @@ -954,7 +954,7 @@ openerp.mail = function (session) { /* bottom of the screen */ var bottom = $(window).scrollTop()+$(window).height()+200; if (bottom > pos.top) { - $last.find('.oe_msg_fetch_more').click(); + $last.find('.oe_msg_more_message').click(); } } } From e0c039b0e50c7bb5a177a962466a36dece9b2ad4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 14:47:38 +0100 Subject: [PATCH 12/82] [IMP] mail: convert dom search on_scroll by filter js bzr revid: chm@openerp.com-20121030134738-h5ypheuze05ohy20 --- addons/mail/static/src/js/mail.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 42976eff1a5..799f14c2116 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -830,6 +830,9 @@ openerp.mail = function (session) { event.stopPropagation(); var self=this; var button = self.$('.oe_star:first'); + + console.log(window); + return this.ds_message.call('favorite_toggle', [[self.id]]) .then(function (star) { self.is_favorite=star; @@ -841,7 +844,6 @@ openerp.mail = function (session) { self.check_for_destroy(); } }); - return false; }, /** @@ -948,19 +950,18 @@ openerp.mail = function (session) { /* When the expandable object is visible on screen (with scrolling) * then the on_expandable function is launch */ - on_scroll: function (event) { - if (event)event.stopPropagation(); - $last = this.$('> .oe_msg_expandable:last'); - if ($last.hasClass('oe_max_limit')) { - var pos = $last.position(); + on_scroll: function () { + var expandables = + _.each( _.filter(this.messages, function (val) {return val.id < 0;}), function (val) { + var pos = val.$el.position(); if (pos.top) { /* bottom of the screen */ var bottom = $(window).scrollTop()+$(window).height()+200; if (bottom > pos.top) { - $last.find('.oe_msg_more_message').click(); + val.on_expandable(); } } - } + }); }, /** From a7d64a13e8512cd9db0dfa4223c4017df0350e12 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 15:40:50 +0100 Subject: [PATCH 13/82] [FIX] mail: write on the last message on a thread, don't indeted the message bzr revid: chm@openerp.com-20121030144050-61ji54ydc3deto8k --- addons/mail/static/src/js/mail.js | 46 +++++++++++++---------------- addons/mail/static/src/xml/mail.xml | 2 +- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 799f14c2116..61c0a327392 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -359,8 +359,13 @@ openerp.mail = function (session) { this.parent_thread.context ]).then(function (record) { var thread = self.parent_thread; + + if (self.options.display_indented_thread < self.thread_level) { + thread = thread.parent_message.parent_thread; + } // create object and attach to the thread object thread.message_fetch(false, false, [record], function (arg, data) { + data[0].no_sorted = true; var message = thread.create_message_object( data[0] ); // insert the message on dom thread.insert_message( message, self.$el ); @@ -536,6 +541,8 @@ openerp.mail = function (session) { init: function (parent, datasets, context) { this._super(parent); + // record options + this.options = datasets.options || {}; // record domain and context this.domain = datasets.domain || []; this.context = _.extend({ @@ -543,30 +550,14 @@ openerp.mail = function (session) { default_res_id: 0, default_parent_id: false }, context || {}); - // record options - this.options = datasets.options || {}; - // data of this message - this.id = datasets.id || -1, - this.model = datasets.model || false, - this.parent_id = datasets.parent_id || false, - this.res_id = datasets.res_id || false, - this.type = datasets.type || false, - this.is_author = datasets.is_author || false, - this.is_private = datasets.is_private || false, - this.subject = datasets.subject || false, - this.name = datasets.name || false, - this.record_name = datasets.record_name || false, - this.body = datasets.body || false, - this.vote_nb = datasets.vote_nb || 0, - this.has_voted = datasets.has_voted || false, - this.is_favorite = datasets.is_favorite || false, - this.thread_level = datasets.thread_level || 0, - this.to_read = datasets.to_read || false, - this.author_id = datasets.author_id || [], - this.attachment_ids = datasets.attachment_ids || [], + for (var k in datasets) { + this[k] = datasets[k]; + } this._date = datasets.date; + this.show_record_name = this.record_name && !this.subject && !this.thread_level && this.model!='res.partner'; + // record options and data this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; this.thread = false; @@ -830,10 +821,7 @@ openerp.mail = function (session) { event.stopPropagation(); var self=this; var button = self.$('.oe_star:first'); - - console.log(window); - - return this.ds_message.call('favorite_toggle', [[self.id]]) + this.ds_message.call('favorite_toggle', [[self.id]]) .then(function (star) { self.is_favorite=star; if (self.is_favorite) { @@ -844,6 +832,7 @@ openerp.mail = function (session) { self.check_for_destroy(); } }); + return false; }, /** @@ -980,6 +969,7 @@ openerp.mail = function (session) { var p=$(this).parent(); p.find('.oe_more_hidden, .oe_hidden').show(); p.find('.oe_more').hide(); + return false; }, /** @@ -989,6 +979,7 @@ openerp.mail = function (session) { var p=$(this).parent(); p.find('.oe_more_hidden, .oe_hidden').hide(); p.find('.oe_more').show(); + return false; }, /* get all child message/thread id linked. @@ -1078,6 +1069,7 @@ openerp.mail = function (session) { on_compose_message: function () { this.instantiate_compose_message(); this.compose_message.on_compose_expandable(); + return false; }, /** @@ -1183,6 +1175,9 @@ openerp.mail = function (session) { var message_older = false; if (message.id > 0) { for (var i in self.messages) { + if (self.messages[i].no_sorted) { + continue; + } if (self.messages[i].id > message.id) { if (!message_newer || message_newer.id > self.messages[i].id) { message_newer = self.messages[i]; @@ -1263,6 +1258,7 @@ openerp.mail = function (session) { on_message_detroy: function (message) { this.messages = _.filter(this.messages, function (val) { return !val.isDestroyed(); }); + return false; }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index a21fb02ad5b..ceeacaa8be1 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -206,7 +206,7 @@
- + From 9b9231dc4fd51afea4235515b12ec228982f0591 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 16:35:23 +0100 Subject: [PATCH 14/82] [FIX] mail: display message after save document bzr revid: chm@openerp.com-20121030153523-ebg68dd2yxuv5r3d --- addons/mail/static/src/js/mail.js | 3 ++- addons/note/note_view.xml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 61c0a327392..aebb237c28c 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -360,7 +360,7 @@ openerp.mail = function (session) { ]).then(function (record) { var thread = self.parent_thread; - if (self.options.display_indented_thread < self.thread_level) { + if (self.options.display_indented_thread < self.thread_level && thread.parent_message) { thread = thread.parent_message.parent_thread; } // create object and attach to the thread object @@ -1481,6 +1481,7 @@ openerp.mail = function (session) { } if (this.root) { + $('').insertAfter(this.root.$el); this.root.destroy(); } // create and render Thread widget diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index 5c3a77b7626..f6ef2b67eea 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -120,7 +120,7 @@
- +
From e143d3fcf2bf1415769f52383ac4b87d316c7e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 30 Oct 2012 16:38:57 +0100 Subject: [PATCH 15/82] [IMP] read less message bzr revid: fva@openerp.com-20121030153857-12w2b9zf36vaoip0 --- addons/mail/static/src/js/mail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 42976eff1a5..a16a6484aec 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -669,10 +669,10 @@ openerp.mail = function (session) { this.$('.oe_msg_body:first').expander({ slicePoint: this.options.truncate_limit, expandText: 'read more', - userCollapseText: 'ã', + userCollapseText: 'read less', detailClass: 'oe_msg_tail', moreClass: 'oe_mail_expand', - lessClass: 'oe_mail_reduce oe_e', + lessClass: 'oe_mail_reduce', }); }, From 6453930f289baa24844e120f260be9c8f562b12b Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 30 Oct 2012 16:47:00 +0100 Subject: [PATCH 16/82] [FIX] mail: on_scroll, load same messages => stack loading. bzr revid: chm@openerp.com-20121030154700-oqe5dklhtvh0r5gj --- addons/mail/static/src/js/mail.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index aebb237c28c..ec8b5726986 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -556,7 +556,7 @@ openerp.mail = function (session) { } this._date = datasets.date; - this.show_record_name = this.record_name && !this.subject && !this.thread_level && this.model!='res.partner'; + this.show_record_name = this.record_name && !this.thread_level && this.model!='res.partner'; // record options and data this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; @@ -941,13 +941,15 @@ openerp.mail = function (session) { */ on_scroll: function () { var expandables = - _.each( _.filter(this.messages, function (val) {return val.id < 0;}), function (val) { + _.each( _.filter(this.messages, function (val) {return val.id == -1 && !val.loading;}), function (val) { var pos = val.$el.position(); if (pos.top) { /* bottom of the screen */ var bottom = $(window).scrollTop()+$(window).height()+200; if (bottom > pos.top) { val.on_expandable(); + // load only one time + val.loading = true; } } }); From fd0b674f5c40ec9082ceafdaaf2fcb1663600ea0 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 31 Oct 2012 10:09:31 +0100 Subject: [PATCH 17/82] [IMP] mail: last_id (js/py) bzr revid: chm@openerp.com-20121031090931-gloqsggi3j276jpj --- addons/mail/mail_message.py | 12 ++++++++++++ addons/mail/static/src/js/mail.js | 13 +++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index bd0ade31b68..70edf0ee53b 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -240,6 +240,7 @@ class mail_message(osv.Model): return { 'id': message['id'], + 'last_id': message['id'], 'type': message['type'], 'attachment_ids': attachment_ids, 'body': message['body'], @@ -425,6 +426,17 @@ class mail_message(osv.Model): # get the child expandable messages for the tree message_list = sorted(message_list, key=lambda k: k['id']) + + + for message in message_list: + if message['parent_id']: + for msg in message_list: + if message['parent_id'] == msg['id']: + if message['last_id'] < message['parent_id']: + message['last_id'] = message['parent_id'] + break + + self._message_read_add_expandables(cr, uid, message_list, read_messages, thread_level=thread_level, message_loaded_ids=message_unload_ids, domain=domain, parent_id=parent_id, context=context, limit=limit) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index ec8b5726986..f3b787e1e15 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -596,7 +596,7 @@ openerp.mail = function (session) { start: function () { this._super.apply(this, arguments); this.expender(); - this.$el.hide().fadeIn(750, function () {$(this).css('display', '');}); + //this.$el.hide().fadeIn(750, function () {$(this).css('display', '');}); this.resize_img(); this.bind_events(); if(this.thread_level < this.options.display_indented_thread) { @@ -895,6 +895,7 @@ openerp.mail = function (session) { // data of this thread this.id = datasets.id || false, + this.last_id = datasets.last_id || false, this.model = datasets.model || false, this.parent_id = datasets.parent_id || false, this.is_private = datasets.is_private || false, @@ -941,7 +942,7 @@ openerp.mail = function (session) { */ on_scroll: function () { var expandables = - _.each( _.filter(this.messages, function (val) {return val.id == -1 && !val.loading;}), function (val) { + _.each( _.filter(this.messages, function (val) {return val.id == -1;}), function (val) { var pos = val.$el.position(); if (pos.top) { /* bottom of the screen */ @@ -1180,12 +1181,12 @@ openerp.mail = function (session) { if (self.messages[i].no_sorted) { continue; } - if (self.messages[i].id > message.id) { - if (!message_newer || message_newer.id > self.messages[i].id) { + if (self.messages[i].last_id > (message.last_id || message.id)) { + if (!message_newer || message_newer.last_id > self.messages[i].last_id) { message_newer = self.messages[i]; } - } else if (self.messages[i].id > 0 && self.messages[i].id < message.id) { - if (!message_older || message_older.id < self.messages[i].id) { + } else if (self.messages[i].last_id > 0 && self.messages[i].last_id < (message.last_id || message.id)) { + if (!message_older || message_older.last_id < self.messages[i].last_id) { message_older = self.messages[i]; } } From 1bbc2c00633516a5901de3243ee1fb905a51b916 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 31 Oct 2012 15:56:10 +0100 Subject: [PATCH 18/82] [IMP] mail: js, compose, expandable and message extend messageglobal bzr revid: chm@openerp.com-20121031145610-e8m9l7lsmzzjru9k --- addons/mail/mail_message.py | 2 +- addons/mail/mail_thread_view.xml | 28 ++- addons/mail/static/src/js/mail.js | 268 +++++++++++++--------------- addons/mail/static/src/xml/mail.xml | 12 +- 4 files changed, 151 insertions(+), 159 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 70edf0ee53b..9ecdb00ad5f 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -227,7 +227,7 @@ class mail_message(osv.Model): is_private = False try: - attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, message['attachment_ids'], context=context)] + attachment_ids = [{'id': attach['id'], 'filename': attach['datas_fname']} for attach in self.pool.get('ir.attachment').read(cr, uid, message['attachment_ids'], ['id', 'datas_fname'], context=context)] except (orm.except_orm, osv.except_osv): attachment_ids = [] diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index 70a0d7a96aa..50da8d6e5b9 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -5,35 +5,45 @@ Inbox mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid, 'view_mailbox': True} }""/> + +

+ Click to define a new sales tag. +

+ Create specific tags that fit your company's activities + to better classify and analyse your leads and opportunities. + Such categories could for instance reflect your product + structure or the different types of sales you do. +

+
To: me mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid, 'view_mailbox': True} }""/> - Favorites + Todo mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid, 'view_mailbox': True} }""/> - Archives + Done mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid, 'view_mailbox': True} }""/> Sent mail.wall + 'context': {'default_model': 'res.users', 'default_res_id': uid, 'view_mailbox': True} }""/> @@ -61,13 +71,13 @@ - Favorites + Todo - Archives + Done diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index f3b787e1e15..fc77719b965 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -114,6 +114,88 @@ openerp.mail = function (session) { }; + mail.ThreadMessageGlobal = session.web.Widget.extend({ + + init: function (parent, datasets, options) { + this._super(parent, options); + + // record options + this.options = datasets.options || options || {}; + // record domain and context + this.domain = datasets.domain || options.domain || []; + this.context = _.extend({ + default_model: 'mail.thread', + default_res_id: 0, + default_parent_id: false }, options.context || {}); + + // data of this message + this.id = datasets.id || -1, + this.last_id = this.id, + this.model = datasets.model || false, + this.res_model = datasets.res_model || false; + this.parent_id = datasets.parent_id || false, + this.res_id = datasets.res_id || false, + this.type = datasets.type || false, + this.is_author = datasets.is_author || false, + this.is_private = datasets.is_private || false, + this.subject = datasets.subject || false, + this.name = datasets.name || false, + this.record_name = datasets.record_name || false, + this.body = datasets.body || false, + this.vote_nb = datasets.vote_nb || 0, + this.has_voted = datasets.has_voted || false, + this.is_favorite = datasets.is_favorite || false, + this.thread_level = datasets.thread_level || 0, + this.to_read = datasets.to_read || false, + this.author_id = datasets.author_id || [this.session.uid], + this.attachment_ids = datasets.attachment_ids || [], + this.partner_ids = datasets.partner_ids || []; + this.nb_messages = datasets.nb_messages; + this._date = datasets.date; + + this.formating_data(); + + // record options and data + this.show_record_name = this.record_name && !this.thread_level && this.model!='res.partner'; + this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; + this.thread = false; + }, + + /* Convert date, timerelative and avatar in displayable data. */ + formating_data: function () { + + //formating and add some fields for render + if (this._date) { + this.date = session.web.format_value(this._date, {type:"datetime"}); + this.timerelative = $.timeago(this.date); + } + if (this.type == 'email') { + this.avatar = ('/mail/static/src/img/email_icon.png'); + } else { + this.avatar = mail.ChatterUtils.get_image(this.session, 'res.partner', 'image_small', this.author_id[0]); + } + for (var l in this.attachment_ids) { + var attach = this.attachment_ids[l]; + attach['url'] = mail.ChatterUtils.get_attachment_url(this.session, attach); + + if (attach.filename.match(/[.](jpg|jpg|gif|png|tif|svg)$/i)) { + attach.is_image = true; + attach['url'] = mail.ChatterUtils.get_image(this.session, 'ir.attachment', 'datas', attach.id); + } + } + }, + + /** + * call on_message_delete on his parent thread + */ + destroy: function () { + + this._super(); + this.parent_thread.on_message_detroy(this); + + } + }); + /** * ------------------------------------------------------------ * ComposeMessage widget @@ -125,7 +207,7 @@ openerp.mail = function (session) { * When the user focuses the textarea, the compose message is instantiated. */ - mail.ThreadComposeMessage = session.web.Widget.extend({ + mail.ThreadComposeMessage = mail.ThreadMessageGlobal.extend({ template: 'mail.compose_message', /** @@ -137,33 +219,18 @@ openerp.mail = function (session) { */ init: function (parent, datasets, options) { - var self = this; - this._super(parent); - this.context = options.context || {}; - this.options = options.options; - + this._super(parent, datasets, options); this.show_compact_message = false; - - // data of this compose message - this.id = datasets.id; - this.model = datasets.model; - this.res_model = datasets.res_model; - this.is_private = datasets.is_private || false; - this.partner_ids = datasets.partner_ids || []; - this.thread_level = datasets.thread_level; - - this.attachment_ids = []; - this.parent_thread= parent.messages!= undefined ? parent : false; - this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); - - this.ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment'); this.show_delete_attachment = true; - - this.fileupload_id = _.uniqueId('oe_fileupload_temp'); - $(window).on(self.fileupload_id, self.on_attachment_loaded); }, start: function () { + this._super.apply(this, arguments); + + this.ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment'); + this.fileupload_id = _.uniqueId('oe_fileupload_temp'); + $(window).on(this.fileupload_id, this.on_attachment_loaded); + this.display_attachments(); this.bind_events(); }, @@ -171,8 +238,7 @@ openerp.mail = function (session) { /* upload the file on the server, add in the attachments list and reload display */ display_attachments: function () { - this.$(".oe_msg_attachment_list").html( - session.web.qweb.render('mail.thread.message.attachments', {'widget': this}) ); + this.$(".oe_msg_attachment_list").html( session.web.qweb.render('mail.thread.message.attachments', {'widget': this}) ); // event: delete an attachment this.$(".oe_msg_attachment_list").on('click', '.oe_mail_attachment_delete', this.on_attachment_delete); }, @@ -424,30 +490,15 @@ openerp.mail = function (session) { * - - visible message * - - expandable */ - mail.ThreadExpandable = session.web.Widget.extend({ + mail.ThreadExpandable = mail.ThreadMessageGlobal.extend({ template: 'mail.thread.expandable', - init: function (parent, datasets, context) { - this._super(parent); - this.domain = datasets.domain || []; - this.options = datasets.options; - this.context = _.extend({ - default_model: 'mail.thread', - default_res_id: 0, - default_parent_id: false }, context || {}); - - // data of this expandable message - this.id = datasets.id || -1, - this.model = datasets.model || false, - this.parent_id = datasets.parent_id || false, - this.nb_messages = datasets.nb_messages || 0, - this.thread_level = datasets.thread_level || 0, - this.type = 'expandable', - this.max_limit = this.id < 0 || false, - this.flag_used = false, - this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; + init: function (parent, datasets, options) { + this._super(parent, datasets, options); + this.type = 'expandable'; + this.max_limit = this.id < 0 || false; + this.flag_used = false; }, - start: function () { this._super.apply(this, arguments); @@ -489,16 +540,6 @@ openerp.mail = function (session) { this.parent_thread.message_fetch(this.domain, this.context); return false; }, - - /** - * call on_message_delete on his parent thread - */ - destroy: function () { - - this._super(); - this.parent_thread.on_message_detroy(this); - - } }); /** @@ -519,10 +560,11 @@ openerp.mail = function (session) { * - - sub message (parent_id = root message) * - - - sub thread */ - mail.ThreadMessage = session.web.Widget.extend({ + mail.ThreadMessage = mail.ThreadMessageGlobal.extend({ template: 'mail.thread.message', /** + * INIT : * @param {Object} parent parent * @param {Array} [domain] * @param {Object} [context] context of the thread. It should @@ -538,71 +580,19 @@ openerp.mail = function (session) { *... @param {boolean} [show_reply_button] display the reply button *... @param {boolean} [show_read_unread_button] display the read/unread button */ - init: function (parent, datasets, context) { - this._super(parent); - - // record options - this.options = datasets.options || {}; - // record domain and context - this.domain = datasets.domain || []; - this.context = _.extend({ - default_model: 'mail.thread', - default_res_id: 0, - default_parent_id: false }, context || {}); - - // data of this message - for (var k in datasets) { - this[k] = datasets[k]; - } - this._date = datasets.date; - - this.show_record_name = this.record_name && !this.thread_level && this.model!='res.partner'; - - // record options and data - this.parent_thread= parent.messages!= undefined ? parent : this.options.root_thread; - this.thread = false; - - if ( this.id > 0 ) { - this.formating_data(); - } - - this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification'); - this.ds_message = new session.web.DataSetSearch(this, 'mail.message'); - this.ds_follow = new session.web.DataSetSearch(this, 'mail.followers'); - }, - - /* Convert date, timerelative and avatar in displayable data. */ - formating_data: function () { - - //formating and add some fields for render - this.date = session.web.format_value(this._date, {type:"datetime"}); - this.timerelative = $.timeago(this.date); - if (this.type == 'email') { - this.avatar = ('/mail/static/src/img/email_icon.png'); - } else { - this.avatar = mail.ChatterUtils.get_image(this.session, 'res.partner', 'image_small', this.author_id[0]); - } - for (var l in this.attachment_ids) { - var attach = this.attachment_ids[l]; - attach['url'] = mail.ChatterUtils.get_attachment_url(this.session, attach); - - if ((attach.filename || attach.name).match(/[.](jpg|jpg|gif|png|tif|svg)$/i)) { - attach.is_image = true; - attach['url'] = mail.ChatterUtils.get_image(this.session, 'ir.attachment', 'datas', attach.id); - } - } - }, start: function () { this._super.apply(this, arguments); this.expender(); - //this.$el.hide().fadeIn(750, function () {$(this).css('display', '');}); this.resize_img(); this.bind_events(); if(this.thread_level < this.options.display_indented_thread) { this.create_thread(); } this.$('.oe_msg_attachments, .oe_msg_images').addClass("oe_hidden"); + + this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification'); + this.ds_message = new session.web.DataSetSearch(this, 'mail.message'); }, resize_img: function () { @@ -835,16 +825,6 @@ openerp.mail = function (session) { return false; }, - /** - * call on_message_delete on his parent thread - */ - destroy: function () { - - this._super(); - this.parent_thread.on_message_detroy(this); - - } - }); /** @@ -879,7 +859,7 @@ openerp.mail = function (session) { * use with browse, fetch... [O]= top parent */ init: function (parent, datasets, options) { - this._super(parent); + this._super(parent, options); this.domain = options.domain || []; this.context = _.extend({ default_model: 'mail.thread', @@ -1124,17 +1104,17 @@ openerp.mail = function (session) { data.options = _.extend(self.options, data.options); if (data.type=='expandable') { - var message = new mail.ThreadExpandable(self, data, { + var message = new mail.ThreadExpandable(self, data, {'context':{ 'default_model': data.model || self.context.default_model, 'default_res_id': data.res_id || self.context.default_res_id, 'default_parent_id': self.id, - }); + }}); } else { - var message = new mail.ThreadMessage(self, data, { + var message = new mail.ThreadMessage(self, data, {'context':{ 'default_model': data.model, 'default_res_id': data.res_id, 'default_parent_id': data.id, - }); + }}); } // check if the message is already create @@ -1160,7 +1140,7 @@ openerp.mail = function (session) { insert_message: function (message, dom_insert_after) { var self=this; - if (this.options.show_compact_message) { + if (this.options.show_compact_message > this.thread_level) { this.instantiate_compose_message(); this.compose_message.do_show_compact(); } @@ -1332,9 +1312,11 @@ openerp.mail = function (session) { 'domain': message_dom, 'options': message.options, }, { - 'default_model': message.model || this.context.default_model, - 'default_res_id': message.res_id || this.context.default_res_id, - 'default_parent_id': this.id, + 'context':{ + 'default_model': message.model || this.context.default_model, + 'default_res_id': message.res_id || this.context.default_res_id, + 'default_parent_id': this.id, + } }); // add object on array and DOM @@ -1489,7 +1471,7 @@ openerp.mail = function (session) { } // create and render Thread widget this.root = new mail.Widget(this, { - 'domain' : (this.options.domain || []).concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]), + 'domain' : (this.domain || []).concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]), 'context' : { 'default_res_id': this.view.datarecord.id || false, 'default_model': this.view.model || 'mail.thread', @@ -1500,7 +1482,7 @@ openerp.mail = function (session) { 'show_read_unread_button': false, 'show_compose_message': this.view.is_action_enabled('edit') || (this.getParent().fields.message_is_follower && this.getParent().fields.message_is_follower.get_value()), 'message_ids': this.getParent().fields.message_ids ? this.getParent().fields.message_ids.get_value() : undefined, - 'show_compact_message': true, + 'show_compact_message': 1, 'no_message': this.node.attrs.help } ); @@ -1532,24 +1514,24 @@ openerp.mail = function (session) { */ init: function (parent, options) { this._super(parent); - this.options = options || {}; - this.options.domain = options.domain || []; - this.options.context = options.context || {}; + this.domain = options.domain || []; + this.context = options.context || {}; - this.options.defaults = {}; + this.defaults = {}; for (var key in options.context) { if(key.match(/^search_default_/)) { - this.options.defaults[key.replace(/^search_default_/, '')] = options.context[key]; + this.defaults[key.replace(/^search_default_/, '')] = options.context[key]; } } }, start: function () { this._super.apply(this); - this.load_searchview(this.options.defaults, false); + this.load_searchview(this.defaults, false); + this.bind_events(); - if(!this.searchview.has_defaults) { + if (!this.searchview.has_defaults) { this.message_render(); } }, @@ -1598,8 +1580,8 @@ openerp.mail = function (session) { *Create the root thread widget and display this object in the DOM */ message_render: function ( search ) { - var domain = this.options.domain.concat(search && search['domain'] ? search['domain'] : []); - var context = _.extend(this.options.context, search && search['context'] ? search['context'] : {}); + var domain = this.domain.concat(search && search['domain'] ? search['domain'] : []); + var context = _.extend(this.context, search && search['context'] ? search['context'] : {}); this.root = new mail.Widget(this, { 'domain' : domain, 'context' : context, @@ -1607,7 +1589,7 @@ openerp.mail = function (session) { 'show_reply_button': true, 'show_read_unread_button': true, 'show_compose_message': true, - 'show_compact_message': false, + 'show_compact_message': this.context.view_mailbox ? false : 1, } ); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index ceeacaa8be1..5cd4c045469 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -38,7 +38,7 @@
-