Browse Source

[ADD] (part of) v11 UI

pull/204/head
Holger Brunn 6 years ago
parent
commit
199b3401db
No known key found for this signature in database GPG Key ID: 1C9760FECA3AE18
  1. 3
      mail_activity/__manifest__.py
  2. 64
      mail_activity/static/src/css/mail_activity.css
  3. 171
      mail_activity/static/src/js/mail_activity.js
  4. 80
      mail_activity/static/src/xml/mail_activity.xml
  5. 12
      mail_activity/views/res_partner.xml
  6. 9
      mail_activity/views/templates.xml

3
mail_activity/__manifest__.py

@ -12,12 +12,15 @@
'mail',
],
"data": [
"views/res_partner.xml",
"data/mail_message_subtype.xml",
'security/ir.model.access.csv',
'views/mail_activity.xml',
'data/mail_activity.xml',
'data/ir_model_data.xml',
'views/templates.xml',
],
"qweb": [
'static/src/xml/mail_activity.xml',
],
}

64
mail_activity/static/src/css/mail_activity.css

@ -0,0 +1,64 @@
.o_mail_activity #o_chatter_planned_activities .o_thread_message .o_thread_message_sidebar .o_avatar_stack img {
width: 31px;
height: 31px;
}
#o_chatter_planned_activities .o_thread_message .o_thread_message_sidebar .o_avatar_stack .o_avatar_icon {
position: absolute;
top: auto;
left: auto;
bottom: -5px;
right: -5px;
width: 25px;
height: 25px;
padding: 6px 5px;
text-align: center;
line-height: 1.2;
color: white;
border-radius: 100%;
border: 2px solid white;
}
.o_mail_activity .o_thread_message {
display: -ms-flexbox;
display: -moz-box;
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding: 4px 16px;
margin-bottom: 0px;
}
.o_mail_activity .o_thread_message .o_thread_message_sidebar {
-ms-flex: 0 0 36px;
-moz-flex: 0 0 36px;
-webkit-box-flex: 0;
-webkit-flex: 0 0 36px;
flex: 0 0 36px;
margin-right: 10px;
margin-top: 2px;
text-align: center;
font-size: smaller;
}
.o_mail_activity .o_thread_message .o_thread_message_core {
-ms-flex: 1 1 auto;
-moz-flex: 1 1 auto;
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
min-width: 0;
max-width: 100%;
word-wrap: break-word;
}
.o_mail_activity .o_thread_date_separator.o_border_dashed[data-toggle="collapse"] {
cursor: pointer;
}
.o_mail_activity .o_thread_date_separator.o_border_dashed {
border-bottom-style: dashed;
}
.o_mail_activity .o_thread_date_separator {
margin-top: 15px;
margin-bottom: 30px;
border-bottom: 1px solid #d9d7d7;
text-align: center;
}
.o_mail_activity.o_form_field {
display: block;
}

171
mail_activity/static/src/js/mail_activity.js

