[IMP] project, portal: group tasks by project on portal.
The portal view for tasks previously listed all task of all projects without grouping them. It was a problem, mainly when we want to make the distinction on project label_tasks, to make the difference between tasks, issues, ... Grouping task by project by default allows to show the label_tasks before each project. Grouping the tasks removes the possibility to define a primary ordering. We want to be able to ungroup the tasks in some cases. The implentation was done in the portalsearch bar adding a group by option. The portal proposes two grouping options, project (by default) and none (to keep strict ordering). Task: #1827950 PR #23769
This commit is contained in:
@@ -195,6 +195,21 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div t-if="searchbar_groupby" class="dropdown pull-right mr4">
|
||||
<button id="portal_searchbar_groupby" class="o_portal_search_panel_fixed_width btn btn-default" type="button" data-toggle="dropdown">
|
||||
<span class="fa fa-bars fa-lg" />
|
||||
<span class='hidden-xs hidden-sm hidden-md' t-esc="searchbar_groupby[groupby].get('label', 'None')"/>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="portal_searchbar_groupby">
|
||||
<li t-foreach="searchbar_groupby" t-as="option" t-att-class="groupby == option and 'active'">
|
||||
<a t-att-href="default_url + '?' + keep_query('*', groupby=option)">
|
||||
<span t-esc="searchbar_groupby[option].get('label')"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template id="portal_contact" name="Contact">
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import OrderedDict
|
||||
from operator import itemgetter
|
||||
|
||||
from odoo import http, _
|
||||
from odoo.http import request
|
||||
from odoo.addons.portal.controllers.portal import get_records_pager, CustomerPortal, pager as portal_pager
|
||||
from odoo.tools import groupby as groupbyelem
|
||||
|
||||
from odoo.osv.expression import OR
|
||||
|
||||
@@ -78,6 +80,7 @@ class CustomerPortal(CustomerPortal):
|
||||
|
||||
@http.route(['/my/tasks', '/my/tasks/page/<int:page>'], type='http', auth="user", website=True)
|
||||
def portal_my_tasks(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None, search_in='content', **kw):
|
||||
groupby = kw.get('groupby', 'project') #TODO master fix this
|
||||
values = self._prepare_portal_layout_values()
|
||||
searchbar_sortings = {
|
||||
'date': {'label': _('Newest'), 'order': 'create_date desc'},
|
||||
@@ -95,6 +98,10 @@ class CustomerPortal(CustomerPortal):
|
||||
'stage': {'input': 'stage', 'label': _('Search in Stages')},
|
||||
'all': {'input': 'all', 'label': _('Search in All')},
|
||||
}
|
||||
searchbar_groupby = {
|
||||
'none': {'input': 'none', 'label': _('None')},
|
||||
'project': {'input': 'project', 'label': _('Project')},
|
||||
}
|
||||
# extends filterby criteria with project (criteria name is the project id)
|
||||
# Note: portal users can't view projects they don't follow
|
||||
projects = request.env['project.project'].sudo().search([('privacy_visibility', '=', 'portal')])
|
||||
@@ -142,22 +149,31 @@ class CustomerPortal(CustomerPortal):
|
||||
step=self._items_per_page
|
||||
)
|
||||
# content according to pager and archive selected
|
||||
if groupby == 'project':
|
||||
order = "project_id, %s" % order # force sort on project first to group by project in view
|
||||
tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
|
||||
request.session['my_tasks_history'] = tasks.ids[:100]
|
||||
if groupby == 'project':
|
||||
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('project_id'))]
|
||||
else:
|
||||
grouped_tasks = [tasks]
|
||||
|
||||
values.update({
|
||||
'date': date_begin,
|
||||
'date_end': date_end,
|
||||
'projects': projects,
|
||||
'tasks': tasks,
|
||||
'tasks': tasks, #TODO master remove this, grouped_tasks is enough
|
||||
'grouped_tasks': grouped_tasks,
|
||||
'page_name': 'task',
|
||||
'archive_groups': archive_groups,
|
||||
'default_url': '/my/tasks',
|
||||
'pager': pager,
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'searchbar_groupby': searchbar_groupby,
|
||||
'searchbar_inputs': searchbar_inputs,
|
||||
'search_in': search_in,
|
||||
'sortby': sortby,
|
||||
'groupby': groupby,
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'filterby': filterby,
|
||||
})
|
||||
|
||||
@@ -130,36 +130,41 @@
|
||||
<h3>Tasks
|
||||
<t t-call="portal.portal_searchbar"/>
|
||||
</h3>
|
||||
<t t-if="not tasks">
|
||||
<t t-if="not grouped_tasks">
|
||||
<div class="alert alert-warning mt8" role="alert">
|
||||
There are no tasks.
|
||||
</div>
|
||||
</t>
|
||||
<div t-if="tasks" class="panel panel-default">
|
||||
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th class="col-md-9">Task</th>
|
||||
<th class="col-md-2">Stage</th>
|
||||
<th>Ref</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="tasks" t-as="task">
|
||||
<tr>
|
||||
<td>
|
||||
<a t-attf-href="/my/task/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="label label-info" title="Current stage of the task" t-esc="task.stage_id.name" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="task.id"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<div t-if="grouped_tasks" class="panel panel-default">
|
||||
<div class="table-responsive">
|
||||
<t t-foreach="grouped_tasks" t-as="tasks">
|
||||
<table class="table table-hover o_portal_my_doc_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th t-if="groupby == 'none'" class="col-md-9">Name</th>
|
||||
<th t-else="" class="col-md-9"><span t-field="tasks[0].project_id.label_tasks"/> for project: <span t-field="tasks[0].project_id.name"/></th>
|
||||
<th class="col-md-2">Stage</th>
|
||||
<th>Ref</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="tasks" t-as="task">
|
||||
<tr>
|
||||
<td>
|
||||
<a t-attf-href="/my/task/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="label label-info" title="Current stage of the task" t-esc="task.stage_id.name" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="task.id"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="pager" class="o_portal_pager text-center">
|
||||
<t t-call="portal.pager"/>
|
||||
|
||||
Reference in New Issue
Block a user