[FIX] mail: improve activity view and fix activity feedback

-Improve no content helper on activity view

-Update chatter after editing an activity un form view

-Avoid context to appear as feedback
When using call_button the context is set as an arg and will be catched by
the kwargs of the called action.

As for action_feedback, we can create a wrapper without kwargs
used when calling this method from a button to avoid this problem.

Another solution would be to change the call_button in order to give
the context as a kwargs. Maybe a possible improvement for master.

-Remove groupby from activity view
group by has no effect on activity

-Change cursor to pointer on record name in activity view

Task: #1878184
PR: #26668
This commit is contained in:
XavierDo
2018-09-07 14:59:05 +02:00
parent dd32131ce6
commit 7f47dcae5b
8 changed files with 130 additions and 17 deletions
+6 -1
View File
@@ -364,8 +364,13 @@ class MailActivity(models.Model):
self.unlink()
return message.ids and message.ids[0] or False
def action_done_schedule_next(self):
""" Wrapper without feedback because web button add context as
parameter, therefore setting context to feedback """
return self.action_feedback_schedule_next()
@api.multi
def action_done_schedule_next(self, feedback=False):
def action_feedback_schedule_next(self, feedback=False):
wizard_ctx = dict(
self.env.context,
default_previous_activity_type_id=self.activity_type_id.id,
+2 -2
View File
@@ -163,7 +163,7 @@ var BasicActivity = AbstractField.extend({
var self = this;
this._rpc({
model: 'mail.activity',
method: 'action_done_schedule_next',
method: 'action_feedback_schedule_next',
args: [[activityID]],
kwargs: {feedback: feedback},
context: this.record.getContext(),
@@ -228,7 +228,7 @@ var BasicActivity = AbstractField.extend({
_onEditActivity: function (ev) {
ev.preventDefault();
var activityID = $(ev.currentTarget).data('activity-id');
return this._openActivityForm(activityID, this._reload.bind(this));
return this._openActivityForm(activityID, this._reload.bind(this, { activity: true, thread: true }));
},
/**
* Called when marking an activity as done
@@ -29,7 +29,7 @@ var ActivityRenderer = AbstractRenderer.extend({
.empty();
if (this.state.data.activity_types.length === 0) {
this.$el.append(QWeb.render('mail.ActivityViewNoContentHelper'));
this.$el.append(QWeb.render('ActivityView.nodata'));
} else {
var $table = $('<table>')
.addClass('table-bordered')
@@ -20,6 +20,7 @@ var ActivityView = AbstractView.extend({
Renderer: ActivityRenderer,
}),
viewType: 'activity',
groupable: false,
});
view_registry.add('activity', ActivityView);
@@ -34,6 +34,7 @@
&:hover {
color: #666;
}
cursor: pointer;
}
.o_activity_type_cell {
padding:10px;
+7 -4
View File
@@ -15,14 +15,17 @@
</th>
</t>
<t t-name="mail.ActivityViewNoContentHelper">
<div class="o_view_nocontent">
<div t-name="ActivityView.nodata">
<div class="o_view_nocontent" role="alert">
<div class="o_nocontent_help">
<p class="o_view_nocontent_empty_folder">
No scheduled activity yet
No data to display
</p><p>
Try to add some activity on records, or make sure that
there is no active filter in the search bar.
</p>
</div>
</div>
</t>
</div>
</templates>
+44 -6
View File
@@ -4,6 +4,8 @@ odoo.define('mail.activity_view_tests', function (require) {
var ActivityView = require('mail.ActivityView');
var testUtils = require('web.test_utils');
var createActionManager = testUtils.createActionManager;
var createView = testUtils.createView;
var ACTIVITY_DATA = {
"grouped_activities":{
@@ -204,8 +206,8 @@ QUnit.test('activity view: no content rendering', function (assert) {
assert.strictEqual(activity.$('.o_view_nocontent').length, 1,
"should display the no content helper");
assert.strictEqual(activity.$('.o_view_nocontent').text().trim(),
"No scheduled activity yet",
assert.strictEqual(activity.$('.o_view_nocontent .o_view_nocontent_empty_folder').text().trim(),
"No data to display",
"should display the no content helper text");
activity.destroy();
@@ -263,10 +265,10 @@ QUnit.test('activity view: activity widget', function (assert) {
assert.step('activity_send_mail');
return $.when();
}
if (args.method === 'action_done_schedule_next'){
assert.deepEqual([[3]],args.args, "Should execute action_done_schedule_next on activity 3 only ");
if (args.method === 'action_feedback_schedule_next'){
assert.deepEqual([[3]],args.args, "Should execute action_feedback_schedule_next on activity 3 only ");
assert.equal(args.kwargs.feedback, "feedback2");
assert.step('action_done_schedule_next');
assert.step('action_feedback_schedule_next');
return $.when({serverGeneratedAction: true});
}
if (args.method === 'get_activity_data') {
@@ -329,12 +331,48 @@ QUnit.test('activity view: activity widget', function (assert) {
"do_action_compose",
"activity_send_mail",
"do_action_activity",
"action_done_schedule_next",
"action_feedback_schedule_next",
"serverGeneratedAction"
]);
activity.destroy();
});
QUnit.test('activity view: no group by', function (assert) {
assert.expect(4);
var actionManager = createActionManager({
actions: [{
id: 1,
name: 'Task Action',
res_model: 'task',
type: 'ir.actions.act_window',
views: [[false, 'activity']],
}],
archs: {
'task,false,activity': '<activity></activity>',
'task,false,search': '<search></search>',
},
data: this.data,
mockRPC: function(route, args) {
if (args.method === 'get_activity_data') {
return $.when(ACTIVITY_DATA);
}
return this._super(route, args);
},
});
actionManager.doAction(1);
assert.strictEqual($('.o_search_options .o_dropdown:visible').length, 2,
"only two elements should be available in view search");
assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1,
"filter should be available in view search");
assert.strictEqual($('.o_search_options .o_dropdown:visible .o_favorites_menu').length, 1,
"favorites should be available in view search");
assert.strictEqual($('.o_search_options .o_dropdown:hidden .o_group_by_menu').length, 1,
"group by should be hidden");
actionManager.destroy();
});
});
});
+68 -3
View File
@@ -447,7 +447,7 @@ QUnit.test('kanban activity widget popover test', function (assert) {
'</t></templates>' +
'</kanban>',
mockRPC: function (route, args) {
if (route === '/web/dataset/call_kw/mail.activity/action_done_schedule_next') {
if (route === '/web/dataset/call_kw/mail.activity/action_feedback_schedule_next') {
rpcCount++;
var current_ids = this.data.partner.records[0].activity_ids;
@@ -1224,8 +1224,8 @@ QUnit.test('form activity widget: schedule next activity', function (assert) {
'</form>',
res_id: 2,
mockRPC: function (route, args) {
if (route === '/web/dataset/call_kw/mail.activity/action_done_schedule_next') {
assert.ok(_.isEqual(args.args[0], [1]), "should call 'action_done_schedule_next' for id 1");
if (route === '/web/dataset/call_kw/mail.activity/action_feedback_schedule_next') {
assert.ok(_.isEqual(args.args[0], [1]), "should call 'action_feedback_schedule_next' for id 1");
assert.strictEqual(args.kwargs.feedback, 'everything is ok',
"the feedback should be sent correctly");
return $.when('test_result');
@@ -1248,6 +1248,71 @@ QUnit.test('form activity widget: schedule next activity', function (assert) {
form.destroy();
});
QUnit.test('form activity widget: edit next activity', function (assert) {
assert.expect(3);
var self = this;
this.data.partner.records[0].activity_ids = [1];
this.data.partner.records[0].activity_state = 'today';
this.data['mail.activity'].records = [{
id: 1,
display_name: "An activity",
date_deadline: moment().format("YYYY-MM-DD"), // now
state: "today",
user_id: 2,
create_user_id: 2,
activity_type_id: 2,
}];
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
services: this.services,
arch: '<form string="Partners">' +
'<sheet>' +
'<field name="foo"/>' +
'</sheet>' +
'<div class="oe_chatter">' +
'<field name="message_ids" widget="mail_thread"/>' +
'<field name="activity_ids" widget="mail_activity"/>' +
'</div>' +
'</form>',
res_id: 2,
intercepts: {
do_action: function (event) {
assert.deepEqual(event.data.action, {
context: {
default_res_id: 2,
default_res_model: "partner"
},
res_id: 1,
res_model: "mail.activity",
target: "new",
type: "ir.actions.act_window",
view_mode: "form",
view_type: "form",
views: [
[
false,
"form"
]
]
},
"should do a do_action with correct parameters");
self.data['mail.activity'].records[0].activity_type_id = 1;
event.data.options.on_close();
},
},
});
assert.strictEqual(form.$('.o_mail_activity .o_mail_info strong:eq(1)').text(), " Type 2",
"Initial type should be Type 2");
form.$('.o_mail_activity .o_edit_activity[data-activity-id=1]').click();
assert.strictEqual(form.$('.o_mail_activity .o_mail_info strong:eq(1)').text(), " Type 1",
"After edit type should be Type 1");
form.destroy();
});
QUnit.test('form activity widget: clic mail template', function (assert) {
assert.expect(4);
this.data.partner.records[0].activity_ids = [1];