Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.0][mail_activity_board] Add new module that insert activities board in boards. #283

Merged
merged 23 commits into from
Nov 2, 2018
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d56c2f0
[ADD] Module that insert activities board.
Jun 12, 2018
4b929c4
[FIX] Author error in __manifest__ file and style changes.
Jun 13, 2018
7ed0a4c
[FIX] Fix replace in view, rename files and style changes.
Jun 13, 2018
919f33e
[FIX] Enumerated list ends without a blank line; unexpected unindent.
Jun 14, 2018
cc486cb
[FIX] Name fail.
Jun 14, 2018
4caf09e
[FIX] Bug in view.
Jun 14, 2018
ad7b784
[FIX] Add button Activities in mail.thread and readme folder. Others…
Jul 8, 2018
f870bad
[FIX] Type 'tree' not found in registry: problem solved.
Jul 9, 2018
ce43235
[FIX] Dependence change: 'mail' for 'calendar'.
Jul 9, 2018
82dd15e
[FIX] Eliminated unnecessary imports.
Jul 9, 2018
470b3dc
[FIX] Bugs about js and if/else.
Jul 13, 2018
4456f9e
[FIX] Improvements following guide lines and eliminating unnecessary …
Jul 16, 2018
e93ca79
[ADD] Added counter in the 'Activities List' button.
Jul 16, 2018
676a3ed
[FIX] Bugs in javascript with 'Activities' button.
Jul 17, 2018
0146f61
[ADD] Tests folder.
dajuayen Sep 8, 2018
926cc1f
[FIX] Deleted references to modules not installed.
dajuayen Sep 9, 2018
d642084
[FIX] Formatting javascript.
dajuayen Sep 9, 2018
21b8b8a
[FIX] Bug: added a soft line before a class.
dajuayen Sep 9, 2018
28c6295
[FIX] Bug: https://github.com/OCA/social/pull/283#discussion_r204302325
dajuayen Sep 9, 2018
0bdcc94
[FIX] Escaping 'lt' in xml file. Bug: https://github.com/OCA/social/p…
dajuayen Sep 10, 2018
bbb99e7
[FIX] The meeting attendees are shown in kanban mode on the meeting b…
dajuayen Sep 16, 2018
3ddadf7
[FIX] Hide in form view of the activity board the assistant field if …
dajuayen Sep 16, 2018
97297af
[FIX] Change to default kanban view for partners.
dajuayen Sep 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions mail_activity_board/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
**This file is going to be generated by oca-gen-addon-readme.**

*Manual changes will be overwritten.*

Please provide content in the ``readme`` directory:

* **DESCRIPTION.rst** (required)
* INSTALL.rst (optional)
* CONFIGURE.rst (optional)
* **USAGE.rst** (optional, highly recommended)
* DEVELOP.rst (optional)
* ROADMAP.rst (optional)
* HISTORY.rst (optional, recommended)
* **CONTRIBUTORS.rst** (optional, highly recommended)
* CREDITS.rst (optional)

Content of this README will also be drawn from the addon manifest,
from keys such as name, authors, maintainers, development_status,
and license.

A good, one sentence summary in the manifest is also highly recommended.
1 change: 1 addition & 0 deletions mail_activity_board/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
24 changes: 24 additions & 0 deletions mail_activity_board/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Activities board',
'summary': 'Add Activity Boards',
'version': '11.0.1.0.0',
'development_status': 'Beta',
'category': 'Social Network',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Doesn't seem much of social, isn't it? Is there another better category for this?

Copy link
Contributor Author

@dajuayen dajuayen Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have corrected this and for the moment I have set Uncategorized.
I accept suggestions.

'website': 'https://github.com/OCA/social',
'author': 'SDi, David Juaneda, Odoo Community Association (OCA)',
'license': 'AGPL-3',
'installable': True,
'depends': [
'calendar',
'board',
],
'data': [
'views/templates.xml',
'views/mail_activity_view.xml',
],
'qweb': [
'static/src/xml/inherit_chatter.xml',
]
}
2 changes: 2 additions & 0 deletions mail_activity_board/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_activity
from . import mail_activity_mixin
40 changes: 40 additions & 0 deletions mail_activity_board/models/mail_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, models, fields


class MailActivity(models.Model):
_inherit = "mail.activity"

