[IMP] project: Add a group by stage for tasks on the portal
A group by stage on the portal would allow the customer to have an overview of his tasks' progress, which is especially useful in a multi-project setting. - add a "Project" column - rearrange columns in the order: Ref -> Task -> Project -> Stage - add a group by stage for Tasks on the portal - hide "Stage" column when group by stage is selected - hide "Project" column when group by project is selected - add a sort by project for Tasks on the portal - when sort by Stage sub-sort by Project - when sort by Project sub-sort by Stage - add a 'Search in Project' for Tasks on the portal - the "Group By" selector shouldn't change when going to next pages
This commit is contained in:
@@ -99,12 +99,13 @@ class CustomerPortal(CustomerPortal):
|
||||
return self._get_page_view_values(task, access_token, values, 'my_tasks_history', False, **kwargs)
|
||||
|
||||
@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', groupby='project', **kw):
|
||||
def portal_my_tasks(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None, search_in='content', groupby=None, **kw):
|
||||
values = self._prepare_portal_layout_values()
|
||||
searchbar_sortings = {
|
||||
'date': {'label': _('Newest'), 'order': 'create_date desc'},
|
||||
'name': {'label': _('Title'), 'order': 'name'},
|
||||
'stage': {'label': _('Stage'), 'order': 'stage_id'},
|
||||
'stage': {'label': _('Stage'), 'order': 'stage_id, project_id'},
|
||||
'project': {'label': _('Project'), 'order': 'project_id, stage_id'},
|
||||
'update': {'label': _('Last Stage Update'), 'order': 'date_last_stage_update desc'},
|
||||
}
|
||||
searchbar_filters = {
|
||||
@@ -115,11 +116,13 @@ class CustomerPortal(CustomerPortal):
|
||||
'message': {'input': 'message', 'label': _('Search in Messages')},
|
||||
'customer': {'input': 'customer', 'label': _('Search in Customer')},
|
||||
'stage': {'input': 'stage', 'label': _('Search in Stages')},
|
||||
'project': {'input': 'project', 'label': _('Search in Project')},
|
||||
'all': {'input': 'all', 'label': _('Search in All')},
|
||||
}
|
||||
searchbar_groupby = {
|
||||
'none': {'input': 'none', 'label': _('None')},
|
||||
'project': {'input': 'project', 'label': _('Project')},
|
||||
'stage': {'input': 'stage', 'label': _('Stage')},
|
||||
}
|
||||
|
||||
# extends filterby criteria with project the customer has access to
|
||||
@@ -144,11 +147,16 @@ class CustomerPortal(CustomerPortal):
|
||||
if not sortby:
|
||||
sortby = 'date'
|
||||
order = searchbar_sortings[sortby]['order']
|
||||
|
||||
# default filter by value
|
||||
if not filterby:
|
||||
filterby = 'all'
|
||||
domain = searchbar_filters[filterby]['domain']
|
||||
|
||||
# default group by value
|
||||
if not groupby:
|
||||
groupby = 'project'
|
||||
|
||||
# archive groups - Default Group By 'create_date'
|
||||
archive_groups = self._get_archive_groups('project.task', domain)
|
||||
if date_begin and date_end:
|
||||
@@ -165,6 +173,8 @@ class CustomerPortal(CustomerPortal):
|
||||
search_domain = OR([search_domain, [('message_ids.body', 'ilike', search)]])
|
||||
if search_in in ('stage', 'all'):
|
||||
search_domain = OR([search_domain, [('stage_id', 'ilike', search)]])
|
||||
if search_in in ('project', 'all'):
|
||||
search_domain = OR([search_domain, [('project_id', 'ilike', search)]])
|
||||
domain += search_domain
|
||||
|
||||
# task count
|
||||
@@ -172,7 +182,7 @@ class CustomerPortal(CustomerPortal):
|
||||
# pager
|
||||
pager = portal_pager(
|
||||
url="/my/tasks",
|
||||
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'search_in': search_in, 'search': search},
|
||||
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'groupby': groupby, 'search_in': search_in, 'search': search},
|
||||
total=task_count,
|
||||
page=page,
|
||||
step=self._items_per_page
|
||||
@@ -180,10 +190,16 @@ class CustomerPortal(CustomerPortal):
|
||||
# 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=(page - 1) * self._items_per_page)
|
||||
elif groupby == 'stage':
|
||||
order = "stage_id, %s" % order # force sort on stage first to group by stage 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'))]
|
||||
elif groupby == 'stage':
|
||||
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('stage_id'))]
|
||||
else:
|
||||
grouped_tasks = [tasks]
|
||||
|
||||
|
||||
@@ -134,25 +134,32 @@
|
||||
<t t-foreach="grouped_tasks" t-as="tasks">
|
||||
<thead>
|
||||
<tr t-attf-class="{{'thead-light' if not groupby == 'none' else ''}}">
|
||||
<th class="text-left">Ref</th>
|
||||
<th t-if="groupby == 'none'">Name</th>
|
||||
<th t-else="">
|
||||
<th t-if="groupby == 'project'">
|
||||
<em class="font-weight-normal text-muted"><span t-field="tasks[0].sudo().project_id.label_tasks"/> for project:</em>
|
||||
<span t-field="tasks[0].sudo().project_id.name"/></th>
|
||||
<th class="text-center">Stage</th>
|
||||
<th class="text-left">Ref</th>
|
||||
<th t-if="groupby == 'stage'">
|
||||
<em class="font-weight-normal text-muted"><span t-field="tasks[0].sudo().project_id.label_tasks"/> in stage:</em>
|
||||
<span t-field="tasks[0].sudo().stage_id.name"/></th>
|
||||
<th t-if="groupby != 'project'" class="text-center">Project</th>
|
||||
<th t-if="groupby != 'stage'" class="text-center">Stage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="tasks" t-as="task">
|
||||
<tr>
|
||||
<td class="text-left">
|
||||
#<span t-esc="task.id"/>
|
||||
</td>
|
||||
<td>
|
||||
<a t-attf-href="/my/task/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="badge badge-pill badge-info" title="Current stage of the task" t-esc="task.stage_id.name" />
|
||||
<td t-if="groupby != 'project'" class="text-center">
|
||||
<span class="badge badge-pill badge-info" title="Current project of the task" t-esc="task.project_id.name" />
|
||||
</td>
|
||||
<td class="text-left">
|
||||
#<span t-esc="task.id"/>
|
||||
<td t-if="groupby != 'stage'" class="text-center">
|
||||
<span class="badge badge-pill badge-info" title="Current stage of the task" t-esc="task.stage_id.name" />
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user