[ADD] project: tasks & issues need-actions
Shortcuts to display tasks & issues with notifications from the projects dashboards
This commit is contained in:
@@ -111,6 +111,14 @@ class project(osv.osv):
|
||||
for project in self.browse(cr, uid, ids, context=context):
|
||||
res[project.id] = len(project.task_ids)
|
||||
return res
|
||||
|
||||
def _task_needaction_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Task = self.pool['project.task']
|
||||
res = dict.fromkeys(ids, 0)
|
||||
projects = Task.read_group(cr, uid, [('project_id', 'in', ids), ('message_needaction', '=', True)], ['project_id'], ['project_id'], context=context)
|
||||
res.update({project['project_id'][0]: int(project['project_id_count']) for project in projects})
|
||||
return res
|
||||
|
||||
def _get_alias_models(self, cr, uid, context=None):
|
||||
""" Overriden in project_issue to offer more options """
|
||||
return [('project.task', "Tasks")]
|
||||
@@ -162,6 +170,7 @@ class project(osv.osv):
|
||||
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
|
||||
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
|
||||
'task_count': fields.function(_task_count, type='integer', string="Tasks",),
|
||||
'task_needaction_count': fields.function(_task_needaction_count, type='integer', string="Tasks",),
|
||||
'task_ids': fields.one2many('project.task', 'project_id',
|
||||
domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)]),
|
||||
'color': fields.integer('Color Index'),
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<field name="user_id"/>
|
||||
<field name="color"/>
|
||||
<field name="task_count"/>
|
||||
<field name="task_needaction_count"/>
|
||||
<field name="label_tasks"/>
|
||||
<field name="task_ids"/>
|
||||
<field name="alias_id"/>
|
||||
@@ -50,10 +51,15 @@
|
||||
</div>
|
||||
|
||||
<div class="o_project_kanban_boxes">
|
||||
<a t-if="record.use_tasks.raw_value" class="o_project_kanban_box" name="%(act_project_project_2_project_task_all)d" type="action">
|
||||
<span class="o_value"><t t-esc="record.task_count.value"/></span>
|
||||
<span class="o_label"><t t-esc="record.label_tasks.value"/></span>
|
||||
</a>
|
||||
<div t-if="record.use_tasks.raw_value" class="o_project_kanban_box">
|
||||
<a name="%(act_project_project_2_project_task_all)d" type="action">
|
||||
<span class="o_value"><t t-esc="record.task_count.value"/></span>
|
||||
<span class="o_label"><t t-esc="record.label_tasks.value"/></span>
|
||||
</a>
|
||||
<a t-if="record.task_needaction_count.raw_value" class="o_needaction" name="%(act_project_project_2_project_task_all)d" type="action" context="{'search_default_message_needaction': 1}">
|
||||
<t t-esc="record.task_needaction_count.raw_value"/>
|
||||
</a>
|
||||
</div>
|
||||
<a t-if="record.doc_count.raw_value" class="o_project_kanban_box" name="attachment_tree_view" type="object">
|
||||
<span class="o_value"><t t-esc="record.doc_count.value"/></span>
|
||||
<span class="o_label">Documents</span>
|
||||
|
||||
@@ -48,8 +48,24 @@
|
||||
.o_label {
|
||||
color: white;
|
||||
}
|
||||
.o_needaction{
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
color: white;
|
||||
font-size: small;
|
||||
opacity: 0.5;
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
&::before {
|
||||
content: "\f0f3";
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
}
|
||||
}
|
||||
|
||||
.o_project_kanban_box {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 15px 0 15px 0;
|
||||
.o-flex(1, 1, auto);
|
||||
|
||||
@@ -7,12 +7,18 @@
|
||||
<field name="use_tasks" position="after">
|
||||
<field name="use_issues"/>
|
||||
<field name="issue_ids" invisible="1"/>
|
||||
<field name="issue_needaction_count" invisible="1"/>
|
||||
</field>
|
||||
<xpath expr="//div/a[contains(@class, 'o_project_kanban_box')]" position="after">
|
||||
<a t-if="record.use_issues.raw_value" class="o_project_kanban_box" name="%(act_project_project_2_project_issue_all)d" type="action">
|
||||
<span class="o_value"><t t-raw="record.issue_ids.raw_value.length"/></span>
|
||||
<span class="o_label"><field name="label_issues"/></span>
|
||||
</a>
|
||||
<div t-if="record.use_issues.raw_value" class="o_project_kanban_box">
|
||||
<a name="%(act_project_project_2_project_issue_all)d" type="action">
|
||||
<span class="o_value"><t t-raw="record.issue_ids.raw_value.length"/></span>
|
||||
<span class="o_label"><field name="label_issues"/></span>
|
||||
</a>
|
||||
<a t-if="record.issue_needaction_count.raw_value" class="o_needaction" name="%(act_project_project_2_project_issue_all)d" type="action" context="{'search_default_message_needaction': 1}">
|
||||
<t t-esc="record.issue_needaction_count.raw_value"/>
|
||||
</a>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[contains(@class, 'o_kanban_manage_reports')]" position="inside">
|
||||
|
||||
@@ -438,10 +438,18 @@ class project(osv.Model):
|
||||
for project_id in ids
|
||||
}
|
||||
|
||||
def _issue_needaction_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
Issue = self.pool['project.issue']
|
||||
res = dict.fromkeys(ids, 0)
|
||||
projects = Issue.read_group(cr, uid, [('project_id', 'in', ids), ('message_needaction', '=', True)], ['project_id'], ['project_id'], context=context)
|
||||
res.update({project['project_id'][0]: int(project['project_id_count']) for project in projects})
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'issue_count': fields.function(_issue_count, type='integer', string="Issues",),
|
||||
'issue_ids': fields.one2many('project.issue', 'project_id', string="Issues",
|
||||
domain=[('stage_id.fold', '=', False)]),
|
||||
'issue_needaction_count': fields.function(_issue_needaction_count, type='integer', string="Issues",),
|
||||
}
|
||||
|
||||
@api.multi
|
||||
|
||||
Reference in New Issue
Block a user