Ivan Yelizariev
10 years ago
commit
507846838f
8 changed files with 605 additions and 0 deletions
-
1__init__.py
-
19__openerp__.py
-
220models.py
-
2security/ir.model.access.csv
-
23static/src/css/main.css
-
115static/src/js/main.js
-
122static/src/xml/main.xml
-
103views.xml
@ -0,0 +1 @@ |
|||
import models |
@ -0,0 +1,19 @@ |
|||
{ |
|||
'name' : 'Extra Widgets for mail wall', |
|||
'version' : '1.0.0', |
|||
'author' : 'Ivan Yelizariev', |
|||
'category' : 'Custom', |
|||
'website' : 'https://it-projects.info', |
|||
'description': """ |
|||
|
|||
Tested on odoo 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d |
|||
""", |
|||
'depends' : ['mail','gamification'], |
|||
'data':[ |
|||
'views.xml', |
|||
#'data.xml', |
|||
'security/ir.model.access.csv', |
|||
], |
|||
'qweb': ['static/src/xml/main.xml'], |
|||
'installable': True, |
|||
} |
@ -0,0 +1,220 @@ |
|||
from openerp.osv import osv,fields as old_fields |
|||
from openerp import api, models, fields, tools |
|||
from openerp.tools.safe_eval import safe_eval |
|||
from openerp.addons.email_template.email_template import mako_template_env |
|||
import copy |
|||
from openerp.tools.translate import _ |
|||
|
|||
class mail_wall_widgets_widget(models.Model): |
|||
_name = 'mail.wall.widgets.widget' |
|||
_order = "sequence, id" |
|||
|
|||
_columns = { |
|||
'name': old_fields.char('Name', required=True, translate=True), |
|||
'type': old_fields.selection(string='Type', selection=[ |
|||
('list', 'List'), |
|||
('funnel', 'Funnel'), |
|||
('slice', 'Slice'), |
|||
#('', ''), |
|||
#('', ''), |
|||
#('', ''), |
|||
#('', ''), |
|||
], help=''' |
|||
Slice - use "domain" for total and "won_domain" for target |
|||
'''), |
|||
|
|||
'description': old_fields.text('Description', translate=True), |
|||
'group_ids': old_fields.many2many('res.groups', relation='mail_wall_widgets_widget_group', column1='widget_id', column2='group_id', string='Groups', help="User groups to show widget"), |
|||
'model_id': old_fields.many2one('ir.model', string='Model', help='The model object for the field to evaluate'), |
|||
'domain': old_fields.char("Filter Domain", help="Domain for filtering records. General rule, not user depending, e.g. [('state', '=', 'done')]. The expression can contain reference to 'user' which is a browse record of the current user if not in batch mode.", required=True), |
|||
'limit': old_fields.integer('Limit', help='Limit count of records to show'), |
|||
'order': old_fields.char('Order', help='Order of records to show'), |
|||
'value_field_id': old_fields.many2one('ir.model.fields', |
|||
string='Value field', |
|||
help='The field containing the value of record'), |
|||
'stage_field_id': old_fields.many2one('ir.model.fields', |
|||
string='Stage field', |
|||
help='Field to split records in funnel. It can be selection type or many2one (the later should have "sequence" field)'), |
|||
#'stage_field_domain': old_fields.many2one('ir.model.fields', |
|||
# string='Stage field domain', |
|||
# help='(for many2one stage_field_id) Domain to find stage objects'), |
|||
'won_domain': old_fields.char('Won domain', |
|||
help='Domain to find won objects'), |
|||
'field_date_id': old_fields.many2one('ir.model.fields', |
|||
string='Date Field', |
|||
help='The date to use for the time period evaluated'), |
|||
'start_date': old_fields.date('Start Date'), |
|||
'end_date': old_fields.date('End Date'), # no start and end = always active |
|||
'content': old_fields.char('Line template', help='Mako template to show content'), |
|||
'value_field_monetary': old_fields.boolean('Value is monetary'), |
|||
'cache': old_fields.boolean('Cache'), |
|||
'active': old_fields.boolean('Active'), |
|||
'sequence': old_fields.integer('Sequence', help='Sequence number for ordering'), |
|||
} |
|||
_defaults = { |
|||
'active': True, |
|||
'cache': False, |
|||
'limit': None, |
|||
'order': None, |
|||
} |
|||
|
|||
@api.one |
|||
def get_data(self, user): |
|||
|
|||
domain = safe_eval(self.domain, {'user': user}) |
|||
won_domain = safe_eval(self.won_domain or '[]', {'user': user}) |
|||
|
|||
field_date_name = self.field_date_id and self.field_date_id.name |
|||
if self.start_date and field_date_name: |
|||
domain.append((field_date_name, '>=', self.start_date)) |
|||
if self.end_date and field_date_name: |
|||
domain.append((field_date_name, '<=', self.end_date)) |
|||
|
|||
res = { |
|||
'name': self.name, |
|||
'type': self.type, |
|||
'model': self.model_id.model, |
|||
'domain': str(domain), |
|||
} |
|||
obj = self.env[self.model_id.model] |
|||
if self.type == 'list': |
|||
res.update({ |
|||
'more': self.limit and self.limit < obj.search_count(domain), |
|||
'lines': [], |
|||
}) |
|||
for r in obj.search(domain, limit=self.limit, order=self.order): |
|||
mako = mako_template_env.from_string(tools.ustr(self.content)) |
|||
content = mako.render({'record':r}) |
|||
r_json = { |
|||
'id': r.id, |
|||
#'fields': dict( (f,getattr(r,f)) for f in fields), |
|||
'display_mode': 'progress', |
|||
'state': 'inprogress', |
|||
'completeness': 0, |
|||
'name': content, |
|||
'description': '', |
|||
} |
|||
if self.value_field_id: |
|||
r_json['current'] = getattr(r, self.value_field_id.name) |
|||
res['lines'].append(r_json) |
|||
elif self.type == 'funnel': |
|||
stage_ids = [] # [key] |
|||
for group in obj.read_group(domain, [], [self.stage_field_id.name]): |
|||
key = group[self.stage_field_id.name] |
|||
if isinstance(key, (list, tuple)): |
|||
key = key[0] |
|||
stage_ids.append(key) |
|||
|
|||
stages = [] # [{'name':Name, 'id': key}] |
|||
if self.stage_field_id.ttype == 'selection': |
|||
d = dict (self.stage_field_id.selection) |
|||
stages = [ {'id':id, 'name':d[id]} for id in stage_ids ] |
|||
else: # many2one |
|||
stage_model = self.stage_field_id.relation |
|||
for r in self.env[stage_model].browse(stage_ids): |
|||
stages.append({'id': r.id, 'name':r.name_get()[0][1]}) |
|||
|
|||
value_field_name = self.value_field_id.name |
|||
for stage in stages: |
|||
d = copy.copy(domain) |
|||
d.append( (self.stage_field_id.name, '=', stage['id']) ) |
|||
result = obj.read_group(d, [value_field_name], []) |
|||
stage['closed_value'] = result and result[0][value_field_name] or 0.0 |
|||
stage['domain'] = str(d) |
|||
|
|||
# won value |
|||
d = domain + won_domain |
|||
result = obj.read_group(domain, [value_field_name], []) |
|||
won = {'name': _('Won'), |
|||
'id':'__won__', |
|||
'closed_value': result and result[0][value_field_name] or 0.0 |
|||
} |
|||
stages.append(won) |
|||
cur = 0 |
|||
for stage in reversed(stages): |
|||
cur += stage['closed_value'] |
|||
stage['abs_value'] = cur |
|||
total_value = stages[0]['abs_value'] |
|||
precision = 0.1 |
|||
for s in stages: |
|||
s['rel_value'] = round(100*s['abs_value']/total_value/precision)*precision if total_value else 100 |
|||
# dummy fields |
|||
s['display_mode'] = 'progress' |
|||
s['monetary'] = 1 |
|||
|
|||
res['stages'] = stages |
|||
res['won'] = won |
|||
res['conversion_rate'] = stages[-1]['rel_value'] |
|||
elif self.type == 'slice': |
|||
value_field_name = self.value_field_id.name |
|||
for f,d in [('total', domain), ('won', won_domain)]: |
|||
result = obj.read_group(d, [value_field_name], []) |
|||
res[f] = result and result[0][value_field_name] or 0.0 |
|||
|
|||
res['domain'] = str(domain) |
|||
res['won_domain'] = str(won_domain) |
|||
|
|||
precision = 10 |
|||
total_value = res['total'] |
|||
res['slice'] = round(100*res['won']/res['total']/precision)*precision if res['total'] else 100 |
|||
# dummy fields |
|||
res['display_mode'] = 'progress' |
|||
res['monetary'] = self.value_field_monetary |
|||
return res |
|||
|
|||
class mail_wall_widgets_cache(models.Model): |
|||
_name = 'mail.wall.widgets.cache' |
|||
|
|||
cache = fields.Text('Cached data') |
|||
res_id = fields.Integer('Resource ID') |
|||
res_model = fields.Integer('Resource Model') |
|||
user_id = fields.Many2one('res.users') |
|||
|
|||
class res_users(models.Model): |
|||
_inherit = 'res.users' |
|||
|
|||
@api.v7 |
|||
def get_serialised_mail_wall_widgets_summary(self, cr, uid, excluded_categories=None, context=None): |
|||
return self._get_serialised_mail_wall_widgets_summary(cr, uid, uid, excluded_categories=excluded_categories, context=context)[0] |
|||
|
|||
@api.one |
|||
def _get_serialised_mail_wall_widgets_summary(self, excluded_categories=None): |
|||
""" |
|||
[ |
|||
{ |
|||
'id': ..., |
|||
'model': ..., |
|||
'currency': <res.currency id>, |
|||
'data': (depend on model) |
|||
}, |
|||
] |
|||
""" |
|||
user = self.env.user |
|||
res = [] |
|||
model = 'mail.wall.widgets.widget' |
|||
domain = [('group_ids', 'in', user.groups_id.ids), ('active', '=', True)] |
|||
for widget in self.env[model].search(domain, order='sequence'): |
|||
if widget.cache: |
|||
#TODO |
|||
continue |
|||
res.append({ |
|||
'model': model, |
|||
'id': widget.id, |
|||
'currency': user.company_id.currency_id.id, |
|||
'data': widget.get_data(user)[0], |
|||
}) |
|||
return res |
|||
|
|||
#def get_challenge_suggestions(self, cr, uid, context=None): |
|||
# """Return the list of challenges suggested to the user""" |
|||
# challenge_info = [] |
|||
# challenge_obj = self.pool.get('mail_wall_widgets.challenge') |
|||
# challenge_ids = challenge_obj.search(cr, uid, [('invited_user_ids', 'in', uid), ('state', '=', 'inprogress')], context=context) |
|||
# for challenge in challenge_obj.browse(cr, uid, challenge_ids, context=context): |
|||
# values = { |
|||
# 'id': challenge.id, |
|||
# 'name': challenge.name, |
|||
# 'description': challenge.description, |
|||
# } |
|||
# challenge_info.append(values) |
|||
# return challenge_info |
@ -0,0 +1,2 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_mail_wall_widgets,mail.wall.widgets.widget,model_mail_wall_widgets_widget,,1,1,1,1 |
@ -0,0 +1,23 @@ |
|||
.openerp .oe_mail_wall .oe_mail_wall_aside .oe_mail_wall_widgets{ |
|||
background-color: #ededf6; |
|||
} |
|||
.oe_open_record:hover, .oe_open_record_list:hover{ |
|||
cursor:pointer; |
|||
} |
|||
.oe_goal_outer_box .more{ |
|||
text-align:center; |
|||
} |
|||
|
|||
.openerp .oe_mail_wall .oe_goal .oe_goals_list.funnel .oe_cell.oe_goal_current { |
|||
font-size: 150%; |
|||
font-weight: bold; |
|||
min-width: 65px; |
|||
padding: 0 5px; |
|||
} |
|||
.openerp .oe_mail_wall .oe_goal .oe_goals_list .oe_cell.oe_goal_current span.small { |
|||
font-weight: normal; |
|||
font-size: 70%; |
|||
} |
|||
.oe_open_record:hover, .oe_open_record_list_funnel:hover{ |
|||
cursor:pointer; |
|||
} |
@ -0,0 +1,115 @@ |
|||
openerp.mail_wall_widgets = function(instance) { |
|||
var QWeb = instance.web.qweb; |
|||
var _t = instance.web._t; |
|||
|
|||
instance.mail_wall_widgets.Sidebar = instance.web.Widget.extend({ |
|||
template: 'mail_wall_widgets.UserWallSidebar', |
|||
init: function (parent, action) { |
|||
var self = this; |
|||
this._super(parent, action); |
|||
this.deferred = $.Deferred(); |
|||
//$(document).off('keydown.klistener');
|
|||
this.widget_templates = { |
|||
'mail.wall.widgets.widget': "mail_wall_widgets.Widget" |
|||
} |
|||
}, |
|||
events: { |
|||
'click .oe_open_record': function(event){ |
|||
var $t = $(event.currentTarget); |
|||
this.do_action({ |
|||
'name': _t('Details'), |
|||
'type': 'ir.actions.act_window', |
|||
'res_model': $t.parent().attr('data-model'), |
|||
'res_id': parseInt($t.attr('data-id')), |
|||
'target': 'current', |
|||
'views': [[false, 'form'],[false, 'list']], |
|||
'domain': $t.parent().attr('data-domain'), |
|||
}) |
|||
}, |
|||
'click .oe_open_record_list': function(event){ |
|||
var $t = $(event.currentTarget); |
|||
this.do_action({ |
|||
'name': _t('More...'), |
|||
'type': 'ir.actions.act_window', |
|||
'res_model': $t.parent().attr('data-model'), |
|||
'target': 'current', |
|||
'views': [[false, 'list'],[false, 'form']], |
|||
'domain': $t.parent().attr('data-domain'), |
|||
}) |
|||
}, |
|||
'click .oe_open_record_list_funnel': function(event){ |
|||
var $t = $(event.currentTarget); |
|||
this.do_action({ |
|||
'name': _t('More...'), |
|||
'type': 'ir.actions.act_window', |
|||
'res_model': $t.parent().attr('data-model'), |
|||
'target': 'current', |
|||
'views': [[false, 'list'],[false, 'form']], |
|||
'domain': $t.attr('data-domain'), |
|||
}) |
|||
}, |
|||
}, |
|||
start: function() { |
|||
var self = this; |
|||
this._super.apply(this, arguments); |
|||
self.get_widgets_info(); |
|||
}, |
|||
get_widgets_info: function() { |
|||
var self = this; |
|||
new instance.web.Model('res.users').call('get_serialised_mail_wall_widgets_summary', []).then(function(result) { |
|||
if (result.length === 0) { |
|||
self.$el.find(".oe_mail_wall_widgets").hide(); |
|||
} else { |
|||
self.$el.find(".oe_mail_wall_widgets").empty(); |
|||
_.each(result, function(item){ |
|||
var $item = $(QWeb.render(self.widget_templates[item.model], {info: item})); |
|||
self.render_money_fields($item); |
|||
//self.render_user_avatars($item);
|
|||
self.$el.find('.oe_mail_wall_widgets').append($item); |
|||
}); |
|||
} |
|||
}); |
|||
}, |
|||
render_money_fields: function(item) { |
|||
var self = this; |
|||
self.dfm = new instance.web.form.DefaultFieldManager(self); |
|||
// Generate a FieldMonetary for each .oe_goal_field_monetary
|
|||
item.find(".oe_goal_field_monetary").each(function() { |
|||
var currency_id = parseInt( $(this).attr('data-id'), 10); |
|||
money_field = new instance.web.form.FieldMonetary(self.dfm, { |
|||
attrs: { |
|||
modifiers: '{"readonly": true}' |
|||
} |
|||
}); |
|||
money_field.set('currency', currency_id); |
|||
money_field.get_currency_info(); |
|||
money_field.set('value', parseInt($(this).text(), 10)); |
|||
money_field.replace($(this)); |
|||
}); |
|||
}, |
|||
render_user_avatars: function(item) { |
|||
var self = this; |
|||
item.find(".oe_user_avatar").each(function() { |
|||
var user_id = parseInt( $(this).attr('data-id'), 10); |
|||
var url = instance.session.url('/web/binary/image', {model: 'res.users', field: 'image_small', id: user_id}); |
|||
$(this).attr("src", url); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
instance.web.WebClient.include({ |
|||
to_kitten: function() { |
|||
this._super(); |
|||
new instance.web.Model('mail_wall_widgets.badge').call('check_progress', []); |
|||
} |
|||
}); |
|||
|
|||
instance.mail.Wall.include({ |
|||
start: function() { |
|||
this._super(); |
|||
var sidebar = new instance.mail_wall_widgets.Sidebar(this); |
|||
sidebar.appendTo($('.oe_mail_wall_aside')); |
|||
}, |
|||
}); |
|||
|
|||
}; |
@ -0,0 +1,122 @@ |
|||
<templates> |
|||
<t t-name="mail_wall_widgets.UserWallSidebar" class="oe_mail_wall_widgets_user_wall_sidebar"> |
|||
<div> |
|||
<div class="oe_mail_wall_widgets"></div> |
|||
</div> |
|||
</t> |
|||
<t t-name="mail_wall_widgets.Widget"> |
|||
<div class="oe_goal"> |
|||
<div> |
|||
<a class="oe_update_challenge oe_e" rol="button" t-attf-id="{info.id}" t-attf-model="{info.model}">e</a> |
|||
<h4><t t-esc="info.data.name" /></h4> |
|||
</div> |
|||
|
|||
<t t-if="info.model=='mail.wall.widgets.widget' and info.data.type == 'list'"> |
|||
<div class="oe_table oe_goals_list" t-att-data-model="info.data.model" t-att-data-domain="info.data.domain"> |
|||
<div t-foreach="info.data.lines" t-as="line" t-attf-class="oe_row oe_goal_outer_box oe_open_record record #{line.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}" t-att-data-id="line.id" > |
|||
<t t-if="line.display_mode == 'progress'"> |
|||
<div class="oe_goal_progress_background"></div> |
|||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+line.completeness+'%;' : 'width:0;'}"></div> |
|||
<div class="oe_cell oe_goal_current"><t t-esc="line.current" /></div> |
|||
</t> |
|||
<div class="oe_cell"> |
|||
<span t-att-title="line.description"><t t-raw="line.name" /></span> |
|||
</div> |
|||
</div> |
|||
<div t-if="info.data.more" class="oe_row oe_goal_outer_box oe_open_record_list"> |
|||
<div class="oe_goal_progress_background"></div> |
|||
<div class="more"> |
|||
More... |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
<t t-if="info.model=='mail.wall.widgets.widget' and info.data.type == 'funnel'"> |
|||
<div class="oe_table oe_goals_list funnel" t-att-data-model="info.data.model" t-att-data-domain="info.data.domain"> |
|||
<div t-foreach="info.data.stages" t-as="line" t-attf-class="oe_row oe_goal_outer_box oe_open_record_list_funnel record #{line.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}" t-att-data-id="line.id" t-att-data-domain="line.domain" > |
|||
<t t-if="line.display_mode == 'progress'"> |
|||
<div class="oe_goal_progress_background"></div> |
|||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+line.rel_value+'%;' : 'width:0;'}"></div> |
|||
<div class="oe_cell oe_goal_current"><t t-esc="line.rel_value" /><span class="small">%</span></div> |
|||
</t> |
|||
<div class="oe_cell"> |
|||
<span t-att-title="line.description"><b><t t-raw="line.name" /></b></span> - <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? info.currency : ''}"><t t-esc="line.abs_value" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
<t t-if="info.model=='mail.wall.widgets.widget' and info.data.type == 'slice'"> |
|||
<div class="oe_table oe_goals_list funnel" t-att-data-model="info.data.model" t-att-data-domain="info.data.domain"> |
|||
<t t-set="line" t-value="info.data"/> |
|||
<div t-attf-class="oe_row oe_goal_outer_box oe_open_record_list record #{line.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}" t-att-data-id="line.id" t-att-data-domain="line.won_domain" > |
|||
<t t-if="line.display_mode == 'progress'"> |
|||
<div class="oe_goal_progress_background"></div> |
|||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+line.slice+'%;' : 'width:0;'}"></div> |
|||
<div class="oe_cell oe_goal_current"><t t-esc="line.slice" /><span class="small">%</span></div> |
|||
</t> |
|||
<div class="oe_cell"> |
|||
<span t-att-title="line.description"><b><span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? info.currency : ''}"><t t-esc="line.won" /></span></b></span> from <span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? info.currency : ''}"><t t-esc="line.total" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
|
|||
<t t-if="0 and challenge.visibility_mode == 'ranking'"> |
|||
<div t-foreach="challenge.lines" t-as="line" class="oe_goals_list oe_table"> |
|||
<div class="oe_row"> |
|||
<div class="oe_cell oe_thead" colspan="3" t-attf-title="#{line.description ? line.description : ''}"> |
|||
<strong><t t-esc="line.name"/></strong> |
|||
<br/> |
|||
<div class="oe_grey"> |
|||
<t t-if="line.definition_condition == 'higher'"> |
|||
Target: |
|||
</t> |
|||
<t t-if="line.definition_condition == 'lower'"> |
|||
Target: <= |
|||
</t> |
|||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="line.target" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div t-foreach="line.goals" t-as="goal" t-attf-class="#{goal.id == line.own_goal_id ? 'oe_bold' : ''}"> |
|||
<div t-attf-class="oe_row oe_goal_outer_box #{goal.state == 'reached' ? 'oe_goal_reached' : ''} #{line.display_mode != 'progress' ? 'oe_no_progress' : ''}"> |
|||
<t t-if="line.display_mode == 'progress'"> |
|||
<div class="oe_goal_progress_background"></div> |
|||
<div class="oe_goal_progress" t-attf-style="#{line.display_mode == 'progress' ? 'width: '+goal.completeness+'%;' : 'width:0;'}"></div> |
|||
</t> |
|||
|
|||
<div class="oe_cell col0"><t t-esc="goal.rank" /></div> |
|||
<div class="oe_cell col1"><img class="oe_user_avatar" t-attf-alt="#{goal.name}" t-attf-data-id="#{goal.user_id}"/></div> |
|||
<div class="oe_cell col2"> |
|||
<t t-if="line.display_mode == 'progress'"> |
|||
<!-- progress, action on current value --> |
|||
<t t-esc="goal.name"/><br/> |
|||
<t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)"> |
|||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> |
|||
</t> |
|||
<t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')"> |
|||
<a class="oe_goal_action" t-att-id="line.own_goal_id"> |
|||
<span t-attf-class="#{line.monetary ? 'oe_goal_field_monetary' : ''}" t-attf-data-id="#{line.monetary ? challenge.currency : ''}"><t t-esc="goal.current" /></span><t t-if="line.suffix"> <t t-esc="line.suffix"/></t> |
|||
</a> |
|||
</t> |
|||
</t> |
|||
<t t-if="line.display_mode != 'progress'"> |
|||
<!-- not progress, action on user name --> |
|||
<t t-if="goal.id != line.own_goal_id or (line.computation_mode != 'manually' and !line.action)"> |
|||
<t t-esc="goal.name"/> |
|||
</t> |
|||
<t t-if="goal.id == line.own_goal_id and (line.action or line.computation_mode == 'manually')"> |
|||
<a class="oe_goal_action" t-att-id="line.own_goal_id"><t t-esc="goal.name"/></a> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
|
|||
</templates> |
@ -0,0 +1,103 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend" name="assets" inherit_id="web.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/mail_wall_widgets/static/src/css/main.css"/> |
|||
<script type="text/javascript" src="/mail_wall_widgets/static/src/js/main.js"></script> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<!-- Widget --> |
|||
<record id="mail_wall_widgets_widget_action" model="ir.actions.act_window"> |
|||
<field name="name">Widgets</field> |
|||
<field name="res_model">mail.wall.widgets.widget</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create"> |
|||
Click to create a Widget. |
|||
</p> |
|||
<p> |
|||
Widget allows to show some information at the inbox |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="mail_wall_widgets_list_view" model="ir.ui.view"> |
|||
<field name="name">Widget list view</field> |
|||
<field name="model">mail.wall.widgets.widget</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Widgets"> |
|||
<field name="name"/> |
|||
<field name="sequence"/> |
|||
<field name="domain"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
|
|||
<record id="mail_wall_widgets_form_view" model="ir.ui.view"> |
|||
<field name="name">Widget form view</field> |
|||
<field name="model">mail.wall.widgets.widget</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Widget"> |
|||
<sheet> |
|||
<label for="name" class="oe_edit_only"/> |
|||
<h1> |
|||
<field name="name" class="oe_inline"/> |
|||
</h1> |
|||
|
|||
<field name="type" class="oe_inline"/> |
|||
<label for="description" class="oe_edit_only"/> |
|||
<div> |
|||
<field name="description" class="oe_inline"/> |
|||
</div> |
|||
|
|||
<group string="How to select records?"> |
|||
|
|||
<field name="model_id" class="oe_inline"/> |
|||
<field name="domain" /> |
|||
<field name="won_domain" attrs="{'invisible':[('type', 'not in', ['funnel','slice'])]}" /> |
|||
<field name="field_date_id"/> |
|||
<field name="start_date"/> |
|||
<field name="end_date"/> |
|||
</group> |
|||
<group string="How to select users?"> |
|||
<field name="group_ids" class="oe_inline" widget="many2many_tags"/> |
|||
</group> |
|||
<group string="How show data?"> |
|||
<field name="stage_field_id" attrs="{'invisible':[('type', 'not in', ['funnel'])]}"/> |
|||
<field name="value_field_id" class="oe_inline"/> |
|||
<field name="value_field_monetary" class="oe_inline"/> |
|||
<field name="content" attrs="{'invisible':[('type', 'not in', ['list'])]}"/> |
|||
<field name="limit" attrs="{'invisible':[('type', 'not in', ['list'])]}" class="oe_inline"/> |
|||
<field name="order" attrs="{'invisible':[('type', 'not in', ['list'])]}" class="oe_inline"/> |
|||
</group> |
|||
<group string="Other"> |
|||
<field name="sequence" class="oe_inline"/> |
|||
<field name="active"/> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="mail_wall_widgets_search_view" model="ir.ui.view"> |
|||
<field name="name">Widget Search</field> |
|||
<field name="model">mail.wall.widgets.widget</field> |
|||
<field name="arch" type="xml"> |
|||
<search string="Search Widget"> |
|||
<field name="name"/> |
|||
<field name="model_id"/> |
|||
<group expand="0" string="Group By"> |
|||
<filter string="Model" domain="[]" context="{'group_by':'model_id'}"/> |
|||
</group> |
|||
</search> |
|||
</field> |
|||
</record> |
|||
|
|||
<!-- menus in settings - technical feature required --> |
|||
<menuitem id="mail_wall_widgets_widget_menu" parent="gamification.gamification_menu" action="mail_wall_widgets_widget_action" sequence="50"/> |
|||
|
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue