[IMP] mail: add force_next on activity type

A new field on activity type allow to change the behaviour of mark done & schedule next:
-marking as done will automatically schedule the next activity, based on the default_next_activity.
-It should also be impossible to edit an activity when this flag is on.

task: #1884521
This commit is contained in:
XavierDo
2018-09-18 13:44:00 +02:00
parent 44fd3bc808
commit 47496b9fe5
9 changed files with 103 additions and 69 deletions
@@ -27,7 +27,7 @@
<attribute name="attrs">{'invisible': [('activity_category', '=', 'meeting')]}</attribute>
</xpath>
<xpath expr="//button[@name='action_done']" position="attributes">
<attribute name="attrs">{'invisible': [('activity_category', '=', 'meeting')]}</attribute>
<attribute name="attrs">{'invisible': ['|', ('activity_category', '=', 'meeting'), ('force_next', '=', True)]}</attribute>
</xpath>
<xpath expr="//button[@special='cancel']" position="attributes">
<attribute name="attrs">{'invisible': [('activity_category', '=', 'meeting')]}</attribute>
+1 -1
View File
@@ -18,7 +18,7 @@ class Users(models.Model):
continue
activity['icon'] = modules.module.get_module_icon('contacts')
activity['actions'] = [{
'icon': 'fa-clock-o',
'icon': 'fa-th',
'name': 'Summary',
'action_xmlid': 'contacts.action_contacts_summary'
}]
+29 -18
View File
@@ -58,6 +58,7 @@ class MailActivityType(models.Model):
' and not available when managing activities for other models.')
default_next_type_id = fields.Many2one('mail.activity.type', 'Default Next Activity',
domain="['|', ('res_model_id', '=', False), ('res_model_id', '=', res_model_id)]")
force_next = fields.Boolean("Auto-launched next activity", default=False)
next_type_ids = fields.Many2many(
'mail.activity.type', 'mail_activity_rel', 'activity_id', 'recommended_id',
domain="['|', ('res_model_id', '=', False), ('res_model_id', '=', res_model_id)]",
@@ -151,6 +152,7 @@ class MailActivity(models.Model):
compute='_compute_has_recommended_activities',
help='Technical field for UX purpose')
mail_template_ids = fields.Many2many(related='activity_type_id.mail_template_ids')
force_next = fields.Boolean(related='activity_type_id.force_next')
@api.multi
@api.onchange('previous_activity_type_id')
@@ -371,24 +373,33 @@ class MailActivity(models.Model):
@api.multi
def action_feedback_schedule_next(self, feedback=False):
wizard_ctx = dict(
self.env.context,
default_previous_activity_type_id=self.activity_type_id.id,
activity_previous_deadline=self.date_deadline,
default_res_id=self.res_id,
default_res_model=self.res_model,
)
self.action_feedback(feedback)
return {
'name': _('Schedule an Activity'),
'context': wizard_ctx,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.activity',
'views': [(False, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
}
ctx = dict(
self.env.context,
default_previous_activity_type_id=self.activity_type_id.id,
activity_previous_deadline=self.date_deadline,
default_res_id=self.res_id,
default_res_model=self.res_model,
)
force_next = self.force_next
self.action_feedback(feedback) # will unlink activity, dont access self after that
if force_next:
Activity = self.env['mail.activity'].with_context(ctx)
res = Activity.new(Activity.default_get(Activity.fields_get()))
res._onchange_previous_activity_type_id()
res._onchange_activity_type_id()
Activity.create(res._convert_to_write(res._cache))
return False
else:
return {
'name': _('Schedule an Activity'),
'context': ctx,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.activity',
'views': [(False, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
}
@api.multi
def action_close_dialog(self):
+11 -6
View File
@@ -169,11 +169,15 @@ var BasicActivity = AbstractField.extend({
context: this.record.getContext(),
}).then(
function (rslt_action) {
self.do_action(rslt_action, {
on_close: function () {
self.trigger_up('reload');
},
});
if (rslt_action) {
self.do_action(rslt_action, {
on_close: function () {
self.trigger_up('reload');
},
});
} else {
self.trigger_up('reload');
}
}
);
},
@@ -270,6 +274,7 @@ var BasicActivity = AbstractField.extend({
var $popoverElement = $(ev.currentTarget);
var activityID = $popoverElement.data('activity-id');
var previousActivityTypeID = $popoverElement.data('previous-activity-type-id');
var forceNextActivity = $popoverElement.data('force-next-activity');
if (!$popoverElement.data('bs.popover')) {
$popoverElement.popover({
template: $(Popover.Default.template).addClass('o_mail_activity_feedback')[0].outerHTML, // Ugly but cannot find another way
@@ -279,7 +284,7 @@ var BasicActivity = AbstractField.extend({
trigger:'click',
placement: 'right', // FIXME: this should work, maybe a bug in the popper lib
content : function () {
var $popover = $(QWeb.render('mail.activity_feedback_form', { previous_activity_type_id: previousActivityTypeID }));
var $popover = $(QWeb.render('mail.activity_feedback_form', { previous_activity_type_id: previousActivityTypeID, force_next: forceNextActivity}));
$popover.find('#activity_feedback').val(self._draftFeedback[activityID]);
$popover.on('click', '.o_activity_popover_done', function (ev) {
ev.stopPropagation();
@@ -13,7 +13,7 @@ var _lt = core._lt;
var ActivityView = AbstractView.extend({
accesskey: "a",
display_name: _lt('Activity'),
icon: 'fa-clock-o',
icon: 'fa-th',
config: _.extend({}, AbstractView.prototype.config, {
Controller: ActivityController,
Model: ActivityModel,
@@ -200,7 +200,7 @@
background-color: $o-brand-lightsecondary;
}
&.o_edit_activity {
&.o_log_activity {
padding: 8px 10px 8px 0px;
vertical-align: middle;
&:hover {
+16 -9
View File
@@ -75,9 +75,10 @@
</div>
</t>
<div class="o_thread_message_tools btn-group">
<span class="o_mark_as_done" data-toggle="popover" t-att-data-activity-id="activity.id" t-att-data-previous-activity-type-id="activity.activity_type_id[0]"><a role="button" href="#" class="btn btn-link btn-success text-muted o_activity_link mr8">
<i class="fa fa-check"/> Mark Done
</a></span>
<span class="o_mark_as_done" data-toggle="popover" t-att-data-activity-id="activity.id" t-att-data-force-next-activity="activity.force_next" t-att-data-previous-activity-type-id="activity.activity_type_id[0]">
<a role="button" href="#" class="btn btn-link btn-success text-muted o_activity_link mr8">
<i class="fa fa-check"/> Mark Done </a>
</span>
<a role="button" href="#" class="btn btn-link btn-secondary text-muted o_edit_activity o_activity_link" t-att-data-activity-id="activity.id">
<i class="fa fa-pencil"/> Edit
</a>
@@ -94,12 +95,18 @@
<div>
<textarea class="form-control" rows="3" id="activity_feedback" placeholder="Write Feedback"/>
<div class="mt8">
<button type="button" class="btn btn-sm btn-primary o_activity_popover_done_next" t-att-data-previous-activity-type-id="previous_activity_type_id">
Done &amp; Schedule Next</button>
<button type="button" class="btn btn-sm btn-primary o_activity_popover_done">
Done</button>
<button type="button" class="btn btn-sm btn-link o_activity_popover_discard">
Discard</button>
<t t-if="!force_next">
<button type="button" class="btn btn-sm btn-primary o_activity_popover_done_next" t-att-data-previous-activity-type-id="previous_activity_type_id">
Done &amp; Schedule Next</button>
<button type="button" class="btn btn-sm btn-primary o_activity_popover_done">
Done</button>
<button type="button" class="btn btn-sm btn-link o_activity_popover_discard">
Discard</button>
</t>
<t t-else="">
<button type="button" class="btn btn-sm btn-primary o_activity_popover_done_next">
Done &amp; Launch Next</button>
</t>
</div>
</div>
</t>
@@ -29,38 +29,44 @@
<t t-esc="selection[key]" /> (<t t-esc="logs.length"/>)
</strong>
</li>
<li t-foreach="logs" t-as="log" t-att-data-activity-id="log.id" class="nav-item o_edit_activity" role="menuitem">
<div class="o_activity_title float-left">
<span t-attf-class="fa #{log.icon} fa-fw" role="img" aria-label="Log" title="Log"/>
<strong>
<t t-esc="log.title_action or log.activity_type_id[1]" />
</strong>
<div>
<span class="fa fa-clock-o fa-fw" role="img" aria-label="Deadline" title="Deadline"/>
<span t-att-title="log.date_deadline"><t t-esc="log.label_delay" /></span>
<div class="mt16" t-att-data-activity-id="log.id" t-att-data-previous-activity-type-id="log.activity_type_id[0]">
<t t-if="log.mail_template_ids">
<t t-foreach="log.mail_template_ids" t-as="mail_template">
<div>
<i class="fa fa-envelope-o" aria-label="Mail" title="Mail" role="img"></i>
<span t-esc="mail_template.name"/>:
<span class="o_activity_template_preview" t-att-data-template-id="mail_template.id">Preview</span>
<span class="text-muted">or</span>
<span class="o_activity_template_send" t-att-data-template-id="mail_template.id">Send Now</span>
</div>
<t t-foreach="logs" t-as="log">
<t t-set="edit_class" t-value="'o_edit_activity'"/>
<t t-if="log.force_next">
<t t-set="edit_class" t-value=""/>
</t>
<li t-att-data-activity-id="log.id" t-attf-class="nav-item o_log_activity #{edit_class}" role="menuitem">
<div class="o_activity_title float-left">
<span t-attf-class="fa #{log.icon} fa-fw" role="img" aria-label="Log" title="Log"/>
<strong>
<t t-esc="log.title_action or log.activity_type_id[1]" />
</strong>
<div>
<span class="fa fa-clock-o fa-fw" role="img" aria-label="Deadline" title="Deadline"/>
<span t-att-title="log.date_deadline"><t t-esc="log.label_delay" /></span>
<div class="mt16" t-att-data-activity-id="log.id" t-att-data-force-next-activity="log.force_next" t-att-data-previous-activity-type-id="log.activity_type_id[0]">
<t t-if="log.mail_template_ids">
<t t-foreach="log.mail_template_ids" t-as="mail_template">
<div>
<i class="fa fa-envelope-o" aria-label="Mail" title="Mail" role="img"></i>
<span t-esc="mail_template.name"/>:
<span class="o_activity_template_preview" t-att-data-template-id="mail_template.id">Preview</span>
<span class="text-muted">or</span>
<span class="o_activity_template_send" t-att-data-template-id="mail_template.id">Send Now</span>
</div>
</t>
</t>
</div>
<t t-if="log.user_id[0] != uid">
<span class="ml4 fa fa-user" role="img" aria-label="User" title="User"/>
<span><t t-esc="log.user_id[1]" /></span>
</t>
</div>
<t t-if="log.user_id[0] != uid">
<span class="ml4 fa fa-user" role="img" aria-label="User" title="User"/>
<span><t t-esc="log.user_id[1]" /></span>
</t>
</div>
</div>
<div class="float-right">
<span class="o_mark_as_done o_activity_link o_activity_link_kanban fa fa-check-circle fa-2x mt4" t-att-data-previous-activity-type-id="log.activity_type_id[0]" t-att-data-activity-id="log.id" title="Mark as done" role="img" aria-label="Mark as done"/>
</div>
</li>
<div class="float-right">
<span class="o_mark_as_done o_activity_link o_activity_link_kanban fa fa-check-circle fa-2x mt4" t-att-data-force-next-activity="log.force_next" t-att-data-previous-activity-type-id="log.activity_type_id[0]" t-att-data-activity-id="log.id" title="Mark as done" role="img" aria-label="Mark as done"/>
</div>
</li>
</t>
</t>
</ul>
</div>
+9 -4
View File
@@ -32,9 +32,10 @@
</div>
</group>
<group>
<field name="force_next"/>
<field name="default_next_type_id" attrs="{'required': [('force_next', '=', True)]}" context="{'default_res_model_id': res_model_id}"/>
<field name="next_type_ids" widget="many2many_tags"
context="{'default_res_model_id': res_model_id}"/>
<field name="default_next_type_id" context="{'default_res_model_id': res_model_id}"/>
attrs="{'invisible': [('force_next', '=', True)]}" context="{'default_res_model_id': res_model_id}"/>
<field name="mail_template_ids" widget="many2many_tags"
domain="[('model_id', '=', res_model_id)]"
attrs="{'invisible': [('res_model_id', '=', False)]}"
@@ -100,6 +101,7 @@
<field name="res_model" invisible="1"/>
<field name="res_model_id" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="force_next" invisible="1"/>
<field name="previous_activity_type_id"/>
<field name="has_recommended_activities"/>
</group>
@@ -125,10 +127,13 @@
<footer>
<button string="Schedule" name="action_close_dialog"
type="object" class="btn-primary"/>
<button string="Mark as Done" name="action_done"
<button attrs="{'invisible': [('force_next', '=', True)]}" string="Mark as Done" name="action_done"
type="object" class="btn-secondary"
context="{'mail_activity_quick_update': True}"/>
<button string="Done &amp; Schedule Next" name="action_done_schedule_next"
<button attrs="{'invisible': [('force_next', '=', True)]}" string="Done &amp; Schedule Next" name="action_done_schedule_next"
type="object" class="btn-secondary"
context="{'mail_activity_quick_update': True}"/>
<button attrs="{'invisible': [('force_next', '=', False)]}" string="Done &amp; Launch Next" name="action_done_schedule_next"
type="object" class="btn-secondary"
context="{'mail_activity_quick_update': True}"/>
<button string="Discard" class="btn-secondary" special="cancel" />