res_model_id_name = fields.Char(
related='res_model_id.name', string="Origin",
readonly=True)
duration = fields.Float(
related='calendar_event_id.duration', readonly=True)
calendar_event_id_start = fields.Datetime(
related='calendar_event_id.start', readonly=True)
calendar_event_id_partner_ids = fields.Many2many(
related='calendar_event_id.partner_ids',
Stringreadonly=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, wrong parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG 😧


@api.multi
def open_origin(self):
self.ensure_one()
response = {'type': 'ir.actions.act_window',
'res_model': self.res_model,
'view_mode': 'form',
'res_id': self.res_id,
'target': 'current',
'flags': {'form': {'action_buttons': False}}}
if self.res_model == 'crm.lead':
res_type = self.env['crm.lead'].browse(self.res_id).type
if res_type == 'opportunity':
view_id = self.env.ref("crm.crm_case_form_view_oppor").id
response['view_id'] = view_id
return response

@api.model
def action_activities_board(self):
action = self.env.ref(
'mail_activity_board.open_boards_activities').read()[0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just do self.env.ref(...).id

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They do not return the same.
self.env.ref ('...'). read () [0] returns a dictionary with all the data of the action.
self.env.ref ('...'). id only returns the id (int) of the action.

I can not change it

return action
32 changes: 32 additions & 0 deletions mail_activity_board/models/mail_activity_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2018 David Juaneda - <djuaneda@sdi.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models


class MailActivityMixin(models.AbstractModel):
_inherit = 'mail.activity.mixin'

def redirect_to_activities(self, **kwargs):
"""Redirects to the list of activities of the object shown.
Redirects to the activity board and configures the domain so that
only those activities that are related to the object shown are
displayed.
Add to the title of the view the name the class of the object from
which the activities will be displayed.
:param kwargs: contains the id of the object and the model it's about.
:return: action.
"""
id = kwargs.get("id")
action = self.env['mail.activity'].action_activities_board()
views = []
for v in action['views']:
if v[1] == 'tree':
v = (v[0], 'list')
views.append(v)
action['views'] = views
action['domain'] = [('res_id', '=', id)]
return action
3 changes: 3 additions & 0 deletions mail_activity_board/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `SDI <https://www.sdi.es>`_:

* David Juaneda
2 changes: 2 additions & 0 deletions mail_activity_board/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module adds an activity board with form, tree, kanban, calendar, pivot, graph and search views.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

9 changes: 9 additions & 0 deletions mail_activity_board/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
To use this module, you need to:

#. Access to the views from menu Boards.

A smartButton of activities is added in the mail thread from form view.
From this smartButton is linked to the activity board, to the view tree,
which shows the activities related to the opportunity.

From the form view of the activity you can navigate to the origin of the activity.
75 changes: 75 additions & 0 deletions mail_activity_board/static/src/js/override_chatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* Copyright 2018 David Juaneda
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */

odoo.define('mail.Chatter.activity', function(require){
"use strict";

var chatter = require('mail.Chatter');
var concurrency = require('web.concurrency');
var core = require('web.core');
var _t = core._t;
var QWeb = core.qweb;

chatter.include({

events: _.extend({}, chatter.prototype.events, {
'click .o_chatter_button_list_activity': '_onListActivity',
}),

_onListActivity: function (event) {
event.preventDefault();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed if you add type="button" to the button. Remove and see comments below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean only the line:

event.preventDefault();

this._rpc({
model: this.record.model,
method: 'redirect_to_activities',
args: [[]],
kwargs: {'id':this.record.res_id,
'model':this.record.model},
context: this.record.getContext(),
}).then($.proxy(this, "do_action"));
},
_formatActivitiesList: function (count){
var str = '';
if (count <= 0) {
str = _t('No activities');
} else if (count === 1){
str = _t('One activity');
} else {
str = ''+count+' '+_t('activities');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method makes sense in your language and some others, but did you know that Russian has different plurals, depending on if the number ends by 2-4 or by other number? And of course, they have singular too. And it's not a corner case. You likely don't want this kind of methods that return different strings depending on the number. Gettext itself should handle that, and if it doesn't, it's upstream's problem (and also I don't think it will affect you, since your language follows the same rules as English).

It's much simpler to be dumber and just do:

return _.str.sprintf(_t("%d activities"));

... which wouldn't be so extremely bad if rendered as 1 activities. You can even translate that into Spanish as %d actividad/es, which is perfectly OK.

This also should make you realize that using a method just for this is not much needed. You can just do that call inline and it should be OK.

In any case, this is being used just to add a title attribute to the button, but we can simply hardcode a more useful title and forget about all of this; so, just remove this whole _formatActivitiesList method please.

I'm just trying to give you a bigger picture about how translations work (or should work), so you can remove all this complexities from your mind (and code!). 😉

Copy link
Contributor Author

@dajuayen dajuayen Jul 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for advice.
When I don't know how to make something I use to find in ODOO folder a piece of code similar to I want to do and copy it.
I found in followers.js something similar:

   _formatFollowers: function (count){
        var str = '';
        if (count <= 0) {
            str = _t('No follower');
        } else if (count === 1){
            str = _t('One follower');
        } else {
            str = ''+count+' '+_t('followers');
        }
        return str;
    }

In next times I'll try to be more efficient and follow your wise advice.

I 🔥 it already

}
return str;
},
_render: function (def) {
// the rendering of the chatter is aynchronous: relational data of its fields needs to be
// fetched (in some case, it might be synchronous as they hold an internal cache).
// this function takes a deferred as argument, which is resolved once all fields have
// fetched their data
// this function appends the fields where they should be once the given deferred is resolved
// and if it takes more than 500ms, displays a spinner to indicate that it is loading
var self = this;

console.log(self.fields.activity);

var $spinner = $(QWeb.render('Spinner'));
concurrency.rejectAfter(concurrency.delay(500), def).then(function () {
$spinner.appendTo(self.$el);
});
return def.then(function () {
if (self.fields.activity) {
self.$('.o_list_activity')
.html(self.fields.activity.activities.length)
.parent().attr("title", self._formatActivitiesList(self.fields.activity.activities.length));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you're duplicating almost all of upstream method just to add these 2 lines, breaking the call chain. Sorry, but that shouldn't be done. 🚫

You have 3 options:

  1. Override the start() method, call its _super(), and, once done, make the changes into this.$topbar, which is there rendered synchronously. All of this deferred rendering of fields has no relation with what you're modifying, which is actually the buttons bar, not the fields themselves.
  2. Vote for [IMP] web: Expose chatter widget to render buttons odoo/odoo#25801 to be merged, and just do all overrides directly in Qweb, as explained below.
  3. Simply show static buttons. That can be done through Qweb only, and wouldn't need [IMP] web: Expose chatter widget to render buttons odoo/odoo#25801 to be merged. I recommend this approach, at least for now; see below.

Remove this _render() method in any case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed _render().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I wrote down option 1. I'm stubborn.


self.fields.activity.$el.appendTo(self.$el);

}
if (self.fields.followers) {
self.fields.followers.$el.appendTo(self.$topbar);
}
if (self.fields.thread) {
self.fields.thread.$el.appendTo(self.$el);
}
}).always($spinner.remove.bind($spinner));
},

});
});
12 changes: 12 additions & 0 deletions mail_activity_board/static/src/xml/inherit_chatter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-extend="mail.Chatter.Buttons">
<t t-jquery="button.o_chatter_button_schedule_activity" t-operation="after">
<button t-if="schedule_activity_btn" class="btn btn-sm btn-link o_chatter_button_list_activity">
<span class="o_list_activity label label-primary"/> <t t-if="isMobile">List</t><t t-else="">Activities list</t>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some points here:

  1. If you need to display something depending on screen size, it's better to do it this way by pure bootstrap CSS:

    <span class="hidden-xs">Activities list</span>
    <span class="visible-xs-inline">Activities</span>

    The less JS and the more CSS you use, the faster everything is. However...

  2. ... KISS; just use "Activities". The "list" word here adds nothing useful really.

  3. Additions should be done here, and not above in the _render() method; however, it's true that will only be possible after [IMP] web: Expose chatter widget to render buttons odoo/odoo#25801 is merged.

So, it should end up being similar to this, as of today:

<button t-if="schedule_activity_btn" class="btn btn-sm btn-link o_chatter_button_list_activity" title="See activities list" type="button">
  Activities
</button>

Once odoo/odoo#25801 is merged, if ever, it could become this:

 <button t-if="schedule_activity_btn" class="btn btn-sm btn-link o_chatter_button_list_activity" title="See activities list" type="button">
+  <span class="o_list_activity label label-primary">
+    <t t-esc="widget.fields.activity.activities.length"/>
+  </span>
   Activities
 </button>

Copy link
Contributor Author

@dajuayen dajuayen Jul 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I have already mentioned to you, when I have to do something, I try to look at how it is done in another part of the code and imitate it.
 
I thought that instead of using an icon, I could use the number of activities for it, in the style of followers and the number of activities when the list of activities is minimized.

What a pity
😔

</button>
</t>
</t>

</templates>
Loading