[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:
laa
2019-11-28 09:54:12 +00:00
parent 98bba5fa0b
commit cbc93d0d11
2 changed files with 34 additions and 11 deletions
+20 -4
View File
@@ -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>