@ -1,7 +1,172 @@
//-*- coding: utf-8 -*-
//© 2017 Therp BV <http://therp.nl>
//© 2017-2018 Therp BV <http://therp.nl>
//License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
openerp.mail_activity = function(instance)
odoo.define('mail.Activity', function(require)
{
};
"use strict";
var Chatter = require('mail.Chatter'),
Model = require('web.Model'),
form_common = require('web.form_common'),
core = require('web.core'),
_t = core._t;
Chatter.include({
init: function() {
this._super.apply(this, arguments);
this.schedule_activity_btn = !!this.view.fields.activity_ids
},
start: function() {
this.$('button.o_chatter_button_schedule_activity').click(
this.proxy('_onScheduleActivity')
);
this.activity = this.view.fields.activity_ids;
if(this.activity) {
this.$('.o_chatter_topbar').after(this.activity.$el);
}
return this._super.apply(this, arguments);
},
_onScheduleActivity: function() {
return this.view.fields.activity_ids._scheduleActivity(false);
},
});
/**
* Set the 'label_delay' entry in activity data according to the deadline date
* @param {Array} activities list of activity Object
* @return {Array} : list of modified activity Object
*/
var setDelayLabel = function(activities) {
var today = moment().startOf('day');
_.each(activities, function(activity){
var to_display = '';
var deadline = moment(activity.date_deadline + ' 00:00:00');
var diff = deadline.diff(today, 'days', true); // true means no rounding
if(diff === 0){
to_display = _t('Today');
}else{
if(diff < 0){ // overdue
if(diff === -1){
to_display = _t('Yesterday');
}else{
to_display = _.str.sprintf(_t('%d days overdue'), Math.abs(diff));
}
}else{ // due
if(diff === 1){
to_display = _t('Tomorrow');
}else{
to_display = _.str.sprintf(_t('Due in %d days'), Math.abs(diff));
}
}
}
activity.label_delay = to_display;
});
return activities;
};
var Activity = form_common.AbstractField.extend({
className: 'o_mail_activity',
events: {
'click .o_activity_edit': '_onEditActivity',
'click .o_activity_unlink': '_onUnlinkActivity',
'click .o_activity_done': '_onMarkActivityDone',
},
render_value: function() {
return $.when(
this._super.apply(this, arguments),
this._readActivities(),
).then(this.proxy('_render_value'));
},
_render_value: function() {
var activities = setDelayLabel(this.activities);
if (activities.length) {
var nbActivities = _.countBy(activities, 'state');
this.$el.html(core.qweb.render('mail.activity_items', {
activities: activities,
nbPlannedActivities: nbActivities.planned,
nbTodayActivities: nbActivities.today,
nbOverdueActivities: nbActivities.overdue,
}));
} else {
this.$el.empty();
}
},
_readActivities: function() {
var self = this;
return new Model('mail.activity')
.query([])
.filter([['id', 'in', this.get('value')]])
.all()
.then(function(activities) {
self.activities = activities;
});
},
_scheduleActivity: function (id, previous_activity_type_id, callback) {
var self = this,
action = {
type: 'ir.actions.act_window',
res_model: 'mail.activity',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new',
context: {
default_res_id: this.view.datarecord.id,
default_res_model: this.view.dataset.model,
default_previous_activity_type_id:
previous_activity_type_id || false,
},
res_id: id || false,
};
return this.do_action(action, {
on_close: function() {
if(callback) {
callback();
}
return self.field_manager.reload()
},
})
},
// handlers
_onEditActivity: function (event, options) {
event.preventDefault();
var self = this;
var activity_id = $(event.currentTarget).data('activity-id');
var action = _.defaults(options || {}, {
type: 'ir.actions.act_window',
res_model: 'mail.activity',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new',
context: {
default_res_id: this.view.datarecord.id,
default_res_model: this.view.dataset.model,
},
res_id: activity_id,
});
return this.do_action(action, {
on_close: function () {
self._render_value();
},
});
},
_onUnlinkActivity: function (event, options) {
event.preventDefault();
var activity_id = $(event.currentTarget).data('activity-id');
options = _.defaults(options || {}, {
model: 'mail.activity',
args: [[activity_id]],
});
return new Model('mail.activity')
.call('unlink', [activity_id])
.then(this.render_value.bind(this));
},
_onMarkActivityDone: function (event) {
//TODO: this should open a wizard to write a comment and call action_feedback
},
});
core.form_widget_registry.add('mail_activity', Activity);
return Activity;
});

