[IMP] mail: clean legacy activity file (2)

- move BasicActivity to KanbanActivity (only usage of that abstract class)
- remove useless class o_activity_link
- remove useless class o_activity_label
- move d-flex from o_activity_title_entry to template
- move align-items-baseline from o_activity_title_entry to template
- move o_no_activity SCSS to template
- clean selection compute
- clean record_id
- clean activityState, _setState, _reset
- remove obsolete unlink activity code

closes odoo/odoo#99824

Related: odoo/enterprise#31201
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Sébastien Theys
2022-09-09 16:23:43 +02:00
parent 390c36f42f
commit e8b369e724
4 changed files with 52 additions and 122 deletions
+41 -104
View File
@@ -13,25 +13,38 @@ const QWeb = core.qweb;
const _t = core._t;
const _lt = core._lt;
const BasicActivity = AbstractField.extend({
// -----------------------------------------------------------------------------
// Activities Widget for Kanban views ('kanban_activity' widget)
// -----------------------------------------------------------------------------
const KanbanActivity = AbstractField.extend({
template: 'mail.KanbanActivity',
events: {
'click .o_edit_activity': '_onEditActivity',
'change input.o_input_file': '_onFileChanged',
'click .o_activity_template_preview': '_onPreviewMailTemplate',
'click .o_activity_template_send': '_onSendMailTemplate',
'click .o_edit_activity': '_onEditActivity',
'click .o_mark_as_done': '_onMarkActivityDone',
'click .o_mark_as_done_upload_file': '_onMarkActivityDoneUploadFile',
'click .o_activity_template_preview': '_onPreviewMailTemplate',
'click .o_schedule_activity': '_onScheduleActivity',
'click .o_activity_template_send': '_onSendMailTemplate',
'click .o_unlink_activity': '_onUnlinkActivity',
'show.bs.dropdown': '_onDropdownShow',
},
init() {
this._super.apply(this, arguments);
this._draftFeedback = {};
fieldDependencies: {
activity_exception_decoration: { type: 'selection' },
activity_exception_icon: { type: 'char' },
activity_state: { type: 'selection' },
},
//------------------------------------------------------------
// Public
//------------------------------------------------------------
/**
* @override
*/
init(parent, name, record) {
this._super.apply(this, arguments);
this._draftFeedback = {};
this.selection = {};
for (const [key, value] of record.fields.activity_state.selection) {
this.selection[key] = value;
}
},
/**
* @param {integer} previousActivityTypeID
@@ -118,21 +131,6 @@ const BasicActivity = AbstractField.extend({
this.trigger_up('reload', { keepChanges: true });
}
},
/**
* @private
* @param {integer} id
* @param {function} callback
* @return {Promise}
*/
_openActivityForm(id, callback) {
const action = this._getActivityFormAction(id);
return this.do_action(action, { on_close: callback });
},
//------------------------------------------------------------
// Handlers
//------------------------------------------------------------
/**
* @private
* @param {MouseEvent} ev
@@ -347,6 +345,15 @@ const BasicActivity = AbstractField.extend({
},
});
},
/**
* @private
* @param {MouseEvent} ev
* @returns {Promise}
*/
_onScheduleActivity(ev) {
ev.preventDefault();
return this._openActivityForm(false, this._reload.bind(this));
},
/**
* @private
* @param {MouseEvent} ev
@@ -365,71 +372,19 @@ const BasicActivity = AbstractField.extend({
},
/**
* @private
* @param {MouseEvent} ev
* @returns {Promise}
* @param {integer} id
* @param {function} callback
* @return {Promise}
*/
_onScheduleActivity(ev) {
ev.preventDefault();
return this._openActivityForm(false, this._reload.bind(this));
_openActivityForm(id, callback) {
const action = this._getActivityFormAction(id);
return this.do_action(action, { on_close: callback });
},
/**
* @private
* @param {MouseEvent} ev
* @param {Object} options
* @returns {Promise}
*/
async _onUnlinkActivity(ev, options) {
ev.preventDefault();
const activityID = $(ev.currentTarget).data('activity-id');
options = _.defaults(options || {}, {
model: 'mail.activity',
args: [[activityID]],
});
await this._rpc({
model: options.model,
method: 'unlink',
args: options.args,
});
this._reload.bind({ activity: true });
},
});
// -----------------------------------------------------------------------------
// Activities Widget for Kanban views ('kanban_activity' widget)
// -----------------------------------------------------------------------------
const KanbanActivity = BasicActivity.extend({
template: 'mail.KanbanActivity',
events: _.extend({}, BasicActivity.prototype.events, {
'show.bs.dropdown': '_onDropdownShow',
}),
fieldDependencies: _.extend({}, BasicActivity.prototype.fieldDependencies, {
activity_exception_decoration: { type: 'selection' },
activity_exception_icon: { type: 'char' },
activity_state: { type: 'selection' },
}),
/**
* @override
*/
init(parent, name, record) {
this._super.apply(this, arguments);
const selection = {};
_.each(record.fields.activity_state.selection, function (value) {
selection[value[0]] = value[1];
});
this.selection = selection;
this._setState(record);
},
//------------------------------------------------------------
// Private
//------------------------------------------------------------
/**
* @private
*/
_reload() {
this.trigger_up('reload', { db_id: this.record_id, keepChanges: true });
this.trigger_up('reload', { db_id: this.record.id, keepChanges: true });
},
/**
* @override
@@ -439,7 +394,7 @@ const KanbanActivity = BasicActivity.extend({
// span classes need to be updated manually because the template cannot
// be re-rendered eaasily (because of the dropdown state)
const spanClasses = ['fa', 'fa-lg', 'fa-fw'];
spanClasses.push('o_activity_color_' + (this.activityState || 'default'));
spanClasses.push('o_activity_color_' + (this.record.data.activity_state || 'default'));
if (this.recordData.activity_exception_decoration) {
spanClasses.push('text-' + this.recordData.activity_exception_decoration);
spanClasses.push(this.recordData.activity_exception_icon);
@@ -500,7 +455,6 @@ const KanbanActivity = BasicActivity.extend({
}
const sortedActivities = _.sortBy(activities, 'date_deadline');
this.$('.o_activity').html(QWeb.render('mail.KanbanActivityDropdown', {
selection: this.selection,
records: _.groupBy(sortedActivities, 'state'),
session: session,
widget: this,
@@ -520,23 +474,6 @@ const KanbanActivity = BasicActivity.extend({
}
}
},
/**
* @override
* @private
* @param {Object} record
*/
_reset(record) {
this._super.apply(this, arguments);
this._setState(record);
},
/**
* @private
* @param {Object} record
*/
_setState(record) {
this.record_id = record.id;
this.activityState = this.recordData.activity_state;
},
//------------------------------------------------------------
// Handlers
@@ -31,7 +31,7 @@ class ActivityRecordAdapter extends ComponentAdapter {
}
/**
* Owl Component Adapter for ActivityCell which is BasicActivity (AbstractField)
* Owl Component Adapter for ActivityCell which is KanbanActivity (AbstractField)
* TODO: Remove this adapter when ActivityCell is a Component
*/
class ActivityCellAdapter extends ComponentAdapter {
@@ -79,8 +79,6 @@
li {
.o_activity_title_entry {
display: flex;
align-items: baseline;
max-width: 275px;
.o_activity_summary {
@include o-text-overflow;
@@ -111,11 +109,6 @@
}
}
}
.o_no_activity {
padding: 10px;
cursor: initial;
}
}
}
}
@@ -6,7 +6,7 @@
<!-- Dropdowns are created in JS to avoid some bugs, that's why the <a/> contains no args for the dropdown creation -->
<a class="dropdown-toggle o-no-caret o_activity_btn" data-boundary="viewport" data-flip="false" data-bs-toggle="dropdown" role="button">
<!-- span classes are generated dynamically (see _render) -->
<span t-att-title="widget.selection[widget.activityState]" role="img" t-att-aria-label="widget.selection[widget.activity_state]"/>
<span t-att-title="widget.selection[widget.record.data.activity_state]" role="img" t-att-aria-label="widget.selection[widget.record.data.activity_state]"/>
</a>
<div class="dropdown-menu o_activity" role="menu"/>
</div>
@@ -19,13 +19,13 @@
</t>
<t t-name="mail.KanbanActivityLoading">
<div class="dropdown-item text-center o_no_activity">
<div class="dropdown-item text-center p-3 cursor-default">
<span class="fa fa-circle-o-notch fa-spin fa-2x" role="img" aria-label="Loading..." title="Loading..."/>
</div>
</t>
<t t-name="mail.KanbanActivityDropdown">
<span role="menuitem" t-if="_.isEmpty(records)" class="dropdown-item-text text-center o_no_activity">
<span role="menuitem" t-if="_.isEmpty(records)" class="dropdown-item-text text-center p-3 cursor-default">
<i>Schedule activities to help you get things done.</i>
</span>
<div t-else="" aria-haspopup="true" role="menu" class="o_activity_log_container dropdown-item bg-100 p-0">
@@ -34,8 +34,8 @@
<t t-set="logs" t-value="records[key]" />
<t t-set="contextual_class" t-value="key == 'planned' ? 'success' : (key == 'today' ? 'warning' : 'danger') "/>
<li role="menuitem" t-attf-class="o_activity_label list-group-item list-group-item list-group-item-light d-flex justify-content-between align-items-center o_activity_color_{{key}} {{!key_first ? 'mt-2' : ''}}">
<strong><t t-esc="selection[key]"/></strong>
<li role="menuitem" t-attf-class="list-group-item list-group-item list-group-item-light d-flex justify-content-between align-items-center o_activity_color_{{key}} {{!key_first ? 'mt-2' : ''}}">
<strong><t t-esc="widget.selection[key]"/></strong>
<span t-attf-class="badge rounded-pill bg-{{contextual_class}} border-0 me-0"><t t-esc="logs.length"/></span>
</li>
<t t-foreach="logs" t-as="log">
@@ -62,18 +62,18 @@
<t t-name="mail.activities-list-group-item">
<li t-attf-class="list-group-item o_log_activity d-flex #{log_last ? 'border-bottom' : ''}" role="menuitem">
<div t-attf-class="o_activity_title o_log_activity #{edit_class}" t-att-data-activity-id="log.id">
<div t-attf-class="o_activity_title_entry o_mail_activity {{ log.chaining_type === 'suggest' ? 'align-items-center' : 'mb-1'}}">
<div t-attf-class="o_activity_title_entry o_mail_activity d-flex align-items-baseline {{ log.chaining_type === 'suggest' ? 'align-items-center' : 'mb-1'}}">
<span t-attf-class="fa #{log.icon ? log.icon : 'fa-bell' } fa-fw me-2 text-center text-muted" role="img" aria-label="Log" title="Log"/>
<strong class="text-dark o_activity_summary"><t t-esc="log.title_action or log.summary or log.activity_type_id[1]"/></strong>
<button t-if="log.chaining_type === 'suggest' and log.can_write" class="btn btn-sm btn-link py-0 o_edit_button"><i class="fa fa-pencil"/></button>
</div>
<div class="o_activity_title_entry mt-1" t-if="log.state != 'today'">
<div class="o_activity_title_entry d-flex align-items-baseline mt-1" t-if="log.state != 'today'">
<span class="fa fa-clock-o fa-fw me-2 text-center text-muted" role="img" aria-label="Deadline" title="Deadline"/>
<small t-if="log.user_id[0] !== session.uid and log.mail_template_ids" class="me-1"><t t-esc="log.user_id[1]"/> -</small>
<small t-att-title="log.date_deadline"><t t-esc="log.label_delay" /></small>
</div>
<t t-if="log.mail_template_ids">
<div t-foreach="log.mail_template_ids" t-as="mail_template" class="o_activity_title_entry mt-2" t-att-data-activity-id="log.id" t-att-data-chaining-type-activity="log.chaining_type" t-att-data-previous-activity-type-id="log.activity_type_id[0]">
<div t-foreach="log.mail_template_ids" t-as="mail_template" class="o_activity_title_entry d-flex align-items-baseline mt-2" t-att-data-activity-id="log.id" t-att-data-chaining-type-activity="log.chaining_type" t-att-data-previous-activity-type-id="log.activity_type_id[0]">
<i class="fa fa-envelope-o fa-fw me-2 text-center text-muted" aria-label="Mail" title="Mail" role="img"></i>
<small>
<div class="mb-1" t-esc="mail_template.name + ':'"/>
@@ -89,7 +89,7 @@
<a t-att-data-chaining-type-activity="log.chaining_type"
t-att-data-previous-activity-type-id="log.activity_type_id[0]"
t-att-data-activity-id="log.id"
class="o_mark_as_done_upload_file o_activity_link o_activity_link_kanban fa fa-upload"
class="o_mark_as_done_upload_file o_activity_link_kanban fa fa-upload"
title="Upload file" role="img" t-att-data-fileupload-id="log.fileuploadID"/>
<span class="d-none">
<t t-call="HiddenInputFile">
@@ -105,7 +105,7 @@
t-att-data-previous-activity-type-id="log.activity_type_id[0]"
t-att-data-activity-id="log.id"
t-attf-href="#o_mark_done_form{{log.id}}"
class="o_mark_as_done o_activity_link o_activity_link_kanban fa fa-check-circle"
class="o_mark_as_done o_activity_link_kanban fa fa-check-circle"
data-bs-toggle="collapse" title="Mark as done" role="img" aria-label="Mark as done"/>
</t>
</div>