diff options
| author | Aaron Bohy <aab@odoo.com> | 2015-08-20 15:29:54 +0200 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2015-09-01 20:57:13 +0200 |
| commit | a0cbf891af58f029e2c52779617ad7eeb8d26eb3 (patch) | |
| tree | 92091e11e51a025f91427d51d1abc614090369ea | |
| parent | 58a46c90cd896772a0b462379bd0a5a440877993 (diff) | |
[REM] *: remove chat menu and timeline view
25 files changed, 46 insertions, 2623 deletions
diff --git a/addons/gamification/__openerp__.py b/addons/gamification/__openerp__.py index c73a73c02d5..cc1a06d8feb 100644 --- a/addons/gamification/__openerp__.py +++ b/addons/gamification/__openerp__.py @@ -35,5 +35,4 @@ Both goals and badges are flexibles and can be adapted to a large range of modul ], 'application': False, 'auto_install': False, - 'qweb': ['static/src/xml/gamification.xml'], } diff --git a/addons/gamification/static/src/css/gamification.css b/addons/gamification/static/src/css/gamification.css index a2c416ffc2d..68479e58760 100644 --- a/addons/gamification/static/src/css/gamification.css +++ b/addons/gamification/static/src/css/gamification.css @@ -1,146 +1,65 @@ -@charset "UTF-8"; .openerp .oe_kanban_view .oe_kanban_card.oe_kanban_goal { width: 230px; - min-height: 200px; } + min-height: 200px; +} .openerp .oe_kanban_view .oe_kanban_card.oe_kanban_badge { width: 250px; - min-height: 150px; } + min-height: 150px; +} .openerp .oe_kanban_badge_avatars { - margin-top: 8px; } - .openerp .oe_kanban_badge_avatars img { - width: 30px; - height: 30px; - padding-left: 0; - margin-top: 3px; - border-radius: 2px; - -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } + margin-top: 8px; +} +.openerp .oe_kanban_badge_avatars img { + width: 30px; + height: 30px; + padding-left: 0; + margin-top: 3px; + border-radius: 2px; + -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} .openerp .oe_margin_top_8 { - margin-top: 8px; } + margin-top: 8px; +} .openerp .oe_margin_top_16 { - margin-top: 16px; } + margin-top: 16px; +} .openerp .oe_kanban_goal .oe_goal_state_block { width: 200px; height: 130px; margin: auto; - margin-bottom: -20px; } - .openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state { - font-size: 2.5em; - font-weight: bold; - padding-top: 30px; } - .openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state .fa { - font-size: 3em; - margin-top: -17px; - margin-left: 17px; } + margin-bottom: -20px; +} +.openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state { + font-size: 2.5em; + font-weight: bold; + padding-top: 30px; +} +.openerp .oe_kanban_goal .oe_goal_state_block .oe_goal_state .fa { + font-size: 3em; + margin-top: -17px; + margin-left: 17px; +} .openerp .oe_kanban_goal .oe_goal_state_block, .openerp .oe_kanban_goal p { - text-align: center; } + text-align: center; +} .openerp .oe_kanban_content .oe_goal_gauge:first-child { - margin: auto; } + margin: auto; +} .openerp .oe_kanban_content .oe_goal_gauge svg { - margin-top: -20px; } + margin-top: -20px; +} .openerp .oe_no_overflow { - overflow: hidden; } + overflow: hidden; +} .openerp .oe_red { - color: red; } + color: red; +} .openerp .oe_green { - color: green; } + color: green; +} .openerp .oe_orange { - color: orange; } + color: orange; +} .openerp .oe_form td .oe_no_padding { - margin-left: -6px; } -.openerp .oe_timeline .oe_tl_inbox_aside .oe_gamification_suggestion { - background-color: #d3def1; } - .openerp .oe_timeline .oe_tl_inbox_aside .oe_gamification_suggestion ul { - padding-left: 15px; } - .openerp .oe_timeline .oe_tl_inbox_aside .oe_gamification_suggestion span { - background-color: #f0eeee; - display: inline-block; - height: 25px; - vertical-align: middle; - font-size: 14px; - font-weight: bold; - margin-top: -20px; - padding-left: 0 5px 0px 5px; } -.openerp .oe_timeline .oe_goal { - background-color: #f0eeee; - border: solid 1px #cacaca; - margin-top: 20px; - padding-left: 10px; } - .openerp .oe_timeline .oe_goal .oe_update_challenge.fa, .openerp .oe_timeline .oe_goal .oe_goal_action.fa { - visibility: hidden; - font-size: 16px; - float: right; - position: relative; } - .openerp .oe_timeline .oe_goal div:hover > .oe_update_challenge, .openerp .oe_timeline .oe_goal div:hover > .oe_goal_action, .openerp .oe_timeline .oe_goal th:hover > .oe_goal_action { - visibility: visible; } - .openerp .oe_timeline .oe_goal .oe_goals_list { - padding-left: 0; - margin-top: 5px; - margin-bottom: 10px; - width: 100%; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_no_progress div { - display: inline-block; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_no_progress::before { - content: "•"; - padding-right: 4px; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_no_progress.oe_goal_reached::before { - content: "✓"; - padding-right: 0; - margin-left: -2px; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_no_progress.oe_goal_reached .oe_cell { - text-decoration: line-through; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_cell.oe_goal_current { - font-size: 150%; - font-weight: bold; - min-width: 50px; - padding: 0 5px; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_goal_outer_box { - display: inline-block; - position: relative; - z-index: 0; - vertical-align: middle; - width: 100%; - border: solid 1px rgba(0, 0, 0, 0.03); - border-radius: 2px; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_goal_outer_box.oe_no_progress { - border: none; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_goal_progress_background { - background-color: white; - position: absolute; - height: 100%; - width: 100%; - z-index: -2; - top: 0; - left: 0; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_goal_progress { - background-color: #d4e9de; - position: absolute; - height: 100%; - width: 0; - z-index: -1; - top: 0; - left: 0; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_thead { - font-weight: normal; - padding: 5px; - text-align: center; } - .openerp .oe_timeline .oe_goal .oe_goals_list .oe_cell { - padding: 3px 0; } -.openerp .oe_timeline .oe_table.oe_goals_list .col0 { - font-size: 200%; - font-weight: bold; - width: 25px; - text-align: center; } -.openerp .oe_timeline .oe_table.oe_goals_list .col1 { - padding: 0 5px; } -.openerp .oe_timeline .oe_table.oe_goals_list .col2 { - width: auto; } -.openerp .oe_timeline .oe_user_avatar { - width: 24px; - padding-right: 5px; } -.openerp .oe_timeline .oe_table { - display: table; } -.openerp .oe_timeline .oe_row { - display: table-row; } -.openerp .oe_timeline .oe_cell { - display: table-cell; - vertical-align: middle; } + margin-left: -6px; +} diff --git a/addons/gamification/static/src/css/gamification.sass b/addons/gamification/static/src/css/gamification.sass index b524c9486b8..cbba41e05fb 100644 --- a/addons/gamification/static/src/css/gamification.sass +++ b/addons/gamification/static/src/css/gamification.sass @@ -61,118 +61,3 @@ // compensate padding from .openerp .oe_form td.oe_form_group_cell + .oe_form_group_cell .oe_form td .oe_no_padding margin-left: -6px - - .oe_timeline - .oe_tl_inbox_aside - .oe_gamification_suggestion - background-color: #d3def1 - - ul - padding-left: 15px - - span - background-color: #f0eeee - display: inline-block - height: 25px - vertical-align: middle - font-size: 14px - font-weight: bold - margin-top: -20px - padding-left: 0 5px 0px 5px - - .oe_goal - background-color: #f0eeee - border: solid 1px #CACACA - margin-top: 20px - padding-left: 10px - .oe_update_challenge.fa, .oe_goal_action.fa - visibility: hidden - font-size: 16px - float: right - position: relative - div:hover > .oe_update_challenge, div:hover > .oe_goal_action, th:hover > .oe_goal_action - visibility: visible - .oe_goals_list - padding-left: 0 - margin-top: 5px - margin-bottom: 10px - width: 100% - - .oe_no_progress - div - display: inline-block - .oe_no_progress::before - content: "•" - padding-right: 4px - .oe_no_progress.oe_goal_reached::before - content: "✓" - padding-right: 0 - margin-left: -2px - .oe_no_progress.oe_goal_reached - .oe_cell - text-decoration: line-through - - .oe_cell.oe_goal_current - font-size: 150% - font-weight: bold - min-width: 50px - padding: 0 5px - - .oe_goal_outer_box - display: inline-block - position: relative - z-index: 0 - vertical-align: middle - width: 100% - border: solid 1px rgba(0,0,0,0.03) - border-radius: 2px - .oe_goal_outer_box.oe_no_progress - border: none - - .oe_goal_progress_background - background-color: white - position: absolute - height: 100% - width: 100% - z-index: -2 - top: 0 - left: 0 - - .oe_goal_progress - background-color: rgb(212, 233, 222) - position: absolute - height: 100% - width: 0 - z-index: -1 - top: 0 - left: 0 - - .oe_thead - font-weight: normal - padding: 5px - text-align: center - .oe_cell - padding: 3px 0 - - .oe_table.oe_goals_list - .col0 - font-size: 200% - font-weight: bold - width: 25px - text-align: center - .col1 - padding: 0 5px - .col2 - width: auto - - .oe_user_avatar - width: 24px - padding-right: 5px - - .oe_table - display: table - .oe_row - display: table-row - .oe_cell - display: table-cell - vertical-align: middle
\ No newline at end of file diff --git a/addons/gamification/static/src/js/gamification.js b/addons/gamification/static/src/js/gamification.js deleted file mode 100644 index 1a096d2e681..00000000000 --- a/addons/gamification/static/src/js/gamification.js +++ /dev/null @@ -1,122 +0,0 @@ -odoo.define('gamification.gamification', function(require) { -"use strict"; - -var mail = require('mail.mail'); -var core = require('web.core'); -var form_common = require('web.form_common'); -var Model = require('web.DataModel'); -var session = require('web.session'); -var Widget = require('web.Widget'); - -var QWeb = core.qweb; - -var Sidebar = Widget.extend({ - template: 'gamification.UserWallSidebar', - init: function (parent, action) { - this._super(parent, action); - this.deferred = $.Deferred(); - this.goals_info = {}; - this.challenge_suggestions = {}; - $(document).off('keydown.klistener'); - }, - events: { - // update a challenge and related goals - 'click i.oe_update_challenge': function(event) { - var self = this; - var challenge_id = parseInt(event.currentTarget.id, 10); - var goals_updated = new Model('gamification.challenge').call('quick_update', [challenge_id]); - $.when(goals_updated).done(function() { - self.get_goal_todo_info(); - }); - }, - // action to modify a goal - 'click a.oe_goal_action': function(event) { - var self = this; - var goal_id = parseInt(event.currentTarget.id, 10); - var goal_action = new Model('gamification.goal').call('get_action', [goal_id]).then(function(res) { - goal_action.action = res; - }); - $.when(goal_action).done(function() { - var action = self.do_action(goal_action.action); - $.when(action).done(function () { - new Model('gamification.goal').call('update', [[goal_id]]).then(function(res) { - self.get_goal_todo_info(); - }); - }); - }); - }, - // get more info about a challenge request - 'click a.oe_challenge_reply': function(event) { - var self = this; - var challenge_id = parseInt(event.currentTarget.id, 10); - var challenge_action = new Model('gamification.challenge').call('reply_challenge_wizard', [challenge_id]).then(function(res) { - challenge_action.action = res; - }); - $.when(challenge_action).done(function() { - self.do_action(challenge_action.action).done(function () { - self.get_goal_todo_info(); - }); - }); - } - }, - start: function() { - var self = this; - this._super.apply(this, arguments); - self.get_goal_todo_info(); - self.get_challenge_suggestions(); - }, - get_goal_todo_info: function() { - var self = this; - var challenges = new Model('res.users').call('get_serialised_gamification_summary', []).then(function(result) { - if (result.length === 0) { - self.$el.find(".oe_gamification_challenge_list").hide(); - } else { - self.$el.find(".oe_gamification_challenge_list").empty(); - _.each(result, function(item){ - var $item = $(QWeb.render("gamification.ChallengeSummary", {challenge: item})); - self.render_money_fields($item); - self.render_user_avatars($item); - self.$el.find('.oe_gamification_challenge_list').append($item); - }); - } - }); - }, - get_challenge_suggestions: function() { - var self = this; - var challenge_suggestions = new Model('res.users').call('get_challenge_suggestions', []).then(function(result) { - if (result.length === 0) { - self.$el.find(".oe_gamification_suggestion").hide(); - } else { - var $item = $(QWeb.render("gamification.ChallengeSuggestion", {challenges: result})); - self.$el.find('.oe_gamification_suggestion').append($item); - } - }); - }, - render_money_fields: function(item) { - var self = this; - var FieldMonetary = core.form_widget_registry.get('monetary'); - self.dfm = new form_common.DefaultFieldManager(self); - // Generate a FieldMonetary for each .oe_goal_field_monetary - item.find(".oe_goal_field_monetary").each(function() { - var currency_id = parseInt( $(this).attr('data-id'), 10); - var money_field = new FieldMonetary(self.dfm, { - attrs: { - modifiers: '{"readonly": true}' - } - }); - money_field.set('currency', currency_id); - money_field.get_currency_info(); - money_field.set('value', parseInt($(this).text(), 10)); - money_field.replace($(this)); - }); - }, - render_user_avatars: function(item) { - item.find(".oe_user_avatar").each(function() { - var user_id = parseInt( $(this).attr('data-id'), 10); - var url = session.url('/web/image', {model: 'res.users', field: 'image_small', id: user_id}); - $(this).attr("src", url); - }); - } -}); - -}); diff --git a/addons/gamification/static/src/xml/gamification.xml b/addons/gamification/static/src/xml/gamification.xml deleted file mode 100644 index 570cfe936d1..00000000000 --- a/addons/gamification/static/src/xml/gamification.xml +++ /dev/null @@ -1,114 +0,0 @@ -<templates> - <t t-name="gamification.UserWallSidebar" class="oe_gamification_user_wall_sidebar"> - <div> - <div class="oe_gamification_suggestion"></div> - <div class="oe_gamification_challenge_list"></div> - </div> - </t> - <t t-name="gamification.ChallengeSummary"> - <div class="oe_goal"> - <div class="oe_gamification_title"> - <i class="oe_update_challenge fa fa-refresh" rol="button" t-attf-id="{challenge.id}"/> - <span><t t-esc="challenge.name" /></span> - </div> - - <t t-if="challenge.visibility_mode == 'personal'"> - <div class="oe_table oe_goals_list"> - <div t-foreach="challenge.lines" t-as="line" t-attf-class="oe_row oe_goal_outer_box #{line.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}"> - <t t-if="line.display_mode == 'progress'"> - <div class="oe_goal_progress_background"></div> - <div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+line.completeness+'%;' : 'width:0;'}"></div> - <div class="oe_cell oe_goal_current"><t t-esc="line.current" /></div> - </t> - <div class="oe_cell"> - <t t-if="line.computation_mode != 'manually' and !line.action"> - <span t-att-title="line.description"><t t-esc="line.name" /></span> - </t> - <t t-if="line.action or line.computation_mode == 'manually'"> - <span t-att-title="line.description"><a class="oe_goal_action" t-att-id="line.id"><t t-esc="line.name" /></a></span> - </t> - <t t-if="line.display_mode == 'progress'"><br/> - <div class="oe_grey"> - <t t-if="line.definition_condition == 'higher'"> - Target: - </t> - <t t-if="line.definition_condition == 'lower'"> - Target: <= - </t> - <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="line.target"/></span> - <t t-if="line.suffix"><t t-esc="line.suffix"/></t> - </div> - </t> - </div> - </div> - </div> - </t> - - <t t-if="challenge.visibility_mode == 'ranking'"> - <div t-foreach="challenge.lines" t-as="line" class="oe_goals_list oe_table"> - <div class="oe_row"> - <div class="oe_cell oe_thead" colspan="3" t-attf-title="#{line.description ? line.description : ''}"> - <strong><t t-esc="line.name"/></strong> - <br/> - <div class="oe_grey"> - <t t-if="line.definition_condition == 'higher'"> - Target: - </t> - <t t-if="line.definition_condition == 'lower'"> - Target: <= - </t> - <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="line.target" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> - </div> - </div> - </div> - <div t-foreach="line.goals" t-as="goal" t-attf-class="#{goal.id == line.own_goal_id ? 'oe_bold' : ''}"> - <div t-attf-class="oe_row oe_goal_outer_box #{goal.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}"> - <t t-if="line.display_mode == 'progress'"> - <div class="oe_goal_progress_background"></div> - <div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+goal.completeness+'%;' : 'width:0;'}"></div> - </t> - - <div class="oe_cell col0"><t t-esc="goal.rank" /></div> - <div class="oe_cell col1"><img class="oe_user_avatar" t-attf-alt="#{goal.name}" t-attf-data-id="#{goal.user_id}"/></div> - <div class="oe_cell col2"> - <t t-if="line.display_mode == 'progress'"> - <!-- progress, action on current value --> - <t t-esc="goal.name"/><br/> - <t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)"> - <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> - </t> - <t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')"> - <a class="oe_goal_action" t-att-id="line.own_goal_id"> - <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> - </a> - </t> - </t> - <t t-if="line.display_mode != 'progress'"> - <!-- not progress, action on user name --> - <t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)"> - <t t-esc="goal.name"/> - </t> - <t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')"> - <a class="oe_goal_action" t-att-id="line.own_goal_id"><t t-esc="goal.name"/></a> - </t> - </t> - </div> - </div> - </div> - </div> - </t> - </div> - </t> - - <t t-name="gamification.ChallengeSuggestion"> - <div class="oe_goal"> - <h4>Invited Challenges</h4> - <ul t-foreach="challenges" t-as="challenge" class="oe_goals_list"> - <li> - <strong><a class="oe_challenge_reply" t-attf-title="#{challenge.description.value ? challenge.description.value : ''}" t-attf-id="{challenge.id}" title="more details..."><t t-esc="challenge.name"/></a></strong> - </li> - </ul> - </div> - </t> - -</templates> diff --git a/addons/gamification/views/gamification.xml b/addons/gamification/views/gamification.xml index 1e2f0096ea5..e99848b9f9d 100644 --- a/addons/gamification/views/gamification.xml +++ b/addons/gamification/views/gamification.xml @@ -4,7 +4,6 @@ <template id="assets_backend" name="gamification assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <link rel="stylesheet" href="/gamification/static/src/css/gamification.css"/> - <script type="text/javascript" src="/gamification/static/src/js/gamification.js"></script> </xpath> </template> </data> diff --git a/addons/hr/__openerp__.py b/addons/hr/__openerp__.py index d8a0d34fe8a..6fecf886d24 100644 --- a/addons/hr/__openerp__.py +++ b/addons/hr/__openerp__.py @@ -41,7 +41,6 @@ You can manage: 'hr_data.xml', 'hr_tip_data.xml', 'res_config_view.xml', - 'mail_hr_view.xml', 'views/hr.xml', 'hr_dashboard.xml', ], diff --git a/addons/hr/mail_hr_view.xml b/addons/hr/mail_hr_view.xml deleted file mode 100644 index 39c28cfa07f..00000000000 --- a/addons/hr/mail_hr_view.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<openerp> - <data> - <record model="ir.actions.act_window" id="mail.mail_message_action_inbox"> - <field name="name">Inbox</field> - <field name="res_model">mail.message</field> - <field name="view_type">form</field> - <field name="view_mode">timeline</field> - <field name="context">{ - 'default_model': 'res.users', - 'default_res_id': uid, - 'thread_model': 'res.partner', - 'options' : {'view_mailbox': True, - 'view_inbox': True, - 'show_write_to_followers': True} - }</field> - <field name="domain">[ - ('needaction', '=', True) - ]</field> - </record> - </data> -</openerp>
\ No newline at end of file diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py index ca88214169e..58021bb2c9f 100644 --- a/addons/mail/__openerp__.py +++ b/addons/mail/__openerp__.py @@ -34,7 +34,6 @@ Main Features 'views/mail_message_views.xml', 'views/mail_mail_views.xml', 'views/mail_followers_views.xml', - 'views/mail_thread_views.xml', 'views/mail_channel_views.xml', 'views/mail_shortcode_views.xml', 'views/res_config_views.xml', @@ -59,7 +58,6 @@ Main Features 'installable': True, 'application': True, 'qweb': [ - 'static/src/xml/mail.xml', 'static/src/xml/mail_thread.xml', 'static/src/xml/mail_chatter.xml', 'static/src/xml/mail_chat_common.xml', diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index ca5ee18b468..97cd5c26513 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -41,17 +41,6 @@ <field name="args">()</field> </record> - <!-- After installation of the module, open the related menu --> - <record id="action_client_messaging_menu" model="ir.actions.client"> - <field name="name">Open Messaging Menu</field> - <field name="tag">reload</field> - <field name="params" eval="{'menu_id': ref('mail.mail_thread_menu_root')}"/> - </record> - <record id="base.open_menu" model="ir.actions.todo"> - <field name="action_id" ref="action_client_messaging_menu"/> - <field name="state">open</field> - </record> - <!-- Admin should not receivve emails at creation --> <record id="base.partner_root" model="res.partner"> <field name="notify_email">none</field> diff --git a/addons/mail/static/src/audio/purr.mp3 b/addons/mail/static/src/audio/purr.mp3 Binary files differdeleted file mode 100644 index 849d303c3b1..00000000000 --- a/addons/mail/static/src/audio/purr.mp3 +++ /dev/null diff --git a/addons/mail/static/src/audio/purr.ogg b/addons/mail/static/src/audio/purr.ogg Binary files differdeleted file mode 100644 index 2ddc77537f1..00000000000 --- a/addons/mail/static/src/audio/purr.ogg +++ /dev/null diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js deleted file mode 100644 index 8064fca4ee1..00000000000 --- a/addons/mail/static/src/js/mail.js +++ /dev/null @@ -1,1468 +0,0 @@ -odoo.define('mail.mail', function (require) { -"use strict"; - -var ajax = require('web.ajax'); -var mail_utils = require('mail.utils'); -var core = require('web.core'); -var data = require('web.data'); -var Dialog = require('web.Dialog'); -var form_common = require('web.form_common'); -var session = require('web.session'); -var SystrayMenu = require('web.SystrayMenu'); -var time = require('web.time'); -var utils = require('web.utils'); -var web_client = require('web.web_client'); -var Widget = require('web.Widget'); -var View = require('web.View'); -var formats = require('web.formats'); - -var _t = core._t; -var QWeb = core.qweb; - -/** - * ------------------------------------------------------------ - * TimelineRecordThread (mail_thread Widget) - * ------------------------------------------------------------ - * - * This widget instantiates the timeline view on a document. Its - * main use is to receive a context and a domain, then display the - * timeline view. - */ -var TimelineRecordThread = form_common.AbstractField.extend ({ - className: 'o_timeline_record_thread', - - init: function (parent, node) { - this._super.apply(this, arguments); - - this.parent = parent; - this.dataset = new data.DataSet(this, 'mail.message', this.view.dataset.context); - this.domain = (this.node.params && this.node.params.domain) || (this.field && this.field.domain) || []; - - this.opts = _.extend({ - 'show_reply_button': false, - 'show_read_unread_button': true, - 'read_action': 'unread', - 'show_record_name': false, - 'show_compact_message': true, - 'compose_as_todo': false, - 'view_inbox': false, - 'view_mailbox': false, - 'emails_from_on_composer': true, - 'fetch_limit': 20, - 'readonly': this.node.attrs.readonly || false, - 'compose_placeholder' : this.node.attrs.placeholder || false, - 'display_log_button' : this.options.display_log_button || true, - 'internal_subtypes' : this.options.internal_subtypes || [], - 'show_compose_message': true, - 'show_link': this.parent.is_action_enabled('edit') || true, - }, this.node.params); - }, - - start: function () { - this.view.on("change:actual_mode", this, this._check_visibility); - this._check_visibility(); - - this.timeline_view = new TimelineView(this, this.dataset, false, this.opts); - this._super.apply(this, arguments); - - return this.timeline_view.appendTo(this.$el); - }, - - _check_visibility: function () { - this.do_toggle(this.view.get("actual_mode") !== "create"); - }, - - render_value: function () { - if (! this.view.datarecord.id || data.BufferedDataSet.virtual_id_regex.test(this.view.datarecord.id)) { - return; - } - - this.timeline_view.set_message_ids(this.get_value()); - - var domain = (this.domain || []).concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]); - var context = { - 'mail_read_set_read': true, - 'default_res_id': this.view.datarecord.id || false, - 'default_model': this.view.model || false, - }; - - return this.timeline_view.do_search(domain, context); - } -}); - -/** - * ------------------------------------------------------------ - * Timeline View - * ------------------------------------------------------------ - * - * This widget handles the display of messages on a document and in - * the inbox. Its main use is to receive a context and a domain, and - * to delegate the message fetching and displaying to the MailThread - * widget. - */ -var TimelineView = View.extend ({ - display_name: _t('Timeline'), - view_type: 'timeline', - template: 'TimelineWall', - - init: function (parent, dataset, view_id, options) { - this._super(parent, dataset, view_id, options); - - this.model = dataset.model; - this.domain = dataset.domain || []; - this.context = dataset.context || {}; - this.parent_view = parent.parent ? parent.parent : this; - - var opt = _.clone(this.context.options); - this.options = options || {}; - this.options = _.extend(this.options, (opt || {})); - this.options = _.extend({ - 'show_link': true, - 'show_reply_button': true, - 'show_read_unread_button': true, - 'fetch_limit': 15, - 'fetch_child_limit': 5, - }, this.options); - - this.fields_view = {}; - this.fields_keys = []; - - this.qweb = new QWeb2.Engine(); - this.has_been_loaded = $.Deferred(); - }, - - view_loading: function (fields_view_get) { - return this.load_timeline(fields_view_get); - }, - - load_timeline: function (fields_view_get) { - var self = this; - - this.fields_view = fields_view_get; - this.fields_keys = _.keys(this.fields_view.fields); - - this.add_qweb_template(); - this.has_been_loaded.resolve(); - }, - - do_show: function () { - this.do_push_state({}); - return this._super(); - }, - - do_search: function (dom, cxt, group_by) { - var self = this; - - var domain = this.domain.concat(dom || []); - var context = _.clone(this.context); - context = _.extend(context, (cxt || {})); - var ds = { - "domain" : domain, - "context" : context, - }; - var opts = _.clone(this.options); - - return this.has_been_loaded.then(function() { - if (self.thread) { - $('<span class="o_timeline-placeholder"/>').insertAfter(self.thread.$el); - self.thread.destroy(); - } - self.thread = new MailThread(self, ds, opts); - self.thread.message_fetch(null, null, self.options.message_ids, self.options.view_inbox ? 1 : 0); - - return self.thread.replace(self.$('.o_timeline-placeholder')); - }); - }, - - do_reload_menu_emails: function () { - var menu = web_client.menu; - if (!menu || !menu.current_menu) { - return $.when(); - } - return menu.rpc("/web/menu/load_needaction", {'menu_ids': [menu.current_menu]}).done(function(r) { - menu.on_needaction_loaded(r); - }).then(function () { - menu.trigger("need_action_reloaded"); - }); - }, - - render_buttons: function($node) { - var self = this; - - this.$buttons = $(QWeb.render("TimelineView.buttons", {'widget': this})); - this.$buttons - .on('click', 'button.o_timeline_button_new', this.on_compose_message) - .on('click', '.o_timeline_share', function(event) { - self.write_to_followers(event, self); - }); - - $node = $node || this.options.$buttons; - if ($node) { - this.$buttons.appendTo($node); - } - else { - this.$('.o_timeline_buttons').replaceWith(this.$buttons); - } - }, - - add_qweb_template: function () { - for (var i = 0; i < this.fields_view.arch.children.length; i++) { - var child = this.fields_view.arch.children[i]; - if (child.tag === 'templates') { - this.qweb.add_template(utils.json_node_to_xml(child)); - break; - } - } - }, - - on_compose_message: function (event) { - event.preventDefault(); - web_client.action_manager.do_action({ - type: 'ir.actions.act_window', - res_model: 'mail.compose.message', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: {}, - }); - }, - - write_to_followers: function (event, view) { - view.thread.instantiate_write_to_followers(event); - }, - - set_message_ids: function (val) { - this.options.message_ids = val; - }, -}); - -/** - * ------------------------------------------------------------ - * Attachment - * ------------------------------------------------------------ - * - * This widget handles some features about the attachments. Those - * features are common to the MailThread widget and ComposeMessage - * widget. - */ -var Attachment = Widget.extend ({ - /** - * Upload the file on the server and add in the attachments list - */ - format_attachments: function (message) { - for (var l in message.attachment_ids) { - var attach = message.attachment_ids[l]; - if (!attach.formating) { - attach.url = '/web/content/' + attach.id + '?download=true'; - attach.name = mail_utils.breakword(attach.name || attach.filename); - attach.formating = true; - } - } - return message.attachment_ids; - }, - - display_attachments: function (message) { - return QWeb.render('ThreadMessageAttachments', {'record': message, 'widget': this}); - }, -}); - -/** - * ------------------------------------------------------------ - * MailThread Widget - * ------------------------------------------------------------ - * - * This widget handles the display of a thread of messages. By - * default, a thread is folded in the inbox and unfolded on a - * document. In the inbox, a thread can be unfolded by clicking - * on it. - * When unfolded, the display of the threads looks like : - * - root thread - * - - thread 1 - * - - - message (parent_id = thread 1) - * - - thread 2 - * - - - message (parent_id = thread 2) - */ -var MailThread = Attachment.extend ({ - template: 'MailThread', - - events: { - 'click .o_timeline_msg .oe_read':'on_message_read', - 'click .o_timeline_msg .oe_unread':'on_message_unread', - 'click .o_timeline_msg .oe_star':'on_star', - 'click .o_timeline_parent_message .oe_reply':'on_message_reply', - 'click .o_timeline_parent_message .oe_read':'on_thread_read', - 'click .o_timeline_action_author':'on_record_author_clicked', - 'click .o_timeline_msg_expandable':'on_message_expandable', - 'click .o_timeline_parent_expandable':'on_thread_expandable', - 'click .o_timeline_parent_subject':'on_parent_message', - 'mouseenter .oe_follwrs':'on_display_followers', - }, - - /** - * @param {Object} parent parent - * @param {Object} dataset - * @param {Object} root thread with context, domain, etc - * @param {Object} messages : {parent_id, list of messages} - * or {expandable} - * @param {Object} [options] - */ - init: function (parent, dataset, options) { - this._super(parent, dataset, options); - var self = this; - - this.domain = dataset.domain || []; - this.context = _.clone(dataset.context) || {}; - this.options = _.clone(options); - this.parent_view = parent.parent_view; - - this.is_ready = $.Deferred(); - this.root = parent instanceof TimelineView ? parent : false; - this.view = parent instanceof TimelineView ? parent : parent.view; - - // data of this thread : - // - list of messages in the thread, - // - parent message = first message of the thread - // - thread type : false (if root thread), parent or expandable - this.messages = dataset.messages ? dataset.messages : []; - this.parent_message = this.messages.length ? this.messages[this.messages.length - 1] : false; - this.thread_type = this.messages.length ? 'parent' : false; - if (this.messages.length && this.messages[0].message_type == 'expandable') { - this.thread_type = 'expandable'; - } - - // thread represented by parent message data - this.id = this.parent_message.id || false; - this.parent_id = this.parent_message.id || false; - this.author_id = this.parent_message.author_id || false; - this.user_pid = this.parent_message.user_pid || false; - this.is_private = this.parent_message.is_private || false; - this.partner_ids = this.parent_message.partner_ids || []; - if (this.parent_message.author_id && !_.contains(_.flatten(this.parent_message.partner_ids),this.parent_message.author_id[0]) && this.parent_message.author_id[0]) { - this.partner_ids.push(this.parent_message.author_id); - } - - this.context.default_model = this.parent_message.model || this.context.default_model; - this.context.default_res_id = this.parent_message.res_id || this.context.default_res_id; - - this.options.root_thread = this.options.root_thread != undefined ? this.options.root_thread : this; - this.options.show_compose_message = this.root ? false : this.options.root_thread.view.options.show_compose_message; - this.options.is_folded = this.options.view_inbox ? true : false; - this.options.toggle_read = true; - - // add some data to messages for the display - _.each(this.messages, function (msg) { - if (msg.message_type != "expandable") { - msg = self.format_message(msg); - } - }); - - this.model = this.parent_message.model || false; - this.res_id = this.parent_message.res_id || false; - this.record_name = this.parent_message.record_name || false; - this.subject = this.parent_message.subject || false; - - // add some data to thread for the display (followers, ...) - if (this.messages.length) { - this.format_thread().then(function () { - self.is_ready.resolve(); - }); - }else { - self.is_ready.resolve(); - } - - this.compose_message = false; - - this.ds_thread = new data.DataSetSearch(this, this.context.default_model || 'mail.thread'); - this.ds_message = new data.DataSetSearch(this, 'mail.message'); - }, - - start: function () { - var self = this; - - return this.is_ready.then(function () { - var $el = $(QWeb.render('MailThread', {'widget': self})); - self.replaceElement($el); - - if (self.options.show_compose_message) { - self.instantiate_compose_message(); - self.compose_message.do_show_compact(); - } - }); - }, - - /** - * instantiate the compose message object and insert this on the DOM - * (its place in the DOM depends on those cases : reply to thread in - * the inbox, write to followers in the inbox, compose new message on - * a document). The compose message is display in compact form. - */ - instantiate_compose_message: function (option) { - if (!this.compose_message) { - this.context = this.options.compose_as_todo ? _.extend({'default_starred': true}, this.context) : this.context; - this.compose_message = new ComposeMessage(this, this, this.options); - - if (this.options.view_inbox && option == 'reply') { - this.compose_message.insertAfter(this.$('.o_timeline_thread_content')); - } else { - if (this.options.view_inbox && option == 'write_to_followers') { - this.compose_message.prependTo(this.$el); - } else { - this.compose_message.insertBefore(this.$el); - } - } - } - }, - - /** - * instantiate the compose message and call the on_toggle_quick_composer - * method to allow the user to write his message. - */ - on_compose_message: function (event, option) { - if (this.compose_message) { - this.compose_message.destroy(); - } - this.compose_message = false; - - this.instantiate_compose_message(option); - return this.compose_message.on_toggle_quick_composer(event); - }, - - instantiate_write_to_followers: function (event) { - var self = this; - return this.on_compose_message(event, 'write_to_followers').then(function () { - self.$('.o_timeline_msg_composer').addClass('o_timeline_write_to_followers'); - }); - }, - - /** - * make a request to read the messages and set them 'read' if needed (calling - * RPC to "message_read_wrapper"). - * @param {Array} replace_domain: domain - * @param {Object} replace_context: context - * @param {Array} ids read (if the are some ids, the method don't use the domain) - */ - message_fetch: function (replace_domain, replace_context, ids, thread_level, callback) { - var self = this; - return this.ds_message.call('message_read_wrapper', [ - // ids force to read - ids === false ? undefined : ids && ids.slice(0, this.options.fetch_limit), - // domain + additional - (replace_domain ? replace_domain : this.domain), - // context + additional - (replace_context ? replace_context : this.context), - // thread_level - thread_level, - // parent_id - this.context.default_parent_id || undefined, - // limits - this.options.fetch_limit, - this.options.fetch_child_limit - ]).done(callback ? _.bind(callback, this, arguments) : this.proxy('treat_threads') - ).done(function (records) { - // records : { - // nb_reab : number of read messages (status from 'unread' to 'read'), - // threads : list of threads [[messages_thread1], [messages_thread2]] - // } - if (records.nb_read) { - self.options.root_thread.view.do_reload_menu_emails(); - } - }); - }, - - /** - * manage the list of threads recieved from message_fetch method - * and create a MailThread oject for each of them - */ - treat_threads: function (records) { - var self = this; - - _.each(records.threads, function (record) { - self.create_thread(record); - }); - - if (!records.threads.length) { - this.create_thread(); - } - }, - - create_thread: function (record) { - var thread = new MailThread(this, _.extend(_.clone(this), { - 'messages': record, - }), this.options); - - thread.appendTo(this.$el); - return thread; - }, - - /** - * set a message 'read' when click on Read in message - */ - on_message_read: function (event) { - var msg_id = $(event.target).data('id'); - var msg = _.findWhere(this.messages, {id: msg_id}); - event.stopPropagation(); - if (msg_id) { - this.on_message_read_unread([msg], true).then(function() { - $(event.target).replaceWith(QWeb.render("MessageReadUnread", {record: msg})); - }); - - } - }, - - /** - * set a message 'unread' when click on Unread in message - */ - on_message_unread: function (event) { - var msg_id = $(event.target).data('id'); - var msg = _.findWhere(this.messages, {id: msg_id}); - event.stopPropagation(); - if (msg_id) { - this.on_message_read_unread([msg], false).then(function() { - $(event.target).replaceWith(QWeb.render("MessageReadUnread", {record: msg})); - }); - } - }, - - /** - * set all the messages of this thread 'read' when click on - * Read in thread - */ - on_thread_read: function (event) { - var self = this; - - event.stopPropagation(); - this.on_message_read_unread(_.filter(this.messages, function (val) {return val.type != 'expandable'}), true).then(function () { - self.check_for_rerender(); - }); - }, - - /** - * Set the selected message(s) to 'read' or 'unread' - * @param {messages} array of messages - * @param {boolean} read_value - */ - on_message_read_unread: function (messages, read_value) { - var self = this; - - // inside the inbox, when the user mark a message as read/done, don't apply this value - // for the starred/favorite message - if (this.options.view_inbox && read_value) { - messages = _.filter(messages, function (val) {return !val.is_favorite && val.id;}); - if (!messages.length) { - return $.Deferred(); - } - } - var message_ids = _.map(messages, function (val) {return val.id;}); - if (read_value) { - var method = 'set_message_done'; - } - else { - var method = 'set_message_needaction'; - } - return this.ds_message.call(method, [message_ids, undefined, this.context]).then(function (nb_read) { - // apply modification - _.each(messages, function (msg) { - msg.to_read = !read_value; - if (self.options.toggle_read) { - msg.options.show_read = msg.to_read; - msg.options.show_unread = !msg.to_read; - } - }); - }); - }, - - /** - * add or remove a favorite (or starred) for a message and change class on the DOM - */ - on_star: function (event) { - var self = this; - var msg_id = $(event.target).data('id'); - var msg = _.findWhere(this.messages, {id: msg_id}); - var button = self.$('.oe_star:first'); - event.stopPropagation(); - - this.ds_message.call('set_message_starred', [[msg_id], !msg.is_favorite]).then(function (star) { - msg.is_favorite = star; - if (msg.is_favorite) { - button.addClass('oe_starred'); - }else { - button.removeClass('oe_starred'); - } - - if (self.options.view_inbox && msg.is_favorite) { - self.on_message_read_unread([msg], true); - } - }); - return false; - }, - - /** - * instantiate ComposeMessage when click on reply - */ - on_message_reply:function (event) { - event.stopPropagation(); - this.on_compose_message(event, 'reply'); - return false; - }, - - /** - * go to form view of the message author - */ - on_record_author_clicked: function (event) { - event.preventDefault(); - var partner_id = $(event.target).data('partner'); - var record_name = $(event.target).data('record'); - var state = { - 'model': 'res.partner', - 'id': partner_id, - 'title': record_name - }; - - web_client.action_manager.do_push_state(state); - this.do_action({ - type:'ir.actions.act_window', - view_type: 'form', - view_mode: 'form', - res_model: 'res.partner', - views: [[false, 'form']], - res_id: partner_id, - }); - }, - - /** - * load next messages when click on 'see more messages' (inside a thread) - */ - on_message_expandable: function (event) { - event.stopPropagation(); - - var self = this; - if (this.options.view_inbox) { - var parent_message = this.messages.pop(); - } - var msg = this.messages.pop(); - - this.message_fetch(msg.domain, this.context, false, 0, function (arg, data) { - var messages = data.threads[0]; - _.each(messages, function (message) { - self.add_message(message, true); - }); - if (this.options.view_inbox) { - this.messages.push(parent_message); - } - self.check_for_rerender(); - }); - }, - - /** - * load next threads when click on 'see more messages' - */ - on_thread_expandable: function (event) { - event.stopPropagation(); - var self = this; - var msg = this.messages.pop(); - - this.options.root_thread.message_fetch(msg.domain, this.context, false, 1).then(function () { - self.$el.remove(); - self.destroy(); - }); - }, - - /** - * unfolded the thread by rerender it - */ - on_parent_message: function (event) { - event.stopPropagation(); - this.options.is_folded = !this.options.is_folded; - this.check_for_rerender(); - }, - - /** - * get and display the users following the document (tooltip) - */ - on_display_followers: function (event) { - var self = this; - var $target = $(event.target); - event.stopPropagation(); - - if (this.followers_data) { - mail_utils.bindTooltipTo($target, this.followers_data, 'right'); - $target.tooltip('hide').tooltip('show'); - $(".tooltip").on("mouseleave", function () { - $(this).remove(); - }); - } - else { - var ds_model = new data.DataSetSearch(this, this.model, this.context); - ajax.jsonRpc('/mail/read_followers', 'call', {'follower_ids': this.follower_ids.slice(0, this.options.followers_limit)}).then(function (records) { - self.followers_data = []; - _.each(records, function(f) { - self.followers_data.push(f.name + '</br>'); - }); - if (self.nb_followers - self.followers_limit > 0) { - self.followers_data.push('and ' + self.nb_followers - self.followers_limit + 'more ... </br>'); - } - mail_utils.bindTooltipTo($target, self.followers_data, 'right'); - $target.tooltip('hide').tooltip('show'); - $(".tooltip").on("mouseleave", function () { - $(this).remove(); - }); - }); - } - }, - - /** - * rerender this thread after some change - */ - check_for_rerender: function () { - var self = this; - - if (this.messages.length) { - this.is_ready = $.Deferred(); - this.format_thread().then(function () { - self.is_ready.resolve(); - }); - } - - this.is_ready.then(function () { - var $el = $(QWeb.render('MailThread', {'widget': self})); - self.replaceElement($el); - self.options.root_thread.view.do_reload_menu_emails(); - }); - }, - - /** - * add a message to this list of messages of this thread (after reply e.g.) - */ - add_message: function (message, to_end) { - message = this.format_message(message); - if (to_end) { - this.messages.push(message); - }else{ - this.messages.unshift(message); - } - }, - - /** - * insert a message in the DOM - */ - insert_message: function (message) { - message.content = this.view.qweb.render("timeline-message", {record: message}); - this.$('.oe_view_nocontent').remove(); - if (this.options.view_inbox && !this.root) { - $(message.content).insertAfter(this.$('.o_timeline_thread_content')); - }else{ - if (this.options.view_inbox && this.root) { - $(message.content).appendTo(this.$('.o_timeline_thread_parent:first')); - } else { - $(message.content).prependTo(this.$el); - } - } - }, - - /** - * add and convert thread data for display - */ - format_thread: function () { - var self = this; - - this.followers_loaded = $.Deferred(); - - if ((! this.nb_followers || !this.follower_ids) && (this.model && this.res_id) && this.options.view_inbox) { - this.nb_followers = 0; - this.follower_ids = []; - - var ctx = this.context; - ctx['active_test'] = true; - this.ds_res = new data.DataSet(this, this.model, ctx); - this.ds_res.read_ids([this.res_id], ['id', 'message_follower_ids'], { - 'context': ctx, - }).then(function (data) { - self.follower_ids = data[0].message_follower_ids; - self.nb_followers = data[0].message_follower_ids.length; - self.followers_loaded.resolve(); - }); - } else { - this.followers_loaded.resolve(); - } - - return this.followers_loaded.then(function () { - var qweb_context = { - record: self.messages[0], - widget: self, - options: self.options, - }; - self.content = self.view.qweb.render("timeline-thread", qweb_context); - }); - }, - - /** - * add and convert message data for display - */ - format_message: function (msg) { - msg.tracking_values = msg.tracking_value_ids ? (msg.tracking_value_ids.length > 0) : false; - msg.partners = msg.partner_ids ? (msg.partner_ids.length > 0) : false; - msg.attachments = msg.attachment_ids ? (msg.attachment_ids.length > 0) : false; - msg.parent_id = msg.parent_id || false; - - msg.date = this.format_date(msg.date); - msg.author_avatar = this.format_avatar(msg.author_avatar, msg.author_id, msg.message_type); - msg.author_id = this.format_author(msg.author_id); - - if (msg.partners) { - msg.partners_nb = this.format_partners_nb(msg.partner_ids); - msg.partners_str = this.format_partners_str(msg.partner_ids); - } - - if (msg.attachments) { - msg.attachments_content = this.display_attachments(msg); - } - - if (msg.model == 'res.partner') { - msg.record_name = _.str.sprintf(_t('Partner Profile of ' + msg.record_name)); - }else{ - if (msg.model == 'hr.employee') { - msg.record_name = _.str.sprintf(_t('News from ' + msg.record_name)); - } - } - - msg.parent_thread = this; - - msg.options = _.clone(this.options); - msg.options.show_read = false; - msg.options.show_unread = false; - - if (this.options.show_read_unread_button) { - if (this.options.read_action == 'read') { - msg.options.show_read = true; - }else{ - if (this.options.read_action == 'unread') { - msg.options.show_unread = true; - }else { - msg.options.show_read = msg.to_read; - msg.options.show_unread = !msg.to_read; - } - } - } - return msg; - }, - - /** - * Convert date in displayable data. - */ - format_date: function (date) { - var d = date ? time.str_to_datetime(date) : false; - if (d) { - var display_date = moment(new Date(d).toISOString()).format('ddd MMM DD YYYY LT'); - date = display_date; - if (new Date().getTime()-d.getTime() < 7*24*60*60*1000) { - var timerelative = $.timeago(d); - date = timerelative; - } - } - return date; - }, - - /** - * Convert avatar in displayable data. - */ - format_avatar: function (avatar, author, type) { - var avt = false; - if (avatar) { - avt = "data:image/png;base64," + avatar; - }else if (type == 'email' && (!author || !author[0])) { - avt = ('/mail/static/src/img/email_icon.png'); - } - else if (author) { - avt = '/web/image/res.partner/' + author[0] + '/image_small'; - }else { - avt = '/web/image/res.users/' + session.uid + '/image_small'; - } - return avt; - }, - - format_author: function (author) { - if (author && author[1]) { - var parsed_email = mail_utils.parse_email(author[1]); - author.push(parsed_email[0], parsed_email[1]); - } - return author; - }, - - format_partners_nb: function (partners) { - return partners.length - 3; - }, - - format_partners_str: function (partners) { - if (partners && partners.length > 3) { - var extra_partners_nbr = this.format_partners_nb(partners); - var extra_partners_str = '' - var extra_partners = partners.slice(3); - - for (var key in extra_partners) { - extra_partners_str += extra_partners[key][1]; - } - - return extra_partners_str; - } - }, -}); - -/** - * ------------------------------------------------------------ - * ComposeMessage widget - * ------------------------------------------------------------ - * - * This widget handles the display to compose a new message. - */ -var ComposeMessage = Attachment.extend ({ - template: 'ComposeMessage', - - events: { - 'click .o_timeline_compose_post':'on_toggle_quick_composer', - 'click .o_timeline_compose_log':'on_toggle_quick_composer', - 'click .oe_post':'on_message_post', - 'click .oe_full':'on_compose_fullmail', - 'click .o_timeline_msg_attachment_list .oe_delete': 'on_attachment_delete', - 'change input.oe_form_binary_file': 'on_attachment_change', - 'blur textarea':'on_toggle_quick_composer', - 'mousedown .o_timeline_msg_center':function (event) { - this.stay_open = true; - }, - 'mouseup .o_timeline_msg_content':function (event) { - this.$('textarea').focus(); - }, - 'change .o_timeline_recipients input':'on_checked_recipient', - }, - - init: function (parent, dataset, options) { - this._super(parent, dataset, options); - - this.domain = dataset.domain || []; - this.context = _.clone(dataset.context) || {}; - this.options = _.clone(options); - - this.show_compact_message = false; - this.show_delete_attachment = true; - this.is_log = false; - - this.id = dataset.id || false; - this.user_pid = dataset.user_pid || false; - this.parent_id = dataset.parent_id || false; - this.is_private = dataset.is_private || false; - this.partner_ids = dataset.partner_ids || []; - this.recipients = []; - this.recipient_ids = []; - this.attachment_ids = []; - - this.parent_thread = parent; - this.view = parent.view; - this.session = session; - - core.bus.on('clear_uncommitted_changes', this, function (chain_callbacks) { - if (this.show_composer) { - var self = this; - chain_callbacks(function() { - var def = $.Deferred(); - var message = _t("You are currently composing a message, your message will be discarded. Are you sure you want to leave this page ?"); - var options = { - title: _t("Warning"), - confirm_callback: function() { - self.on_cancel(); - this.on('closed', null, function() { // 'this' is the dialog widget - def.resolve(); - }); - }, - cancel_callback: function() { - def.reject(); - }, - }; - Dialog.confirm(this, message, options); - return def; - }); - } - }); - }, - - start: function () { - this.ds_attachment = new data.DataSetSearch(this, 'ir.attachment'); - this.fileupload_id = _.uniqueId('oe_fileupload_temp'); - $(window).on(this.fileupload_id, this.on_attachment_loaded); - this.$(".o_timeline_msg_attachment_list").html(this.display_attachments(this)); - this.bind_events(); - return this._super.apply(this, arguments); - }, - - reinit: function () { - var $render = $(QWeb.render('ComposeMessage', {'widget': this})); - this.replaceElement($render); - this.$(".o_timeline_msg_attachment_list").html(this.display_attachments(this)); - this.bind_events(); - }, - - bind_events: function () { - var self = this; - var ev_stay = {}; - ev_stay.mouseup = ev_stay.keydown = ev_stay.focus = function () {self.stay_open = false;}; - this.$('textarea').on(ev_stay); - autosize(this.$('textarea')); - }, - - on_cancel: function (event) { - if (event) event.stopPropagation(); - this.attachment_ids = []; - this.stay_open = false; - this.show_composer = false; - this.reinit(); - }, - - /** - * compute the list of unknown email_from the the given thread - */ - compute_emails_from: function () { - var self = this; - var messages = this.parent_thread.messages; - _.each(messages, function (thread) { - if (thread.author_id && !thread.author_id[0] && - !_.find(self.recipients, function (recipient) {return recipient.email_address == thread.author_id[3];})) { - self.recipients.push({'full_name': thread.author_id[1], - 'name': thread.author_id[2], - 'email_address': thread.author_id[3], - 'partner_id': false, - 'checked': true, - 'reason': 'Incoming email author' - }); - } - }); - return self.recipients; - }, - - /** - * Quick composer: toggle minimal / expanded mode - * - toggle minimal (one-liner) / expanded (textarea, buttons) mode - * - when going into expanded mode: - * - call `message_get_suggested_recipients` to have a list of partners to add - * - compute email_from list (list of unknown email_from to propose to create partners) - */ - on_toggle_quick_composer: function (event) { - var self = this; - var $input = $(event.target); - - this.compute_emails_from(); - var email_addresses = _.pluck(this.recipients, 'email_address'); - - var suggested_partners = $.Deferred(); - - // if clicked: call for suggested recipients - if (event.type == 'click') { - this.is_log = $input.hasClass('o_timeline_compose_log'); - suggested_partners = this.parent_thread.ds_thread.call('message_get_suggested_recipients', [[this.context.default_res_id], this.context]).done(function (additional_recipients) { - var thread_recipients = additional_recipients[self.context.default_res_id]; - - _.each(thread_recipients, function (recipient) { - var parsed_email = mail_utils.parse_email(recipient[1]); - if (_.indexOf(email_addresses, parsed_email[1]) == -1) { - self.recipients.push({ - 'checked': true, - 'partner_id': recipient[0], - 'full_name': recipient[1], - 'name': parsed_email[0], - 'email_address': parsed_email[1], - 'reason': recipient[2], - }) - } - }); - }); - } else { - suggested_partners.resolve({}); - } - - // when call for suggested partners finished: re-render the widget - $.when(suggested_partners).pipe(function (additional_recipients) { - if ((!self.stay_open || (event && event.type == 'click')) - && (!self.show_composer || !self.$('textarea:not(.o_timeline_compact)').val().match(/\S+/) - && !self.attachment_ids.length)) { - self.show_composer = !self.show_composer || self.stay_open; - self.reinit(); - } - if (!self.stay_open && self.show_composer && (!event || event.type != 'blur')) { - self.$('textarea:not(.o_timeline_compact):first').focus(); - } - }); - - return suggested_partners; - }, - - on_message_post: function (event) { - if (this.flag_post){ - return; - } - - var self = this; - this.flag_post = true; - if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { - if (this.is_log) { - this.do_send_message_post([], this.is_log); - } else { - this.check_recipient_partners().done(function (partner_ids) { - self.do_send_message_post(partner_ids, self.is_log); - }); - } - } - }, - - /** - * post a message and fetch the message - */ - do_send_message_post: function (partner_ids, log) { - var self = this; - - var values = { - 'body': this.$('textarea').val(), - 'subject': false, - 'parent_id': this.parent_id || this.id, - 'partner_ids': partner_ids, - 'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}), - 'context': _.extend(this.parent_thread.context, { - 'mail_post_autofollow': true, - 'mail_post_autofollow_partner_ids': partner_ids, - }), - 'message_type': 'comment', - 'content_subtype': 'plaintext', - }; - - if (log) { - var subtype_id = parseInt(this.$('select').first().val()); - if (_.indexOf(_.pluck(self.options.internal_subtypes, 'id'), subtype_id) == -1) { - values['subtype'] = 'mail.mt_note' - } - else { - values['subtype_id'] = subtype_id; - } - } else { - values['subtype'] = 'mail.mt_comment'; - } - - this.parent_thread.ds_thread._model.call('message_post', [this.context.default_res_id], values).done(function (message_id) { - var thread = self.parent_thread; - - // attach message to the thread object - thread.message_fetch([["id", "=", message_id]], false, [message_id], 0, function (arg, data) { - var message = data.threads[0][0]; - thread.add_message(message, false); - thread.insert_message(message); - }); - - self.on_cancel(); - self.flag_post = false; - }); - }, - - check_recipient_partners: function () { - var self = this; - var check_done = $.Deferred(); - - var recipients = _.filter(this.recipients, function (recipient) { return recipient.checked; }); - var recipients_to_find = _.filter(recipients, function (recipient) { return (! recipient.partner_id); }); - var names_to_find = _.pluck(recipients_to_find, 'full_name'); - var recipients_to_check = _.filter(recipients, function (recipient) { return (recipient.partner_id && ! recipient.email_address); }); - var recipient_ids = _.pluck(_.filter(recipients, function (recipient) { return recipient.partner_id && recipient.email_address; }), 'partner_id'); - - var names_to_remove = []; - var recipient_ids_to_remove = []; - - // 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) { - 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([]); - } - - // for unknown names + incomplete partners -> open popup - cancel = remove from recipients - $.when(find_done).pipe(function (result) { - var emails_deferred = []; - var recipient_popups = result.concat(recipients_to_check); - - _.each(recipient_popups, function (partner_info) { - var deferred = $.Deferred(); - emails_deferred.push(deferred); - - var partner_name = partner_info.full_name; - var partner_id = partner_info.partner_id; - var parsed_email = mail_utils.parse_email(partner_name); - - var pop = new form_common.FormViewDialog(this, { - res_model: 'res.partner', - res_id: partner_id, - context: { - 'force_email': true, - 'ref': "compound_context", - 'default_name': parsed_email[0], - 'default_email': parsed_email[1], - }, - title: _t("Please complete partner's informations"), - }).open(); - pop.on('closed', self, function () { - deferred.resolve(); - }); - pop.view_form.on('on_button_cancel', self, function () { - names_to_remove.push(partner_name); - if (partner_id) { - recipient_ids_to_remove.push(partner_id); - } - }); - }); - - $.when.apply($, emails_deferred).then(function () { - var new_names_to_find = _.difference(names_to_find, names_to_remove); - find_done = $.Deferred(); - if (new_names_to_find.length > 0) { - 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([]); - } - $.when(find_done).pipe(function (result) { - var recipient_popups = result.concat(recipients_to_check); - _.each(recipient_popups, function (partner_info) { - if (partner_info.partner_id && _.indexOf(partner_info.partner_id, recipient_ids_to_remove) == -1) { - recipient_ids.push(partner_info.partner_id); - } - }); - }).pipe(function () { - check_done.resolve(recipient_ids); - }); - }); - }); - - return check_done; - }, - - on_compose_fullmail: function () { - if (!this.do_check_attachment_upload()) - return false; - - var self = this; - var recipient_done = $.Deferred(); - - if (this.is_log){ - recipient_done.resolve([]); - }else{ - recipient_done = this.check_recipient_partners(); - } - - $.when(recipient_done).done(function (partner_ids) { - var context = { - 'default_parent_id': self.id, - 'default_body': mail_utils.get_text2html( - self.$el ? (self.$el.find('textarea:not(.o_timeline_compact)').val() || '') : ''), - 'default_attachment_ids': _.map(self.attachment_ids, function (file) {return file.id;}), - 'default_partner_ids': partner_ids, - 'default_is_log': self.is_log, - 'mail_post_autofollow': true, - 'mail_post_autofollow_partner_ids': partner_ids, - 'is_private': self.is_private, - }; - - if (self.context.default_model && self.context.default_res_id) { - context.default_model = self.context.default_model; - context.default_res_id = self.context.default_res_id; - } - - var action = { - type: 'ir.actions.act_window', - res_model: 'mail.compose.message', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: context, - }; - self.do_action(action, { - 'on_close': function(){ self.is_log && self.parent_thread.message_fetch() } - }); - self.on_cancel(); - }); - }, - - on_checked_recipient: function (event) { - var $input = $(event.target); - var full_name = $input.attr("data"); - _.each(this.recipients, function (recipient) { - if (recipient.full_name == full_name) { - recipient.checked = $input.is(":checked"); - } - }); - }, - - /** - * when a user click on the upload button, send file read on_attachment_loaded - */ - on_attachment_change: function (event) { - event.stopPropagation(); - var $target = $(event.target); - - if ($target.val() !== '') { - var filename = $target.val().replace(/.*[\\\/]/,''); - - // if the files exits for this answer, delete the file before upload - var attachments = []; - for (var i in this.attachment_ids) { - if ((this.attachment_ids[i].filename || this.attachment_ids[i].name) == filename) { - if (this.attachment_ids[i].upload) { - return false; - } - this.ds_attachment.unlink([this.attachment_ids[i].id]); - } else { - attachments.push(this.attachment_ids[i]); - } - } - - this.attachment_ids = attachments; - - // submit file - this.$('form.oe_form_binary_form').submit(); - this.$(".oe_attachment_file").hide(); - - this.attachment_ids.push({ - 'id': 0, - 'name': filename, - 'filename': filename, - 'url': '', - 'upload': true, - 'mimetype': '' - }); - - this.$(".o_timeline_msg_attachment_list").html(this.display_attachments(this)); - } - }, - - /** - * when the file is uploaded - */ - on_attachment_loaded: function (event, result) { - if (result.erorr || !result.id ) { - this.do_warn(QWeb.render('mail.error_upload'), result.error); - this.attachment_ids = _.filter(this.attachment_ids, function (val) { return !val.upload; }); - } - else { - for (var i in this.attachment_ids) { - if (this.attachment_ids[i].filename == result.filename && this.attachment_ids[i].upload) { - this.attachment_ids[i] = { - 'id': result.id, - 'name': result.name, - 'filename': result.filename, - 'mimetype': result.mimetype, - 'url': '/web/content/' + result.id + '?download=true' - }; - } - } - } - this.$(".o_timeline_msg_attachment_list").html(this.display_attachments(this)); - - var $input = this.$('input.oe_form_binary_file'); - $input.after($input.clone(true)).remove(); - this.$(".oe_attachment_file").show(); - }, - - /** - * Unlink the file on the server and reload display - */ - on_attachment_delete: function (event) { - event.stopPropagation(); - var attachment_id = $(event.target).data("id"); - - if (attachment_id) { - var attachments = []; - for (var i in this.attachment_ids) { - if (attachment_id != this.attachment_ids[i].id) { - attachments.push(this.attachment_ids[i]); - } - else { - this.ds_attachment.unlink([attachment_id]); - } - } - this.attachment_ids = attachments; - this.$(".o_timeline_msg_attachment_list").html(this.display_attachments(this)); - } - }, - - /** - * return true if all file are complete else return false and make an alert - */ - do_check_attachment_upload: function () { - if (_.find(this.attachment_ids, function (file) {return file.upload;})) { - this.do_warn(_t("Uploading error"), _t("Please, wait while the file is uploading.")); - return false; - } - return true; - }, - - do_show_compact: function () { - this.show_compact_message = true; - if (!this.show_composer) { - this.reinit(); - } - }, -}); - -/** - * ------------------------------------------------------------ - * UserMenu - * ------------------------------------------------------------ - * - * Add a link on the top user bar for write a full mail - */ -var ComposeMessageTopButton = Widget.extend({ - template:'ComposeMessageTopButton', - - events: { - "click": "on_compose_message", - }, - - on_compose_message: function (ev) { - ev.preventDefault(); - var ctx = {} - if ($('button.o_timeline_compose_post') && $('button.o_timeline_compose_post').is(":visible") == true && - (this.getParent()).getParent().action_manager.inner_widget.active_view.type == 'form'){ - ctx = { - 'default_res_id': (this.getParent()).getParent().action_manager.inner_widget.active_view.controller.datarecord.id, - 'default_model': (this.getParent()).getParent().action_manager.inner_widget.active_view.controller.model, - }; - } - web_client.action_manager.do_action({ - type: 'ir.actions.act_window', - res_model: 'mail.compose.message', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: ctx, - }); - }, -}); - -// Put the ComposeMessageTopButton widget in the systray menu -//SystrayMenu.Items.push(ComposeMessageTopButton); - -core.view_registry.add('timeline', TimelineView); -//core.form_widget_registry.add('mail_thread', TimelineRecordThread); - -return { - TimelineView: TimelineView, - MailThread: MailThread, - TimelineRecordThread: TimelineRecordThread, -}; - -}); - -odoo.define('mail.compatibility', function (require) { -var mail = require('mail.mail'); - -window.openerp = window.openerp || {}; -openerp.mail = {}; -openerp.mail.Wall = mail.Wall; - -}); diff --git a/addons/mail/static/src/js/mail_chatter.js b/addons/mail/static/src/js/mail_chatter.js index 7032f864eb4..2a4ace5b0da 100644 --- a/addons/mail/static/src/js/mail_chatter.js +++ b/addons/mail/static/src/js/mail_chatter.js @@ -440,14 +440,6 @@ var ComposeMessageTopButton = Widget.extend({ }, on_compose_message: function (ev) { ev.preventDefault(); - var ctx = {}; - if ($('button.o_timeline_compose_post') && $('button.o_timeline_compose_post').is(":visible") == true && - (this.getParent()).getParent().action_manager.inner_widget.active_view.type == 'form'){ - ctx = { - 'default_res_id': (this.getParent()).getParent().action_manager.inner_widget.active_view.controller.datarecord.id, - 'default_model': (this.getParent()).getParent().action_manager.inner_widget.active_view.controller.model, - }; - } web_client.action_manager.do_action({ type: 'ir.actions.act_window', res_model: 'mail.compose.message', @@ -455,7 +447,6 @@ var ComposeMessageTopButton = Widget.extend({ view_type: 'form', views: [[false, 'form']], target: 'new', - context: ctx, }); }, }); diff --git a/addons/mail/static/src/js/mail_utils.js b/addons/mail/static/src/js/mail_utils.js index a18dc449d6b..8b9b470a81a 100644 --- a/addons/mail/static/src/js/mail_utils.js +++ b/addons/mail/static/src/js/mail_utils.js @@ -37,60 +37,6 @@ function get_text2html(text) { .replace(/[\n\r]/g,'<br/>'); } -/* Returns the complete domain with "&" - * TDE note: please add some comments to explain how/why - */ -function expand_domain(domain) { - var nb_and = -1; - var k; - // TDE note: smarted code maybe ? - for (k = domain.length-1; k >= 0 ; k-- ) { - if (typeof domain[k] != 'object' ) { - nb_and -= 2; - continue; - } - nb_and += 1; - } - - for (k = 0; k < nb_and ; k++) { - domain.unshift('&'); - } - - return domain; -} - -// inserts zero width space between each letter of a string so that -// the word will correctly wrap in html boxes smaller than the text -function breakword(str){ - var out = ''; - if (!str) { - return str; - } - for(var i = 0, len = str.length; i < len; i++){ - out += _.str.escapeHTML(str[i]) + '​'; - } - return out; -} - - -// TODO JEM : remove me in master -function bindTooltipTo($el, value, position) { - $el.tooltip({ - 'title': value, - 'placement': position, - 'html': true, - 'trigger': 'manual', - 'animation': false, - }).on("mouseleave", function () { - setTimeout(function () { - if (!$(".tooltip:hover").length) { - $el.tooltip("hide"); - } - }, 100); - }); -} - - /** * ------------------------------------------------------------ * MailChat Utils @@ -169,9 +115,6 @@ function beep(session){ return { parse_email: parse_email, get_text2html: get_text2html, - expand_domain: expand_domain, - breakword: breakword, - bindTooltipTo: bindTooltipTo, shortcode_apply: shortcode_apply, shortcode_substitution: shortcode_substitution, attachment_filetype_to_fa_class: attachment_filetype_to_fa_class, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml deleted file mode 100644 index f1de2b68daf..00000000000 --- a/addons/mail/static/src/xml/mail.xml +++ /dev/null @@ -1,233 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<templates> - -<div t-name="TimelineView.buttons" class="o_timeline_buttons"> - <t t-if="widget.options.action_buttons !== false"> - <button type="button" class="o_timeline_button_new btn btn-primary btn-sm"> - New message - </button> - <t t-if="!widget.options.readonly and widget.options.show_write_to_followers"> - <span class="oe_alternative"> - <span class="oe_fade">or</span> - <div class="oe_bounce_container"> - <t t-if="widget.options.compose_placeholder"> - <a class="o_timeline_share text-info"><t t-raw="widget.options.compose_placeholder"/></a> - </t> - <t t-if="! widget.options.compose_placeholder"> - <a class="o_timeline_share text-info">Write to my followers</a> - </t> - </div> - </span> - </t> - </t> -</div> - -<div t-name="TimelineWall" t-attf-class="o_timeline #{widget.options.view_inbox ? 'o_timeline_inbox' : 'o_timeline_chatter'}"> - <div class="o_timeline_buttons"/> - <div class="o_timeline-placeholder"></div> -</div> - -<t t-name="ComposeMessage"> - <div t-if="widget.show_composer and !widget.options.readonly" - class="o_timeline_msg o_timeline_msg_composer_compact"> - <div class="o_timeline_msg o_timeline_msg_composer"> - <div class="o_timeline_msg_center"> - <div class="o_timeline_msg_content"> - <button t-if="! widget.is_log" class="oe_full" title="Open the full mail composer"> - <i class='fa fa-pencil-square-o'/> - </button> - <t t-call="ThreadListRecipients"/> - <t t-if="widget.is_log and widget.options.internal_subtypes.length > 1"> - <label>Activity</label> - <select class=""> - <t t-foreach="widget.options.internal_subtypes" t-as="subtype"> - <option t-att-value="subtype['id']"><t t-raw="subtype['name']"/></option> - </t> - </select> - </t> - <textarea class="field_text"></textarea> - </div> - <div class="o_timeline_msg_footer"> - <div class="o_timeline_msg_attachment_list"></div> - <div class="btn-group btn-group-sm"> - <button type="button" class="oe_post btn btn-primary"> - <t t-if="!widget.is_log">Send</t> - <t t-if="widget.is_log">Log</t> - </button> - <t t-call="ComposeMessage.AddAttachment"/> - </div> - </div> - </div> - </div> - </div> - - <div t-if="widget.show_compact_message and !widget.show_composer and !widget.options.readonly" - class="o_timeline_msg o_timeline_msg_composer_compact"> - <t t-if="!widget.options.view_inbox"> - <div class="field_text o_timeline_compact o_timeline_compact_record"> - <div class="btn-group btn-group-sm"> - <button type="button" class="o_timeline_compose_post btn btn-primary" - t-if="widget.options.compose_placeholder"> - <t t-raw="widget.options.compose_placeholder"/> - </button> - <button type="button" class="o_timeline_compose_post btn btn-primary" - t-if="!widget.options.compose_placeholder and !widget.options.view_inbox" - title="Send a message. Followers will be notified."> - New message - </button> - </div> - <t t-if="widget.options.display_log_button"> - <span class="text-muted o_timeline_sep_word">or</span> - <div class="btn-group btn-group-sm"> - <button class="o_timeline_compose_log btn btn-link btn-small" - title="Log a note. Followers will not be notified."> - Log an internal note - </button> - </div> - </t> - </div> - </t> - </div> - - <span t-if="!(widget.show_compact_message and !widget.show_composer) and !widget.show_composer" - class="oe_placeholder_compose"></span> -</t> - -<!-- - ComposeMessage.AddAttachment template - Small template to be inserted in the composition for add attachments - --> -<t t-name="ComposeMessage.AddAttachment"> - <span class="oe_attachment_file"> - <span class="oe_add"> - <!-- uploader of file --> - <button class="oe_attach"><i class="fa fa-paperclip"/></button> - <span class='oe_attach_label'>Attach a file</span> - <t t-call="HiddenInputFile"> - <t t-set="fileupload_id" t-value="widget.fileupload_id"/> - <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> - <input type="hidden" name="model" value="mail.compose.message"/> - <input type="hidden" name="id" value="0"/> - <input type="hidden" name="session_id" t-att-value="widget.session.session_id"/> - </t> - </span> - </span> -</t> - -<!-- - template to the recipients list - --> -<t t-name="ThreadListRecipients"> - <div class="o_timeline_list_recipients" t-if="!widget.is_log"> - To: - <t t-if="!widget.is_private"> - <span class="o_timeline_all_follower"> - <t t-if="widget.parent_thread.parent_message.record_name"> - Followers of - <t t-raw="'"' + widget.parent_thread.parent_message.record_name + '"'"/> - </t> - <t t-if="!widget.parent_thread.parent_message.record_name and widget.options.view_mailbox"> - My Followers </t> - <t t-if="!widget.parent_thread.parent_message.record_name and !widget.options.view_mailbox"> - Followers of this document </t> - </span> - </t> - <t t-set="inc" t-value="0"/> - <t t-foreach="widget.partner_ids" t-as="partner"> - <t t-if="widget.is_private or (widget.user_pid != partner[0])"> - <t t-if="!widget.is_private and inc==0"> and </t> - <span t-attf-class="o_timeline_partner_follower #{inc>=3?'oe_hidden':''}"> - <t t-if="inc" t-raw="', '"/> - <a t-if="widget.options.show_link" - t-attf-href="#model=res.partner&id=#{partner[0]}"> - <t t-esc="partner[1]"/> - </a> - <t t-if="!widget.options.show_link" t-esc="partner[1]"/> - </span> - <t t-set="inc" t-value="inc+1"/> - </t> - </t> - - <t t-if="widget.partner_ids.length > 3"> - <span class="oe_more"> - , <a><t t-esc="widget.partner_ids.length - 3"/> others...</a> - </span> - </t> - - <div class="o_timeline_recipients" t-if="!widget.is_log"> - <t t-foreach='widget.recipients' t-as='recipient'> - <label t-attf-title="Add as recipient and follower (reason: #{recipient.reason})"> - <input type="checkbox" - t-att-checked="recipient.checked ? 'checked' : undefined" - t-att-data="recipient.full_name"/> - <t t-esc="recipient.name"/> - <t t-if="recipient.email_address">(<t t-esc="recipient.email_address"/>)</t> - <t t-if="!recipient.email_address">(no email address)</t> - </label> - </t> - </div> - </div> - <div class="o_timeline_is_log" t-if="widget.is_log"> - <span class="text-muted"> - Log an internal note which will not be sent to followers. - Note that users reading the document can read internal notes. - </span> - </div> -</t> - -<div t-name="MailThread" class="oe_thread"> - <div t-attf-class="#{widget.options.view_inbox ? 'o_timeline_thread_parent' : ''}"> - <t t-raw="widget.content"/> - </div> - <t t-if="!widget.messages.length and !widget.root"> - <t t-call="NoMessage" /> - </t> -</div> - -<!-- - mail.thread.message.attachments template - Template used to display attachments in a mail.message - --> -<t t-name="ThreadMessageAttachments"> - <t t-foreach='widget.format_attachments(record)' t-as='attachment'> - <div t-attf-class="oe_attachment oe_preview #{attachment.upload ? 'oe_uploading' : ''}"> - <a class="o_image" t-att-href='attachment.url' target="_blank" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/100x80"> - <div class='oe_name'><t t-raw='attachment.name'/></div> - </a> - <div class='oe_delete oe_e'> - <i class='fa fa-times-circle' title="Delete this attachment" t-att-data-id="attachment.id"/> - </div> - <div class='oe_progress_bar'> - uploading - </div> - </div> - </t> -</t> - -<t t-name="MessageReadUnread"> - <i t-if="record.options.show_read" title="Done" - class="oe_read fa fa-check" t-att-data-id="record.id"/> - <i t-if="record.is_favorite and record.options.show_unread" title="Set back to Todo" - class="oe_unread fa fa-inbox" t-att-data-id="record.id"/> - <i t-if="!record.is_favorite and record.options.show_unread" title="Move to Inbox" - class="oe_unread fa fa-inbox" t-att-data-id="record.id"/> -</t> - -<t t-name="NoMessage"> - <div class="oe_view_nocontent">No message.</div> -</t> - -<!-- - ComposeMessage.ButtonTopBar - render of the button on the user bar for open wizard compose message - --> -<t t-name="ComposeMessageTopButton"> - <li title='Compose new Message' class="oe_topbar_item oe_topbar_compose_full_email"> - <a href="#"> - <i class="fa fa-envelope-o fa-fw"></i> - </a> - </li> -</t> - -</templates>
\ No newline at end of file diff --git a/addons/mail/views/mail_channel_views.xml b/addons/mail/views/mail_channel_views.xml index b9b75112782..1112bcc0072 100644 --- a/addons/mail/views/mail_channel_views.xml +++ b/addons/mail/views/mail_channel_views.xml @@ -177,10 +177,6 @@ <field name="search_view_id" ref="mail_channel_view_search"/> </record> - <!-- left-side menu: Groups !--> - <menuitem id="mail_channel_menu_root" parent="mail_thread_menu_root" sequence="2" name="Channels"/> - <menuitem id="mail_channel_menu_all" parent="mail_channel_menu_root" sequence="100" action="mail_channel_action_view"/> - <!-- settings !--> <menuitem id="mail_channel_menu_settings" parent="base.menu_email" sequence="90" name="Channels" action="mail_channel_action_view" diff --git a/addons/mail/views/mail_message_views.xml b/addons/mail/views/mail_message_views.xml index c84fe061e75..3103ab7faf1 100644 --- a/addons/mail/views/mail_message_views.xml +++ b/addons/mail/views/mail_message_views.xml @@ -142,273 +142,5 @@ <field name="view_mode">kanban,tree,form</field> </record> - <record model="ir.ui.view" id="mail_message_view_timeline"> - <field name="name">mail.message.view.timeline.</field> - <field name="model">mail.message</field> - <field name="arch" type="xml"> - <timeline string="Mail Timeline"> - <field name="date"/> - <field name="author_id"/> - <field name="subject"/> - <field name="model"/> - <field name="res_id"/> - <field name="body"/> - <field name="attachment_ids"/> - <field name="tracking_value_ids"/> - <field name="subtype_id"/> - <field name="message_type"/> - <field name="starred"/> - <templates> - <t t-name="timeline-message"> - <div t-attf-class="row o_timeline_msg o_timeline_msg_#{record.message_type} - #{record.subtype ? '' : 'o_timeline_msg_nobody'}"> - <t t-if="record.message_type == 'expandable'"> - <div class="col-md-2"> </div> - <span> - - - - - - - - - - - See more messages - - - - - - - - - - - </span> - </t> - - <t t-if="record.message_type != 'expandable'"> - <div class="col-md-2"> - <div class="o_timeline_msg_date"> - <span> <t t-raw="record.date"/> </span> - </div> - </div> - - <div class="col-md-10 o_timeline_msg_message"> - <div class='o_timeline_msg_left'> <!-- *** avatar *** --> - <a t-if="record.options.show_link" - t-attf-href="#model=res.partner&id=#{record.author_id[0]}" - t-att-title="record.author_id[1]"> - <img class="o_timeline_msg_icon" - t-att-src="record.author_avatar"/> - </a> - <img t-if="!record.options.show_link" class="o_timeline_msg_icon" - t-att-src="record.author_avatar"/> - </div> <!-- *** avatar *** --> - - <div class="o_timeline_msg_center"> <!-- *** msg_center *** --> - <div class="o_timeline_msg_content"> <!-- *** msg_content *** --> - - <div class="o_timeline_header"> <!-- *** msg_header *** --> - <!-- *** header when tracking values *** --> - <div t-if="record.tracking_values" class="o_timeline_tracking_value_header"> - <span t-if="!record.subtype" class="text-muted o_timeline_no_subtype"> - Update </span> - <span t-if="record.subtype" class="o_timeline_subtype"> - <t t-raw="record.subtype"/> - </span> - <span t-attf-class="text-muted #{!record.subtype ? 'o_timeline_no_subtype' : ''}"> - by </span> - <span t-attf-class="#{!record.subtype ? 'text-muted o_timeline_no_subtype' : ''}"> - <a t-if="record.options.show_link" - class="o_timeline_action_author" - t-attf-href="#model=res.partner&id=#{record.author_id[0]}" - t-att-data-partner="record.author_id[0]"> - <t t-raw="record.author_id[2]"/> - </a> - <a t-if="!record.options.show_link" - class="o_timeline_action_author"> - <t t-raw="record.author_id[2]"/> - </a> - </span> - </div> - - <!-- *** header when no tracking value *** --> - <span t-if="!record.tracking_values" class="o_timeline_msg_header"> - <span t-if="record.author_id and !(record.message_type == 'notification')" - class="text-muted"> - <t t-if="record.subtype and record.message_type == 'comment'"> Message </t> - <t t-if="record.subtype and record.message_type == 'email'"> Email </t> - <t t-if="!record.subtype"> Note </t> - from - <a t-if="record.options.show_link and record.author_id[0]" - t-attf-href="#model=res.partner&id=#{record.author_id[0]}" - t-att-data-partner="record.author_id[0]" t-att-data-record="record.record_name" - class="o_timeline_action_author"> - <t t-raw="record.author_id[2]"/> - </a> - <a t-if="record.author_id and (!record.options.show_link or !record.author_id[0])" - class="o_timeline_action_author"> - <t t-raw="record.author_id[2]"/> - </a> - </span> - </span> - - <div t-attf-class="o_timeline_msg_icons #{record.tracking_values ? - 'o_timeline_msg_icons_track' : ''}" - t-if="!record.options.readonly"> <!-- *** icons *** --> - <span> - <i t-if="record.options.show_read" title="Done" - class="oe_read fa fa-check" t-att-data-id="record.id"/> - <i t-if="record.is_favorite and record.options.show_unread" title="Set back to Todo" - class="oe_unread fa fa-inbox" t-att-data-id="record.id"/> - <i t-if="!record.is_favorite and record.options.show_unread" title="Move to Inbox" - class="oe_unread fa fa-inbox" t-att-data-id="record.id"/> - </span> - <span> - <i title="To Do" t-attf-class="oe_star #{record.is_favorite ? 'oe_starred':''} fa fa-star" - t-att-data-id="record.id"/> - </span> - </div> <!-- *** icons *** --> - </div> <!-- *** msg_header *** --> - - <div t-attf-class="o_timeline_msg_body"> <!-- *** msg_body *** --> - <t t-raw="record.body"/> - <t t-if="!record.body and record.subject"> - <t t-raw="record.subject"/> - </t> - <ul class="o_timeline_tracking_value_list"> - <t t-foreach='record.tracking_value_ids' t-as='value'> - <li> - <t t-esc="value.changed_field"/> - <span> : </span> - <t t-if="value.old_value"> - <span class="o_timeline_tracking_value"> <t t-esc="value.old_value"/> </span> - <span> <i class="fa fa-long-arrow-right"></i> </span> - </t> - <span class="o_timeline_tracking_value"> <t t-esc="value.new_value"/> </span> - </li> - </t> - </ul> - </div> <!-- *** msg_body *** --> - - <div class="o_timeline_msg_footer"> <!-- *** msg_footer *** --> - <t t-if="record.attachments"> - <div class="o_timeline_msg_attachment_list"> - <t t-raw="record.attachments_content"/> - </div> - </t> - - <t t-if="(record.message_type == 'comment' or record.message_type == 'email') and - (record.subtype and record.partners)"> - <div t-if="record.partners" class="o_timeline_partners_followers"> - <span class="text-muted"> - To </span> - <span class="o_timeline_partners_list"> - <t t-foreach="record.partner_ids.slice(0, 3)" t-as="partner"> - <span t-attf-class="o_timeline_partner_follower"> - <a t-if="record.options.show_link" - t-attf-href="#model=res.partner&id=#{partner[0]}" - t-att-data-partner="partner[0]" - class="o_timeline_action_author"> - <t t-esc="partner[1]"/> - </a> - <t t-if="!record.options.show_link" t-esc="partner[1]"/> - </span> - <t t-if="!partner_last">,</t> - </t> - <t t-if="record.partner_ids.length > 3"> - <span t-att-title="record.partners_str"> - and <t t-esc="record.partners_nb"/> more - </span> - </t> - </span> - </div> - </t> - </div> <!-- *** msg_footer *** --> - - </div> <!-- *** msg_content *** --> - </div> <!-- *** msg_center *** --> - </div> - </t> - </div> - </t> - <t t-name="timeline-thread"> - <t t-if="options.view_inbox"> - <div t-attf-class="o_timeline_thread_content o_timeline_parent_#{widget.thread_type}"> - <t t-if="widget.thread_type == 'expandable'"> - <div class="col-md-2"> </div> - <span> - - - - - - - - - - - See more messages - - - - - - - - - - - </span> - </t> - - <t t-if="widget.thread_type != 'expandable'"> - <span class="col-md-2"> - <t t-if="options.is_folded"> - <div class="o_timeline_msg_date"> - <span> <t t-raw="record.date"/> </span> - </div> - </t> - </span> - - <div class="o_timeline_parent_message"> - - <span class="o_timeline_msg_icons" t-if="!options.readonly"> <!-- *** read *** --> - <i t-if="options.show_read_unread_button" title="Done" class="oe_read fa fa-check"/> - </span> <!-- *** read *** --> - - <span t-attf-class="o_timeline_parent_subject #{widget.model and widget.res_id - and options.show_link ? 'o_timeline_small_subject' : ''}"> <!-- *** subject *** --> - <span class="o_timeline_subject"> - <t t-if="widget.res_id and widget.subject"> - <t t-raw="widget.record_name"/> : <t t-raw="widget.subject"/> - </t> - <t t-if="widget.res_id and !widget.subject"> - <t t-raw="widget.record_name"/> - </t> - <t t-if="!widget.res_id and widget.subject"> - <t t-raw="widget.subject"/> - </t> - <t t-if="!widget.res_id and !widget.subject"> - No subject - </t> - </span> - </span> <!-- *** subject *** --> - - <span class="o_timeline_go_to_doc" t-if="record.res_id and record.model and options.show_link"> <!-- *** Go to doc *** --> - <a t-attf-href="#action=mail.action_mail_redirect&model=#{record.model}&res_id=#{record.res_id}"> - <i class="fa fa-arrow-circle-right" title="Go to document"></i> - </a> - </span> <!-- *** Go to doc *** --> - - <span class="o_timeline_parent_avatar"> <!-- *** avatar *** --> - <a t-if="options.show_link" - t-attf-href="#model=res.partner&id=#{record.author_id[0]}" - t-att-title="record.author_id[1]"> - <img class="o_timeline_msg_icon" - t-att-src="record.author_avatar"/> - </a> - <img t-if="!options.show_link" class="o_timeline_msg_icon" - t-att-src="record.author_avatar"/> - </span> <!-- *** avatar *** --> - - <span class="o_timeline_parent_author"> <!-- *** author *** --> - <a t-if="options.show_link and record.author_id[0]" - t-attf-href="#model=res.partner&id=#{record.author_id[0]}" - t-att-data-partner="record.author_id[0]" class="o_timeline_action_author" - title="Last sender"> - <t t-raw="record.author_id[2]"/> - </a> - <a t-if="record.author_id and (!options.show_link or !record.author_id[0])" - class="o_timeline_action_author" - title="Last sender"> - <t t-raw="record.author_id[2]"/> - </a> - </span> <!-- *** author *** --> - - <span class="o_timeline_parent_followers"> <!-- *** followers *** --> - <span t-if="widget.nb_followers > 0" title="Number of followers"> <t t-raw="widget.nb_followers"/> </span> - <i t-if="widget.nb_followers > 0" class="oe_follwrs fa fa-users"></i> - </span> <!-- *** followers *** --> - - <span class="o_timeline_msg_icons" t-if="!options.readonly"> <!-- *** repy *** --> - <i t-if="options.show_reply_button" title="Reply" class="oe_reply fa fa-reply"/> - </span> <!-- *** reply *** --> - </div> - </t> - </div> - </t> - <t t-if="!options.is_folded"> - <t t-foreach="widget.messages" t-as="message"> - <t t-call="timeline-message"> - <t t-set="record" t-value="message"/> - </t> - </t> - </t> - </t> - </templates> - </timeline> - </field> - </record> - </data> </openerp> diff --git a/addons/mail/views/mail_templates.xml b/addons/mail/views/mail_templates.xml index a5ea4c93a62..dfe1e8befc4 100644 --- a/addons/mail/views/mail_templates.xml +++ b/addons/mail/views/mail_templates.xml @@ -3,7 +3,6 @@ <data> <template id="assets_backend" name="mail assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> - <script type="text/javascript" src="/mail/static/src/js/mail.js"></script> <script type="text/javascript" src="/mail/static/src/js/mail_utils.js"></script> <script type="text/javascript" src="/mail/static/src/js/mail_followers.js"></script> <script type="text/javascript" src="/mail/static/src/js/many2many_tags_email.js"></script> diff --git a/addons/mail/views/mail_thread_views.xml b/addons/mail/views/mail_thread_views.xml deleted file mode 100644 index 8d4638032db..00000000000 --- a/addons/mail/views/mail_thread_views.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0"?> -<odoo> - - <menuitem id="mail.mail_thread_menu_root" name="Chat" - icon="fa-envelope" web_icon="mail,static/description/icon.png" - groups="base.group_user" sequence="1"/> - - <record id="mail_message_action_inbox" model="ir.actions.act_window"> - <field name="name">Inbox</field> - <field name="res_model">mail.message</field> - <field name="view_type">form</field> - <field name="view_mode">timeline</field> - <field name="context">{ - 'default_model': 'res.users', - 'default_res_id': uid, - 'thread_model': 'res.partner', - 'options' : {'view_mailbox': True, - 'view_inbox': True, - 'show_write_to_followers': False} - }</field> - <field name="domain">[('needaction', '=', True)]</field> - </record> - - <menuitem id="mail.mail_inbox" name="Inbox" action="mail_message_action_inbox" - parent="mail.mail_thread_menu_root" groups="base.group_user" sequence="1"/> - -</odoo> diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml index dfaae8e0ee3..a30edceba76 100644 --- a/addons/portal/portal_view.xml +++ b/addons/portal/portal_view.xml @@ -9,28 +9,6 @@ web_icon="portal,static/description/icon.png" sequence="15"/> - <menuitem name="Messaging" id="portal_messages" parent="portal_menu" sequence="10" groups="base.group_portal"/> - - <record model="ir.actions.act_window" id="mail_message_action_inbox_portal"> - <field name="name">Inbox</field> - <field name="res_model">mail.message</field> - <field name="view_type">form</field> - <field name="view_mode">timeline</field> - <field name="context">{ - 'default_model': 'res.users', - 'default_res_id': uid, - 'thread_model': 'res.partner', - 'options' : {'view_mailbox': True, - 'view_inbox': True, - 'show_link': 'False', - 'show_write_to_followers': False} - }</field> - <field name="domain">[('needaction', '=', True)]</field> - </record> - - <menuitem name="Inbox" id="portal_inbox" parent="portal_messages" - action="mail_message_action_inbox_portal" sequence="10" groups="base.group_portal"/> - <!-- Create menu items that we'll leave empty for now - they'll be filled up by other portal modules. diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index cf0043ad8a2..f3db3be8323 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1475,7 +1475,6 @@ max-width: 892px; margin: 0 auto; padding: 16px 16px 48px; - background-color: #f0eeee; } .openerp .oe_form div.oe_form_configuration p, .openerp .oe_form div.oe_form_configuration ul, .openerp .oe_form div.oe_form_configuration ol { color: #aaa; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 5c3a0e5bd69..68ed4eb36d7 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -1321,7 +1321,6 @@ $sheet-padding: 16px max-width: $sheet-max-width + 2* $sheet-padding margin: 0 auto padding: 16px 16px 48px - background-color: #f0eeee div.oe_form_configuration p, ul, ol color: #aaa diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index d23d75c7850..98edbc55f66 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -207,7 +207,6 @@ class view(osv.osv): ('form','Form'), ('graph', 'Graph'), ('pivot', 'Pivot'), - ('timeline', 'Timeline'), ('calendar', 'Calendar'), ('diagram','Diagram'), ('gantt', 'Gantt'), diff --git a/openerp/addons/base/rng/view.rng b/openerp/addons/base/rng/view.rng index f2bcd74bc8a..47414816afa 100644 --- a/openerp/addons/base/rng/view.rng +++ b/openerp/addons/base/rng/view.rng @@ -701,20 +701,6 @@ </rng:element> </rng:define> - <rng:define name="timeline"> - <rng:element name="timeline"> - <rng:optional><rng:attribute name="string" /></rng:optional> - <rng:zeroOrMore> - <rng:ref name="field"/> - </rng:zeroOrMore> - <rng:element name="templates"> - <rng:oneOrMore> - <rng:ref name="any"/> - </rng:oneOrMore> - </rng:element> - </rng:element> - </rng:define> - <rng:define name="button"> <rng:element name="button"> <rng:ref name="overload"/> @@ -814,7 +800,6 @@ <rng:ref name="notebook" /> <rng:ref name="graph" /> <rng:ref name="pivot" /> - <rng:ref name="timeline" /> <rng:ref name="calendar" /> <rng:ref name="data" /> <rng:ref name="gantt" /> |