80
mail_activity/static/src/xml/mail_activity.xml

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="mail.Chatter">
<t t-jquery="button.o_chatter_button_log_note" t-operation="after">
<button t-if="widget.schedule_activity_btn" class="btn btn-sm btn-link o_chatter_button_schedule_activity" title="Log or schedule an activity">
<i class="fa fa-clock-o"/> Schedule activity
</button>
</t>
</t>
<t t-name="mail.activity_items">
<div class="o_thread_date_separator o_border_dashed" data-toggle="collapse" data-target="#o_chatter_planned_activities">
<span class="o_thread_date btn">
<i class="fa fa-fw fa-caret-down"/>
Planned activities
<small class="o_chatter_planned_activities_summary ml8">
<span class="label img-circle label-danger"><t t-esc="nbOverdueActivities"/></span>
<span class="label img-circle label-warning"><t t-esc="nbTodayActivities"/></span>
<span class="label img-circle label-success"><t t-esc="nbPlannedActivities"/></span>
</small>
</span>
</div>
<div id="o_chatter_planned_activities" class="collapse in">
<t t-foreach="activities" t-as="activity">
<div class="o_thread_message" style="margin-bottom: 10px">
<div class="o_thread_message_sidebar">
<div class="o_avatar_stack">
<img t-attf-src="/web/image#{activity.user_id[0] >= 0 ? ('/res.users/' + activity.user_id[0] + '/image_small') : ''}" class="o_thread_message_avatar img-circle mb8" t-att-title="activity.create_uid[1]"/>
<i t-att-class="'o_avatar_icon fa ' + activity.icon + ' bg-' + (activity.state == 'planned'? 'success' : (activity.state == 'today'? 'warning' : 'danger')) + '-full'"
t-att-title="activity.activity_type_id[1]"/>
</div>
</div>
<div class="o_thread_message_core">
<div class="o_mail_info">
<strong><span t-attf-class="o_activity_date o_activity_color_#{activity.state}"><t t-esc="activity.label_delay" /></span></strong>:
<strong t-if="activity.summary"> &#8220;<t t-esc="activity.summary"/>&#8221;</strong>
<strong t-if="!activity.summary"> <t t-esc="activity.activity_type_id[1]" /></strong>
<em> for </em>
<t t-esc="activity.user_id[1]" />
<a class="btn btn-link btn-info text-muted collapsed o_activity_info ml4" role="button" data-toggle="collapse" t-attf-data-target="#o_chatter_activity_info_#{activity.id}">
<i class="fa fa-info-circle"></i>
</a>
<div class="o_thread_message_collapse collapse" t-attf-id="o_chatter_activity_info_#{activity.id}">
<dl class="dl-horizontal well">
<dt>Activity type</dt>
<dd class="mb8">
<t t-esc="activity.activity_type_id[1]"/>
</dd>
<dt>Created on</dt>
<dd class="mb8">
<t t-esc="moment(activity.create_date)"/>
</dd>
<dt>Assigned to</dt>
<dd class="mb8">
<img t-attf-src="/web/image#{activity.user_id[0] >= 0 ? ('/res.users/' + activity.user_id[0] + '/image_small') : ''}" height="18" width="18" class="img-circle mr4" t-att-title="activity.create_uid[1]"/>
<b><t t-esc="activity.user_id[1]"/></b>
<em>, due on </em><span t-attf-class="o_activity_color_#{activity.state}"><t t-esc="moment(activity.date_deadline)"/></span>
</dd>
</dl>
</div>
</div>
<div t-if="activity.note" class="o_thread_message_note small">
<t t-raw="activity.note"/>
</div>
<div class="o_thread_message_tools btn-group">
<a href="#" class="btn btn-link btn-success text-muted btn-sm o_activity_done o_activity_link mr8" t-att-data-activity-id="activity.id" t-att-data-previous-activity-type-id="activity.activity_type_id[0]" data-toggle="popover">
<i class="fa fa-check"/> Mark Done
</a>
<a href="#" class="btn btn-link btn-default text-muted btn-sm o_activity_edit o_activity_link" t-att-data-activity-id="activity.id">
<i class="fa fa-pencil"/> Edit
</a>
<a href="#" class="btn btn-link btn-sm btn-danger text-muted o_activity_unlink o_activity_link" t-att-data-activity-id="activity.id">
<i class="fa fa-times"/> Cancel
</a>
</div>
</div>
</div>
</t>
</div>
</t>
</templates>

12
mail_activity/views/res_partner.xml

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="model">res.partner</field>
<field name="inherit_id" ref="mail.view_emails_partner_info_form" />
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_chatter']/field[@name='message_follower_ids']" position="after">
<field name="activity_ids" widget="mail_activity" />
</xpath>
</field>
</record>
</odoo>

9
mail_activity/views/templates.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="assets_backend" name="mail_activity assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/mail_activity/static/src/js/mail_activity.js"></script>
<link rel="stylesheet" href="/mail_activity/static/src/css/mail_activity.css"/>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save