summaryrefslogtreecommitdiff
path: root/addons/mail/static
diff options
context:
space:
mode:
Diffstat (limited to 'addons/mail/static')
-rw-r--r--addons/mail/static/description/icon.png (renamed from addons/mail/static/src/img/icon.png)bin5754 -> 5754 bytes
-rw-r--r--addons/mail/static/description/index.html178
-rw-r--r--addons/mail/static/description/mail_illustration.pngbin0 -> 34110 bytes
-rw-r--r--addons/mail/static/description/mail_sc_00.pngbin0 -> 71427 bytes
-rw-r--r--addons/mail/static/description/mail_sc_01.pngbin0 -> 23632 bytes
-rw-r--r--addons/mail/static/description/mail_sc_02.pngbin0 -> 27486 bytes
-rw-r--r--addons/mail/static/description/mail_sc_03.pngbin0 -> 21784 bytes
-rw-r--r--addons/mail/static/description/mail_sc_04.pngbin0 -> 92888 bytes
-rw-r--r--addons/mail/static/description/mail_sc_05.pngbin0 -> 27375 bytes
-rw-r--r--addons/mail/static/description/mail_sc_06.pngbin0 -> 27375 bytes
-rw-r--r--addons/mail/static/description/mail_sc_07.pngbin0 -> 100179 bytes
-rw-r--r--addons/mail/static/description/photo.pngbin0 -> 6289 bytes
-rw-r--r--addons/mail/static/lib/jquery.expander/jquery.expander.js385
-rw-r--r--addons/mail/static/src/css/mail.css95
-rw-r--r--addons/mail/static/src/css/mail_group.css1
-rw-r--r--addons/mail/static/src/js/mail.js94
-rw-r--r--addons/mail/static/src/js/mail_followers.js112
-rw-r--r--addons/mail/static/src/js/suggestions.js77
-rw-r--r--addons/mail/static/src/xml/mail.xml38
-rw-r--r--addons/mail/static/src/xml/mail_followers.xml1
-rw-r--r--addons/mail/static/src/xml/suggestions.xml38
21 files changed, 568 insertions, 451 deletions
diff --git a/addons/mail/static/src/img/icon.png b/addons/mail/static/description/icon.png
index 53ccc469127..53ccc469127 100644
--- a/addons/mail/static/src/img/icon.png
+++ b/addons/mail/static/description/icon.png
Binary files differ
diff --git a/addons/mail/static/description/index.html b/addons/mail/static/description/index.html
new file mode 100644
index 00000000000..aa55e63008d
--- /dev/null
+++ b/addons/mail/static/description/index.html
@@ -0,0 +1,178 @@
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <div class="oe_span12">
+ <h2 class="oe_slogan">Enterprise Social Network</h2>
+ <h3 class="oe_slogan">A private social network for your company</h3>
+ </div>
+ <div class="oe_span6">
+ <div class="oe_demo oe_picture oe_screenshot">
+ <a href="https://www.openerp.com/saas_master/demo?lang=en_US&module=crm">
+ <img src="mail_sc_00.png">
+ </a>
+ <div class="oe_demo_footer oe_centeralign">Online Demo</div>
+ </div>
+ </div>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Connect with experts, follow what interests you, share documents and promote
+best practices. Get work done with effective collaboration across departments,
+geographies, documents and business applications. All of this while decreasing
+email overload.
+
+ </p>
+ <div class="oe_centeralign oe_websiteonly">
+ <a href="http://www.openerp.com/start?app=mail" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
+ </div>
+ </div>
+ </div>
+</section>
+
+<section class="oe_container oe_dark">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Connect with experts</h2>
+ <h3 class="oe_slogan">Get the right information, when you need it</h3>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Next time you have a question for the marketing, sales, R&amp;D or any other
+department, don't send an email blast-post the question to OpenERP and get
+answers from the right persons.
+ </p>
+ </div>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_sc_01.png">
+ </div>
+ </div>
+ </div>
+</section>
+
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Follow what interests you</h2>
+ <h3 class="oe_slogan">Make the information flow across your company</h3>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture" src="mail_sc_02.png">
+ </div>
+ </div>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Want to get informed about new product features, hot deals, bottlenecks in projects or any other event? Just follow what interests you to get the information you need what you need; no more, no less.
+ </p>
+ </div>
+ </div>
+</section>
+
+
+<section class="oe_container oe_dark">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Get Things Done</h2>
+ <h3 class="oe_slogan">Your inbox is a todo list</h3>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+You can process (not only read) the inbox and easily mark messages for future actions. Start feeling the pleasure of having an empty inbox every day; no more overload of information.
+ </p>
+ </div>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_sc_03.png">
+ </div>
+ </div>
+ </div>
+</section>
+
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Promote best practices</h2>
+ <h3 class="oe_slogan">Discussion groups at your fingertips</h3>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_sc_04.png">
+ </div>
+ </div>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Cut back on meetings and email chains by working together in groups of interests. Create a group to let people share files, discuss ideas, and vote to promote best practices.
+ </p>
+ </div>
+ </div>
+</section>
+
+<section class="oe_container oe_dark">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Improve Access to Information and Expertise</h2>
+ <h3 class="oe_slogan">Easily find the information you need</h3>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Break down information silos. Search across your existing systems to find the answers and expertise you need to complete projects quickly.
+ </p>
+ </div>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_illustration.png">
+ </div>
+ </div>
+ </div>
+</section>
+
+<section class="oe_container">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">Collaborate securely</h2>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_sc_06.png">
+ </div>
+ </div>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Set the right security policy; public, private or on invitation only -- according to the information sensitivity.
+ </p>
+ </div>
+ </div>
+</section>
+
+
+<section class="oe_container oe_dark">
+ <div class="oe_row oe_spaced">
+ <h2 class="oe_slogan">A Twitter-like Network For Your Company </h2>
+ <div class="oe_span6">
+ <p class="oe_mt32">
+Make every employee feel more connected and engaged with twitter-like features
+for your own company. Follow people, share best practices, 'like' top ideas, etc.
+ </p>
+ </div>
+ <div class="oe_span6">
+ <div class="oe_row_img oe_centered">
+ <img class="oe_picture oe_screenshot" src="mail_sc_07.png">
+ </div>
+ </div>
+ </div>
+</section>
+
+
+<section class="oe_container">
+ <div class="oe_row">
+ <div class="oe_span12">
+ <h2 class="oe_slogan">Trusted by millions worldwide</h2>
+ </div>
+ <div class="oe_span12">
+ <div class="oe_quote">
+ <q>
+ Emails make me waste my time. But I need them. Reading my inbox
+ is the most unproductive task I do on a daily basis. I have to
+ spend one or two full hours a day to process my emails. All the
+ junk flows in the same inbox; spams, information that doesn't
+ matter, quoted answers of quoted answers, etc. At the end of
+ the hour, only 10 emails actually requested an answer from me.
+ Since I use OpenERP, I can do the same job in only 10 minutes!
+ </q>
+ <cite class="oe_cite oe_clearfix">
+ <img class="oe_photo" src="photo.png">
+ <div class="oe_author">Luc de Keyser</div>
+ </cite>
+ </div>
+ </div>
+ </div>
+</section>
+<section class="oe_container oe_separator">
+</section>
diff --git a/addons/mail/static/description/mail_illustration.png b/addons/mail/static/description/mail_illustration.png
new file mode 100644
index 00000000000..4fff4837faa
--- /dev/null
+++ b/addons/mail/static/description/mail_illustration.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_00.png b/addons/mail/static/description/mail_sc_00.png
new file mode 100644
index 00000000000..3011ef129b5
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_00.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_01.png b/addons/mail/static/description/mail_sc_01.png
new file mode 100644
index 00000000000..1b1099f6536
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_01.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_02.png b/addons/mail/static/description/mail_sc_02.png
new file mode 100644
index 00000000000..4e59c9d1e0f
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_02.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_03.png b/addons/mail/static/description/mail_sc_03.png
new file mode 100644
index 00000000000..dbb14b4da36
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_03.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_04.png b/addons/mail/static/description/mail_sc_04.png
new file mode 100644
index 00000000000..b8f47ba2935
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_04.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_05.png b/addons/mail/static/description/mail_sc_05.png
new file mode 100644
index 00000000000..251b4ebc676
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_05.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_06.png b/addons/mail/static/description/mail_sc_06.png
new file mode 100644
index 00000000000..251b4ebc676
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_06.png
Binary files differ
diff --git a/addons/mail/static/description/mail_sc_07.png b/addons/mail/static/description/mail_sc_07.png
new file mode 100644
index 00000000000..9a33332817e
--- /dev/null
+++ b/addons/mail/static/description/mail_sc_07.png
Binary files differ
diff --git a/addons/mail/static/description/photo.png b/addons/mail/static/description/photo.png
new file mode 100644
index 00000000000..e605e5c6f8e
--- /dev/null
+++ b/addons/mail/static/description/photo.png
Binary files differ
diff --git a/addons/mail/static/lib/jquery.expander/jquery.expander.js b/addons/mail/static/lib/jquery.expander/jquery.expander.js
deleted file mode 100644
index 91cc03db918..00000000000
--- a/addons/mail/static/lib/jquery.expander/jquery.expander.js
+++ /dev/null
@@ -1,385 +0,0 @@
-/*!
- * jQuery Expander Plugin v1.4.2
- *
- * Date: Fri Mar 16 14:29:56 2012 EDT
- * Requires: jQuery v1.3+
- *
- * Copyright 2011, Karl Swedberg
- * Dual licensed under the MIT and GPL licenses (just like jQuery):
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- *
- *
- *
-*/
-
-(function($) {
- $.expander = {
- version: '1.4.2',
- defaults: {
- // the number of characters at which the contents will be sliced into two parts.
- slicePoint: 100,
-
- // whether to keep the last word of the summary whole (true) or let it slice in the middle of a word (false)
- preserveWords: true,
-
- // a threshold of sorts for whether to initially hide/collapse part of the element's contents.
- // If after slicing the contents in two there are fewer words in the second part than
- // the value set by widow, we won't bother hiding/collapsing anything.
- widow: 4,
-
- // text displayed in a link instead of the hidden part of the element.
- // clicking this will expand/show the hidden/collapsed text
- expandText: 'read more',
- expandPrefix: '&hellip; ',
-
- expandAfterSummary: false,
-
- // class names for summary element and detail element
- summaryClass: 'summary',
- detailClass: 'details',
-
- // class names for <span> around "read-more" link and "read-less" link
- moreClass: 'read-more',
- lessClass: 'read-less',
-
- // number of milliseconds after text has been expanded at which to collapse the text again.
- // when 0, no auto-collapsing
- collapseTimer: 0,
-
- // effects for expanding and collapsing
- expandEffect: 'fadeIn',
- expandSpeed: 250,
- collapseEffect: 'fadeOut',
- collapseSpeed: 200,
-
- // allow the user to re-collapse the expanded text.
- userCollapse: true,
-
- // text to use for the link to re-collapse the text
- userCollapseText: 'read less',
- userCollapsePrefix: ' ',
-
-
- // all callback functions have the this keyword mapped to the element in the jQuery set when .expander() is called
-
- onSlice: null, // function() {}
- beforeExpand: null, // function() {},
- afterExpand: null, // function() {},
- onCollapse: null // function(byUser) {}
- }
- };
-
- $.fn.expander = function(options) {
- var meth = 'init';
-
- if (typeof options == 'string') {
- meth = options;
- options = {};
- }
-
- var opts = $.extend({}, $.expander.defaults, options),
- rSelfClose = /^<(?:area|br|col|embed|hr|img|input|link|meta|param).*>$/i,
- rAmpWordEnd = opts.wordEnd || /(&(?:[^;]+;)?|[a-zA-Z\u00C0-\u0100]+)$/,
- rOpenCloseTag = /<\/?(\w+)[^>]*>/g,
- rOpenTag = /<(\w+)[^>]*>/g,
- rCloseTag = /<\/(\w+)>/g,
- rLastCloseTag = /(<\/[^>]+>)\s*$/,
- rTagPlus = /^<[^>]+>.?/,
- delayedCollapse;
-
- var methods = {
- init: function() {
- this.each(function() {
- var i, l, tmp, newChar, summTagless, summOpens, summCloses,
- lastCloseTag, detailText, detailTagless,
- $thisDetails, $readMore,
- openTagsForDetails = [],
- closeTagsForsummaryText = [],
- defined = {},
- thisEl = this,
- $this = $(this),
- $summEl = $([]),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- hasDetails = !!$this.find('.' + o.detailClass).length,
- hasBlocks = !!$this.find('*').filter(function() {
- var display = $(this).css('display');
- return (/^block|table|list/).test(display);
- }).length,
- el = hasBlocks ? 'div' : 'span',
- detailSelector = el + '.' + o.detailClass,
- moreSelector = 'span.' + o.moreClass,
- expandSpeed = o.expandSpeed || 0,
- allHtml = $.trim( $this.html() ),
- allText = $.trim( $this.text() ),
- summaryText = allHtml.slice(0, o.slicePoint);
-
- // bail out if we've already set up the expander on this element
- if ( $.data(this, 'expander') ) {
- return;
- }
-
- $.data(this, 'expander', true);
-
- // determine which callback functions are defined
- $.each(['onSlice','beforeExpand', 'afterExpand', 'onCollapse'], function(index, val) {
- defined[val] = $.isFunction(o[val]);
- });
-
- // back up if we're in the middle of a tag or word
- summaryText = backup(summaryText);
-
- // summary text sans tags length
- summTagless = summaryText.replace(rOpenCloseTag, '').length;
-
- // add more characters to the summary, one for each character in the tags
- while (summTagless < o.slicePoint) {
- newChar = allHtml.charAt(summaryText.length);
- if (newChar == '<') {
- newChar = allHtml.slice(summaryText.length).match(rTagPlus)[0];
- }
- summaryText += newChar;
- summTagless++;
- }
-
- summaryText = backup(summaryText, o.preserveWords);
-
- // separate open tags from close tags and clean up the lists
- summOpens = summaryText.match(rOpenTag) || [];
- summCloses = summaryText.match(rCloseTag) || [];
-
- // filter out self-closing tags
- tmp = [];
- $.each(summOpens, function(index, val) {
- if ( !rSelfClose.test(val) ) {
- tmp.push(val);
- }
- });
- summOpens = tmp;
-
- // strip close tags to just the tag name
- l = summCloses.length;
- for (i = 0; i < l; i++) {
- summCloses[i] = summCloses[i].replace(rCloseTag, '$1');
- }
-
- // tags that start in summary and end in detail need:
- // a). close tag at end of summary
- // b). open tag at beginning of detail
- $.each(summOpens, function(index, val) {
- var thisTagName = val.replace(rOpenTag, '$1');
- var closePosition = $.inArray(thisTagName, summCloses);
- if (closePosition === -1) {
- openTagsForDetails.push(val);
- closeTagsForsummaryText.push('</' + thisTagName + '>');
-
- } else {
- summCloses.splice(closePosition, 1);
- }
- });
-
- // reverse the order of the close tags for the summary so they line up right
- closeTagsForsummaryText.reverse();
-
- // create necessary summary and detail elements if they don't already exist
- if ( !hasDetails ) {
-
- // end script if there is no detail text or if detail has fewer words than widow option
- detailText = allHtml.slice(summaryText.length);
- detailTagless = $.trim( detailText.replace(rOpenCloseTag, '') );
-
- if ( detailTagless === '' || detailTagless.split(/\s+/).length < o.widow ) {
- return;
- }
- // otherwise, continue...
- lastCloseTag = closeTagsForsummaryText.pop() || '';
- summaryText += closeTagsForsummaryText.join('');
- detailText = openTagsForDetails.join('') + detailText;
-
- } else {
- // assume that even if there are details, we still need readMore/readLess/summary elements
- // (we already bailed out earlier when readMore el was found)
- // but we need to create els differently
-
- // remove the detail from the rest of the content
- detailText = $this.find(detailSelector).remove().html();
-
- // The summary is what's left
- summaryText = $this.html();
-
- // allHtml is the summary and detail combined (this is needed when content has block-level elements)
- allHtml = summaryText + detailText;
-
- lastCloseTag = '';
- }
- o.moreLabel = $this.find(moreSelector).length ? '' : buildMoreLabel(o);
-
- if (hasBlocks) {
- detailText = allHtml;
- }
- summaryText += lastCloseTag;
-
- // onSlice callback
- o.summary = summaryText;
- o.details = detailText;
- o.lastCloseTag = lastCloseTag;
-
- if (defined.onSlice) {
- // user can choose to return a modified options object
- // one last chance for user to change the options. sneaky, huh?
- // but could be tricky so use at your own risk.
- tmp = o.onSlice.call(thisEl, o);
-
- // so, if the returned value from the onSlice function is an object with a details property, we'll use that!
- o = tmp && tmp.details ? tmp : o;
- }
-
- // build the html with summary and detail and use it to replace old contents
- var html = buildHTML(o, hasBlocks);
-
- $this.html( html );
-
- // set up details and summary for expanding/collapsing
- $thisDetails = $this.find(detailSelector);
- $readMore = $this.find(moreSelector);
- $thisDetails.hide();
- $readMore.find('a').unbind('click.expander').bind('click.expander', expand);
-
- $summEl = $this.find('div.' + o.summaryClass);
-
- if ( o.userCollapse && !$this.find('span.' + o.lessClass).length ) {
- $this
- .find(detailSelector)
- .append('<span class="' + o.lessClass + '">' + o.userCollapsePrefix + '<a href="#">' + o.userCollapseText + '</a></span>');
- }
-
- $this
- .find('span.' + o.lessClass + ' a')
- .unbind('click.expander')
- .bind('click.expander', function(event) {
- event.preventDefault();
- clearTimeout(delayedCollapse);
- var $detailsCollapsed = $(this).closest(detailSelector);
- reCollapse(o, $detailsCollapsed);
- if (defined.onCollapse) {
- o.onCollapse.call(thisEl, true);
- }
- });
-
- function expand(event) {
- event.preventDefault();
- $readMore.hide();
- $summEl.hide();
- if (defined.beforeExpand) {
- o.beforeExpand.call(thisEl);
- }
-
- $thisDetails.stop(false, true)[o.expandEffect](expandSpeed, function() {
- $thisDetails.css({zoom: ''});
- if (defined.afterExpand) {o.afterExpand.call(thisEl);}
- delayCollapse(o, $thisDetails, thisEl);
- });
- }
-
- }); // this.each
- },
- destroy: function() {
- if ( !this.data('expander') ) {
- return;
- }
- this.removeData('expander');
- this.each(function() {
- var $this = $(this),
- o = $.meta ? $.extend({}, opts, $this.data()) : opts,
- details = $this.find('.' + o.detailClass).contents();
-
- $this.find('.' + o.moreClass).remove();
- $this.find('.' + o.summaryClass).remove();
- $this.find('.' + o.detailClass).after(details).remove();
- $this.find('.' + o.lessClass).remove();
-
- });
- }
- };
-
- // run the methods (almost always "init")
- if ( methods[meth] ) {
- methods[ meth ].call(this);
- }
-
- // utility functions
- function buildHTML(o, blocks) {
- var el = 'span',
- summary = o.summary;
- if ( blocks ) {
- el = 'div';
- // if summary ends with a close tag, tuck the moreLabel inside it
- if ( rLastCloseTag.test(summary) && !o.expandAfterSummary) {
- summary = summary.replace(rLastCloseTag, o.moreLabel + '$1');
- } else {
- // otherwise (e.g. if ends with self-closing tag) just add moreLabel after summary
- // fixes #19
- summary += o.moreLabel;
- }
-
- // and wrap it in a div
- summary = '<div class="' + o.summaryClass + '">' + summary + '</div>';
- } else {
- summary += o.moreLabel;
- }
-
- return [
- summary,
- '<',
- el + ' class="' + o.detailClass + '"',
- '>',
- o.details,
- '</' + el + '>'
- ].join('');
- }
-
- function buildMoreLabel(o) {
- var ret = '<span class="' + o.moreClass + '">' + o.expandPrefix;
- ret += '<a href="#">' + o.expandText + '</a></span>';
- return ret;
- }
-
- function backup(txt, preserveWords) {
- if ( txt.lastIndexOf('<') > txt.lastIndexOf('>') ) {
- txt = txt.slice( 0, txt.lastIndexOf('<') );
- }
- if (preserveWords) {
- txt = txt.replace(rAmpWordEnd,'');
- }
-
- return $.trim(txt);
- }
-
- function reCollapse(o, el) {
- el.stop(true, true)[o.collapseEffect](o.collapseSpeed, function() {
- var prevMore = el.prev('span.' + o.moreClass).show();
- if (!prevMore.length) {
- el.parent().children('div.' + o.summaryClass).show()
- .find('span.' + o.moreClass).show();
- }
- });
- }
-
- function delayCollapse(option, $collapseEl, thisEl) {
- if (option.collapseTimer) {
- delayedCollapse = setTimeout(function() {
- reCollapse(option, $collapseEl);
- if ( $.isFunction(option.onCollapse) ) {
- option.onCollapse.call(thisEl, false);
- }
- }, option.collapseTimer);
- }
- }
-
- return this;
- };
-
- // plugin defaults
- $.fn.expander.defaults = $.expander.defaults;
-})(jQuery);
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index 958c2bccd5f..a4beca607ba 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -22,10 +22,20 @@
width: 32px;
height: 32px;
padding: 0px;
- margin: 0px
+ margin: 0px;
border-radius: 0px;
}
+/* ---- GENERIC FOR MAIL-RELATED STUFF ---- */
+.openerp .oe_e.oe_e_alias {
+ font-size: 30px;
+ line-height: 15px;
+ vertical-align: top;
+ margin-right: 3px;
+ color: white;
+ text-shadow: 0px 0px 2px black;
+}
+
/* ------------ MAIL WIDGET --------------- */
.openerp .oe_mail, .openerp .oe_mail *{
-webkit-box-sizing: border-box;
@@ -108,6 +118,9 @@
text-overflow:ellipsis;
word-wrap: break-word;
}
+.openerp .oe_mail .oe_msg .oe_msg_content .oe_msg_body .oe_mail_cleaned {
+ display: none;
+}
/* a) Indented Messages */
@@ -622,11 +635,10 @@
}
.openerp .oe_followers .oe_partner {
height: 32px;
- margin-right: 8px;
+ margin-right: 24px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
- margin-right: 10px;
}
.openerp .oe_followers .oe_partner img{
width: 32px;
@@ -639,7 +651,18 @@
right: 0px;
line-height: 20px;
}
-
+.openerp .oe_followers .oe_edit_subtype{
+ cursor: pointer;
+ position: absolute;
+ right: 12px;
+ line-height: 20px;
+}
+.openerp .oe_followers .oe_partner .oe_hidden{
+ display: none;
+}
+.openerp.ui-dialog .ui-dialog-titlebar .ui-dialog-title{
+ padding-right: 20px;
+}
.openerp .oe_followers .oe_show_more{
cursor: pointer;
}
@@ -665,8 +688,72 @@
.openerp .oe_mail_wall .oe_mail{
margin: 16px;
width: 600px;
+ display: inline-block;
}
.openerp .oe_mail .oe_view_nocontent > p {
padding-left: 15px;
}
+
+
+/* ------------- WALL SIDEBAR ------------- */
+
+.openerp .oe_mail_wall .oe_mail_wall_aside {
+ margin: 16px;
+ position: relative;
+ display: inline-block;
+ vertical-align: top;
+ width: 260px;
+}
+.openerp .oe_mail_wall_aside .oe_sidebar_suggestion {
+ background-color: #EDEDF6;
+ border-radius: 2px;
+ padding-top: 1px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_title h2 {
+ font-size: 14px;
+ font-weight: bold;
+ margin-left: 10px;
+ padding: 0px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item {
+ border-radius: 2px;
+ width: 100%;
+ margin-left: 10px;
+ min-height: 67px; /* image_small 66x66px */
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item_image {
+ float: left;
+ padding-right: 10px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item_image img {
+ border-radius: 2px;
+ border: solid 1px rgba(0,0,0,0.03);
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item_content button {
+ margin-top: 10px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item_content a.oe_suggestion_item_name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ width: 90%;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_title a.oe_suggestion_remove {
+ line-height: 15px;
+ margin-top: -2px;
+ float: right;
+ visibility: hidden;
+ margin-right: 7px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_items .oe_suggested_item_content a.oe_suggestion_remove_item {
+ line-height: 15px;
+ margin-top: -2px;
+ float: right;
+ visibility: hidden;
+ margin-right: 16px;
+}
+.openerp .oe_sidebar_suggestion .oe_suggest_title:hover a.oe_suggestion_remove,
+.openerp .oe_sidebar_suggestion .oe_suggest_items:hover a.oe_suggestion_remove_item {
+ visibility: visible;
+}
+
diff --git a/addons/mail/static/src/css/mail_group.css b/addons/mail/static/src/css/mail_group.css
index 5ba817aa1a5..39cdf5c0b4c 100644
--- a/addons/mail/static/src/css/mail_group.css
+++ b/addons/mail/static/src/css/mail_group.css
@@ -48,7 +48,6 @@
text-align: center;
overflow: hidden;
-moz-border-radius: 3px;
- border-collapse: separate;
-webkit-border-radius: 3px;
-o-border-radius: 3px;
-ms-border-radius: 3px;
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 7df6cdbef0d..62e9241cf4f 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -2,10 +2,10 @@ openerp.mail = function (session) {
var _t = session.web._t,
_lt = session.web._lt;
- var mail = session.mail = {};
+ var mail = session.mail;
- openerp_mail_followers(session, mail); // import mail_followers.js
- openerp_FieldMany2ManyTagsEmail(session); // import manyy2many_tags_email.js
+ openerp_mail_followers(session, mail); // import mail_followers.js
+ openerp_FieldMany2ManyTagsEmail(session); // import manyy2many_tags_email.js
/**
* ------------------------------------------------------------
@@ -225,6 +225,7 @@ openerp.mail = function (session) {
this.name = datasets.name || false,
this.record_name = datasets.record_name || false,
this.body = datasets.body || '',
+ this.body_short = datasets.body_short || '',
this.vote_nb = datasets.vote_nb || 0,
this.has_voted = datasets.has_voted || false,
this.is_favorite = datasets.is_favorite || false,
@@ -237,8 +238,15 @@ openerp.mail = function (session) {
this.format_data();
+ // update record_name: Partner profile
+ if (this.model == 'res.partner') {
+ this.record_name = 'Partner Profile of ' + this.record_name;
+ }
+ else if (this.model == 'hr.employee') {
+ this.record_name = 'News from ' + this.record_name;
+ }
// record options and data
- this.show_record_name = this.options.show_record_name && this.record_name && !this.thread_level && this.model != 'res.partner';
+ this.show_record_name = this.options.show_record_name && this.record_name && !this.thread_level;
this.options.show_read = false;
this.options.show_unread = false;
if (this.options.show_read_unread_button) {
@@ -257,8 +265,10 @@ openerp.mail = function (session) {
/* Convert date, timerelative and avatar in displayable data. */
format_data: function () {
+
//formating and add some fields for render
this.date = this.date ? session.web.str_to_datetime(this.date) : false;
+ this.display_date = this.date.toString('ddd MMM dd yyyy HH:mm');
if (this.date && new Date().getTime()-this.date.getTime() < 7*24*60*60*1000) {
this.timerelative = $.timeago(this.date);
}
@@ -623,10 +633,7 @@ openerp.mail = function (session) {
// have unknown names -> call message_get_partner_info_from_emails to try to find partner_id
var find_done = $.Deferred();
if (names_to_find.length > 0) {
- var values = {
- 'res_id': this.context.default_res_id,
- }
- find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_find], values);
+ find_done = self.parent_thread.ds_thread._model.call('message_partner_info_from_emails', [this.context.default_res_id, names_to_find]);
}
else {
find_done.resolve([]);
@@ -672,11 +679,7 @@ openerp.mail = function (session) {
var new_names_to_find = _.difference(names_to_find, names_to_remove);
find_done = $.Deferred();
if (new_names_to_find.length > 0) {
- var values = {
- 'link_mail': true,
- 'res_id': self.context.default_res_id,
- }
- find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_find], values);
+ find_done = self.parent_thread.ds_thread._model.call('message_partner_info_from_emails', [self.context.default_res_id, new_names_to_find, true]);
}
else {
find_done.resolve([]);
@@ -745,7 +748,7 @@ openerp.mail = function (session) {
}
// 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] );
+ var message = thread.create_message_object( data.slice(-1)[0] );
// insert the message on dom
thread.insert_message( message, root ? undefined : self.$el, root );
});
@@ -942,7 +945,6 @@ openerp.mail = function (session) {
start: function () {
this._super.apply(this, arguments);
- this.expender();
this.bind_events();
if(this.thread_level < this.options.display_indented_thread) {
this.create_thread();
@@ -965,6 +967,26 @@ openerp.mail = function (session) {
this.$('.oe_reply').on('click', this.on_message_reply);
this.$('.oe_star').on('click', this.on_star);
this.$('.oe_msg_vote').on('click', this.on_vote);
+ this.$('.oe_mail_expand').on('click', this.on_expand);
+ this.$('.oe_mail_reduce').on('click', this.on_expand);
+ this.$('.oe_mail_action_model').on('click', this.on_record_clicked);
+ },
+
+ on_record_clicked: function (event) {
+ event.stopPropagation();
+ var state = {
+ 'model': this.model,
+ 'id': this.res_id,
+ 'title': this.record_name
+ };
+ session.webclient.action_manager.do_push_state(state);
+ this.do_action({
+ res_model: state.model,
+ res_id: state.id,
+ type: 'ir.actions.act_window',
+ views: [[false, 'form']]
+ });
+ return false;
},
/* Call the on_compose_message on the thread of this message. */
@@ -975,15 +997,11 @@ openerp.mail = function (session) {
return false;
},
- expender: function () {
- this.$('.oe_msg_body:first').expander({
- slicePoint: this.options.truncate_limit,
- expandText: 'read more',
- userCollapseText: 'read less',
- detailClass: 'oe_msg_tail',
- moreClass: 'oe_mail_expand',
- lessClass: 'oe_mail_reduce',
- });
+ on_expand: function (event) {
+ event.stopPropagation();
+ this.$('.oe_msg_body_short:first').toggle();
+ this.$('.oe_msg_body_long:first').toggle();
+ return false;
},
/**
@@ -1842,6 +1860,19 @@ openerp.mail = function (session) {
/**
* ------------------------------------------------------------
+ * Aside Widget
+ * ------------------------------------------------------------
+ *
+ * This widget handles the display of a sidebar on the Wall. Its main use
+ * is to display group and employees suggestion (if hr is installed).
+ */
+ mail.WallSidebar = session.web.Widget.extend({
+ template: 'mail.wall.sidebar',
+ });
+
+
+ /**
+ * ------------------------------------------------------------
* Wall Widget
* ------------------------------------------------------------
*
@@ -1901,6 +1932,9 @@ openerp.mail = function (session) {
if (! this.searchview.has_defaults) {
this.message_render();
}
+ // render sidebar
+ var wall_sidebar = new mail.WallSidebar(this);
+ wall_sidebar.appendTo(this.$el.find('.oe_mail_wall_aside'));
},
/**
@@ -2018,4 +2052,16 @@ openerp.mail = function (session) {
});
},
});
+
+
+ /**
+ * ------------------------------------------------------------
+ * Sub-widgets loading
+ * ------------------------------------------------------------
+ *
+ * Load here widgets that could depend on widgets defined in mail.js
+ */
+
+ openerp.mail.suggestions(session, mail); // import suggestion.js (suggestion widget)
+
};
diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js
index f812844194b..a0dad1fcdbc 100644
--- a/addons/mail/static/src/js/mail_followers.js
+++ b/addons/mail/static/src/js/mail_followers.js
@@ -29,7 +29,6 @@ openerp_mail_followers = function(session, mail) {
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 = [];
@@ -74,10 +73,33 @@ openerp_mail_followers = function(session, mail) {
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', self.on_invite_follower);
+ // event: click on 'edit_subtype(pencil)' button to edit subscription
+ this.$el.on('click', '.oe_edit_subtype', self.on_edit_subtype);
this.$el.on('click', '.oe_remove_follower', self.on_remove_follower);
this.$el.on('click', '.oe_show_more', self.on_show_more_followers)
},
+ on_edit_subtype: function(event) {
+ var self = this;
+ var $currentTarget = $(event.currentTarget);
+ var user_pid = $currentTarget.data('id');
+ $('div.oe_edit_actions').remove();
+ self.$dialog = new session.web.dialog($('<div class="oe_edit_actions">'), {
+ modal: true,
+ width: 'auto',
+ height: 'auto',
+ title: _t('Edit Subscription of ') + $currentTarget.siblings('a').text(),
+ buttons: [
+ { text: _t("Apply"), click: function() {
+ self.do_update_subscription(event, user_pid);
+ $(this).dialog("close");
+ }},
+ { text: _t("Cancel"), click: function() { $(this).dialog("close"); }}
+ ],
+ });
+ return self.fetch_subtypes(user_pid);
+ },
+
on_invite_follower: function (event) {
var self = this;
var action = {
@@ -130,7 +152,7 @@ openerp_mail_followers = function(session, mail) {
fetch_followers: function (value_) {
this.value = value_ || {};
- return this.ds_follow.call('read', [this.value, ['name', 'user_ids']])
+ return this.ds_model.call('read_followers_data', [this.value])
.then(this.proxy('display_followers'), this.proxy('fetch_generic'))
.then(this.proxy('display_buttons'))
.then(this.proxy('fetch_subtypes'));
@@ -147,6 +169,7 @@ openerp_mail_followers = function(session, mail) {
self.message_is_follower = (_.indexOf(self.value, pid) != -1);
}).then(self.proxy('display_generic'));
},
+
_format_followers: function(count){
var str = '';
if(count <= 0){
@@ -158,6 +181,7 @@ openerp_mail_followers = function(session, mail) {
}
return str;
},
+
/* Display generic info about follower, for people not having access to res_partner */
display_generic: function () {
var self = this;
@@ -168,16 +192,32 @@ openerp_mail_followers = function(session, mail) {
/** Display the followers */
display_followers: function (records) {
var self = this;
+ this.message_is_follower = false;
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(this.followers.length));
// truncate number of displayed followers
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, 'widget': self})).appendTo(node_user_list);
+ partner = {
+ 'id': record[0],
+ 'name': record[1],
+ 'is_uid': record[2]['is_uid'],
+ 'is_editable': record[2]['is_editable'],
+ 'avatar_url': mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record[0]),
+ }
+ if (partner.is_uid) {
+ self.message_is_follower = partner.is_uid;
+ }
+ $(session.web.qweb.render('mail.followers.partner', {'record': partner, 'widget': self})).appendTo(node_user_list);
+ // On mouse-enter it will show the edit_subtype pencil.
+ if (partner.is_editable) {
+ self.$('.oe_follower_list').on('mouseenter mouseleave', function(e) {
+ self.$('.oe_edit_subtype').toggleClass('oe_hidden', e.type == 'mouseleave');
+ self.$('.oe_follower_list').find('.oe_partner').toggleClass('oe_partner_name', e.type == 'mouseenter');
+ });
+ }
});
// FVA note: be sure it is correctly translated
if (truncated.length < this.followers.length) {
@@ -185,12 +225,6 @@ openerp_mail_followers = function(session, mail) {
}
},
- /** Computes whether the current user is in the followers */
- set_is_follower: function (records) {
- var user_ids = _.pluck(_.pluck(records, 'user_ids'), 0);
- return _.indexOf(user_ids, this.session.uid) != -1;
- },
-
display_buttons: function () {
if (this.message_is_follower) {
this.$('button.oe_follower').removeClass('oe_notfollow').addClass('oe_following');
@@ -206,25 +240,37 @@ openerp_mail_followers = function(session, mail) {
},
/** Fetch subtypes, only if current user is follower */
- fetch_subtypes: function () {
+ fetch_subtypes: function (user_pid) {
var self = this;
- var subtype_list_ul = this.$('.oe_subtype_list').empty();
- if (! this.message_is_follower) return;
+ var dialog = false;
+ if (user_pid) {
+ dialog = true;
+ } else {
+ var subtype_list_ul = this.$('.oe_subtype_list').empty();
+ if (! this.message_is_follower) return;
+ }
var id = this.view.datarecord.id;
- this.ds_model.call('message_get_subscription_data', [[id], new session.web.CompoundContext(this.build_context(), {})])
- .then(function (data) {self.display_subtypes(data, id);});
+ this.ds_model.call('message_get_subscription_data', [[id], user_pid, new session.web.CompoundContext(this.build_context(), {})])
+ .then(function (data) {self.display_subtypes(data, id, dialog);});
},
/** Display subtypes: {'name': default, followed} */
- display_subtypes:function (data, id) {
+ display_subtypes:function (data, id, dialog) {
var self = this;
- var $list = this.$('.oe_subtype_list');
+ if (dialog) {
+ var $list = self.$dialog;
+ }
+ else {
+ var $list = this.$('.oe_subtype_list');
+ }
$list.empty().hide();
var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
+ this.records_length = $.map(records, function(value, index) { return index; }).length;
+ if (this.records_length > 1) { self.display_followers(); }
_(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') );
+ $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo($list);
});
if (_.size(records) > 1) {
$list.show();
@@ -241,35 +287,49 @@ openerp_mail_followers = function(session, mail) {
});
},
- do_unfollow: function () {
+ do_unfollow: function (user_pid) {
if (confirm(_t("Warning! \nYou won't be notified of any email or discussion on this document. Do you really want to unfollow this document ?"))) {
_(this.$('.oe_msg_subtype_check')).each(function (record) {
$(record).attr('checked',false);
});
+ var action_unsubscribe = 'message_unsubscribe_users';
+ var follower_ids = [this.session.uid];
+ if (user_pid) {
+ action_unsubscribe = 'message_unsubscribe';
+ follower_ids = [user_pid];
+ }
var context = new session.web.CompoundContext(this.build_context(), {});
- return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], [this.session.uid], context])
- .then(this.proxy('read_value'));
+ return this.ds_model.call(action_unsubscribe, [[this.view.datarecord.id], follower_ids, context])
+ .then(this.proxy('read_value'));
}
return false;
},
- do_update_subscription: function (event) {
+ do_update_subscription: function (event, user_pid) {
var self = this;
+ var action_subscribe = 'message_subscribe_users';
+ var follower_ids = [this.session.uid];
+ var oe_action = this.$('.oe_actions input[type="checkbox"]');
+ if (user_pid) {
+ action_subscribe = 'message_subscribe';
+ follower_ids = [user_pid];
+ oe_action = $('.oe_edit_actions input[type="checkbox"]');
+ }
var checklist = new Array();
- _(this.$('.oe_actions input[type="checkbox"]')).each(function (record) {
+ _(oe_action).each(function (record) {
if ($(record).is(':checked')) {
checklist.push(parseInt($(record).data('id')));
}
});
if (!checklist.length) {
- if (!this.do_unfollow()) {
+ if (!this.do_unfollow(user_pid)) {
$(event.target).attr("checked", "checked");
}
} 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])
+ return this.ds_model.call(action_subscribe, [[this.view.datarecord.id], follower_ids, checklist, context])
.then(this.proxy('read_value'));
}
},
diff --git a/addons/mail/static/src/js/suggestions.js b/addons/mail/static/src/js/suggestions.js
new file mode 100644
index 00000000000..4d0fcec32bf
--- /dev/null
+++ b/addons/mail/static/src/js/suggestions.js
@@ -0,0 +1,77 @@
+openerp.mail.suggestions = function(session, mail) {
+ var _t = session.web._t;
+ var QWeb = session.web.qweb;
+
+ var suggestions = session.suggestions = {};
+ var removed_suggested_group = session.suggestions.removed_suggested_group = [];
+
+ suggestions.Groups = session.web.Widget.extend({
+ events: {
+ 'click .oe_suggestion_remove.oe_suggestion_group': 'stop_group_suggestion',
+ 'click .oe_suggestion_remove_item.oe_suggestion_group': 'remove_group_suggestion',
+ 'click .oe_suggestion_join': 'join_group',
+ },
+
+ init: function () {
+ this._super.apply(this, arguments);
+ this.mail_group = new session.web.DataSetSearch(this, 'mail.group');
+ this.res_users = new session.web.DataSetSearch(this, 'res.users');
+ this.groups = [];
+ },
+
+ start: function () {
+ this._super.apply(this, arguments);
+ return this.fetch_suggested_groups();
+ },
+
+ fetch_suggested_groups: function () {
+ var self = this;
+ var group = self.mail_group.call('get_suggested_thread', {'removed_suggested_threads': removed_suggested_group}).then(function (res) {
+ _(res).each(function (result) {
+ result['image']=self.session.url('/web/binary/image', {model: 'mail.group', field: 'image_small', id: result.id});
+ });
+ self.groups = res;
+ });
+ return $.when(group).then(this.proxy('display_suggested_groups'));
+ },
+
+ display_suggested_groups: function () {
+ var suggested_groups = this.$('.oe_sidebar_suggestion.oe_suggestion_group');
+ if (suggested_groups) {
+ suggested_groups.empty();
+ }
+ if (this.groups.length === 0) {
+ return this.$el.empty();
+ }
+ return this.$el.empty().html(QWeb.render('mail.suggestions.groups', {'widget': this}));
+ },
+
+ join_group: function (event) {
+ var self = this;
+ return this.mail_group.call('message_subscribe_users', [[$(event.currentTarget).attr('id')],[this.session.uid]]).then(function(res) {
+ self.fetch_suggested_groups();
+ });
+ },
+
+ remove_group_suggestion: function (event) {
+ removed_suggested_group.push($(event.currentTarget).attr('id'));
+ return this.fetch_suggested_groups();
+ },
+
+ stop_group_suggestion: function (event) {
+ var self = this;
+ return this.res_users.call('stop_showing_groups_suggestions', [this.session.uid]).then(function(res) {
+ self.$(".oe_sidebar_suggestion.oe_suggestion_group").hide();
+ });
+ }
+ });
+
+ session.mail.WallSidebar.include({
+ start: function () {
+ this._super.apply(this, arguments);
+ var sug_groups = new suggestions.Groups(this);
+ return sug_groups.appendTo(this.$('.oe_suggestions_groups'));
+ },
+ });
+
+};
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index f5004941a8d..1be9754e1c7 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -121,9 +121,11 @@
To:
<t t-if="!widget.is_private">
<span class="oe_all_follower">
- Followers of
- <t t-if="widget.parent_thread.parent_message.record_name" t-raw="'&quot;' + widget.parent_thread.parent_message.record_name + '&quot;'"/>
- <t t-if="!widget.parent_thread.parent_message.record_name">this document</t>
+ <t t-if="widget.parent_thread.parent_message.record_name" t-raw="'&quot;' + widget.parent_thread.parent_message.record_name + '&quot;'">
+ Followers of <t t-raw="'&quot;' + widget.parent_thread.parent_message.record_name + '&quot;'"/>
+ </t>
+ <t t-if="!widget.parent_thread.parent_message.record_name and widget.options.view_inbox">My Followers</t>
+ <t t-if="!widget.parent_thread.parent_message.record_name and !widget.options.view_inbox">Followers of this document</t>
</span>
</t>
<t t-if="!widget.is_private and (widget.partner_ids.length or (widget.author_id and widget.author_id[0]))"> and </t>
@@ -197,9 +199,17 @@
</tbody>
</table>
<div class="oe_mail-placeholder"></div>
+ <aside class="oe_mail_wall_aside"></aside>
</div>
<!--
+ Empty template that holds the sidebar of the Wall
+ -->
+ <t t-name="mail.wall.sidebar">
+ <div class="oe_mail_wall_sidebar"></div>
+ </t>
+
+ <!--
display message on the wall when there are no message
-->
<t t-name="mail.wall_no_message">
@@ -256,7 +266,13 @@
<t t-if="widget.subject" t-raw="widget.subject"/>
</h1>
<div class="oe_msg_body">
- <t t-raw="widget.body"/>
+ <t t-if="widget.body_short">
+ <div class="oe_msg_body_short"><t t-raw="widget.body_short"/></div>
+ <div class="oe_msg_body_long" style="display: none;"><t t-raw="widget.body"/><span class="oe_mail_reduce"><a href="#">read less</a></span></div>
+ </t>
+ <t t-if="! widget.body_short">
+ <t t-raw="widget.body"/>
+ </t>
</div>
</div>
<div class="oe_msg_footer">
@@ -271,16 +287,16 @@
<span class='oe_subtle'>•</span>
</t>
</t>
- <t t-if="widget.type == 'comment' and ! widget.subtype">
+ <t t-if="widget.type == 'comment' and ! widget.subtype and widget.partner_ids.length == 0">
logged a note
</t>
- <t t-if="(widget.type == 'comment' or widget.type == 'email') and widget.subtype">
+ <t t-if="(widget.type == 'comment' or widget.type == 'email') and (widget.subtype or widget.partner_ids.length > 0)">
to
<t t-if="widget.partner_ids.length == 0">
nobody
</t>
</t>
- <t t-if="widget.type == 'notification' or ( (widget.type == 'email' or widget.type == 'comment') and widget.subtype)"
+ <t t-if="widget.type == 'notification' or ( (widget.type == 'email' or widget.type == 'comment') and (widget.subtype or widget.partner_ids.length > 0))"
t-foreach="widget.partner_ids.slice(0, 3)" t-as="partner">
<span t-attf-class="oe_partner_follower">
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&amp;id=#{partner[0]}"><t t-raw="partner[1]"/></a>
@@ -295,7 +311,10 @@
notified
</t>
<span class='oe_subtle'>•</span>
- <span t-att-title="widget.date"><t t-if="widget.timerelative" t-raw="widget.timerelative"/><t t-if="!widget.timerelative" t-raw="widget.date"/></span>
+ <span t-att-title="widget.date">
+ <t t-if="widget.timerelative" t-raw="widget.timerelative"/>
+ <t t-if="!widget.timerelative" t-raw="widget.display_date"/>
+ </span>
<span t-if="!widget.options.readonly" class='oe_subtle'>•</span>
<t t-if="!widget.options.readonly" t-call="mail.thread.message.vote"/>
</div>
@@ -339,7 +358,4 @@
</a>
</span>
- <!-- mail.thread.message.star
- Template used to display stared/unstared message in a mail.message
- -->
</template>
diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml
index 5ad3ff09bb3..a936b8237d6 100644
--- a/addons/mail/static/src/xml/mail_followers.xml
+++ b/addons/mail/static/src/xml/mail_followers.xml
@@ -31,6 +31,7 @@
<div t-name="mail.followers.partner" class='oe_partner'>
<img class="oe_mail_thumbnail oe_mail_frame" t-attf-src="{record.avatar_url}"/>
<a t-attf-href="#model=res.partner&amp;id=#{record.id}" t-att-title="record.name"><t t-esc="record.name"/></a>
+ <span t-if="record.is_editable and (widget.records_length &gt; 1)" class="oe_edit_subtype oe_e oe_hidden" title="Edit subscription" t-att-data-id="record.id">&amp;</span>
<span t-if="widget.view_is_editable" class="oe_remove_follower oe_e" title="Remove this follower" t-att-data-id="record.id">X</span>
</div>
diff --git a/addons/mail/static/src/xml/suggestions.xml b/addons/mail/static/src/xml/suggestions.xml
new file mode 100644
index 00000000000..9157dcbe32e
--- /dev/null
+++ b/addons/mail/static/src/xml/suggestions.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template>
+
+ <!-- Groups placeholder in sidebar -->
+ <t t-extend="mail.wall.sidebar">
+ <t t-jquery=".oe_mail_wall_sidebar" t-operation="append">
+ <div class="oe_suggestions_groups"></div>
+ </t>
+ </t>
+
+
+ <!-- Suggested groups -->
+ <div t-name="mail.suggestions.groups" class="oe_sidebar_suggestion oe_suggestion_group">
+ <div class="oe_suggest_title">
+ <a class="oe_suggestion_remove oe_suggestion_group oe_e">X</a>
+ <h2>Suggested Groups</h2>
+ </div>
+ <div class="oe_suggest_items">
+ <t t-foreach="widget.groups" t-as="result">
+ <div class="oe_suggested_item">
+ <div class="oe_suggested_item_image">
+ <a t-attf-href="#model=mail.group&amp;id=#{result.id}">
+ <img t-attf-src="{result.image}" t-attf-alt="{result.name}"/>
+ </a>
+ </div>
+ <div class="oe_suggested_item_content">
+ <a class="oe_suggestion_item_name" t-attf-href="#model=mail.group&amp;id=#{result.id}"><t t-esc="result.name"/></a>
+ <a class="oe_suggestion_remove_item oe_suggestion_group oe_e" t-attf-id="{result.id}">X</a>
+ <br/>
+ <button t-att-id="result.id" class="oe_suggestion_join">Join Group</button>
+ </div>
+ </div>
+ </t>
+ </div>
+ </div>
+
+
+</template>