-
-
Notifications
You must be signed in to change notification settings - Fork 623
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
Changes from 13 commits
d56c2f0
4b929c4
7ed0a4c
919f33e
cc486cb
4caf09e
ad7b784
f870bad
ce43235
82dd15e
470b3dc
4456f9e
e93ca79
676a3ed
0146f61
926cc1f
d642084
21b8b8a
28c6295
0bdcc94
bbb99e7
3ddadf7
97297af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
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', | ||
'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', | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import mail_activity | ||
from . import mail_activity_mixin |
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, wrong parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They do not return the same. I can not change it |
||
return action |
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* `SDI <https://www.sdi.es>`_: | ||
|
||
* David Juaneda |
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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔥 |
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. |
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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed if you add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean only the line:
|
||
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'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
... 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 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!). 😉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for advice. _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)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
Remove this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed _render(). There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)); | ||
}, | ||
|
||
}); | ||
}); |
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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some points here:
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> There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. What a pity |
||
</button> | ||
</t> | ||
</t> | ||
|
||
</templates> |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.