Assign KBItems to teams

This allows you to only show on the dashboard those tickets which belong to a
given user's team.
This commit is contained in:
Timothy Hobbs 2020-01-27 19:45:15 +01:00
parent eea76a5eb7
commit 5b0d44ec3a
7 changed files with 81 additions and 5 deletions

View File

@ -1343,6 +1343,9 @@ class KBItem(models.Model):
def num_open_tickets(self):
return Ticket.objects.filter(kbitem=self, status__in=(1, 2)).count()
def unassigned_tickets(self):
return Ticket.objects.filter(kbitem=self, status__in=(1, 2), assigned_to__isnull=True)
def get_markdown(self):
return get_markdown(self.answer)

View File

@ -1,6 +1,5 @@
{% load i18n humanize %}
<!-- DataTables Example -->
<div class="card mb-3">
<div class="card-header">
<i class="fas fa-table"></i>
@ -40,3 +39,43 @@
<div class="card-footer small text-muted">Listing {{ unassigned_tickets|length }} ticket(s).</div>
</div>
{% for kbitem in kbitems %}
<div class="card mb-3">
<div class="card-header">
<i class="fas fa-table"></i>
{% trans "KBItem:" %} {{kbitem.title}} {% trans "Team:" %} {{kbitem.team.name}} {% trans "(pick up a ticket if you start to work on it)" %}
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-sm table-striped" id="dataTable" width="100%" cellspacing="0">
<thead class="thead-light">
<tr>
<th>{% trans "Ticket" %}</th>
<th>{% trans "Prority" %}</th>
<th>{% trans "Queue" %}</th>
<th>{% trans "Created" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for ticket in kbitem.unassigned_tickets %}
<tr class="{{ ticket.get_priority_css_class }}">
<td class="tickettitle"><a href='{{ ticket.get_absolute_url }}'>{{ ticket.id }}. {{ ticket.title }} </a></td>
<td>{{ ticket.priority }}</td>
<td>{{ ticket.queue }}</td>
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|naturaltime }}</span></td>
<td class="text-center">
<a href='{{ ticket.get_absolute_url }}?take'><button class='btn btn-primary btn-sm'><i class="fas fa-hand-paper"></i>&nbsp;{% trans "Take" %}</button></a>
<a href='{% url 'helpdesk:delete' ticket.id %}'><button class='btn btn-danger btn-sm'><i class="fas fa-trash"></i>&nbsp;{% trans "Delete" %}</button></a>
</td>
</tr>
{% empty %}
<tr><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="card-footer small text-muted">Listing {{ kbitem.unassigned_tickets|length }} ticket(s).</div>
</div>
{% endfor %}

View File

@ -96,6 +96,10 @@
<option value='unassign'>{% trans "Nobody (Unassign)" %}</option>
{% for u in user_choices %}<option value='assign_{{ u.id }}'>{{ u.get_username }}</option>{% endfor %}
</optgroup>
<optgroup label='{% trans "Set KB Item" %}'>
<option value='kbitem_none'>{% trans "No KB Item" %}</option>
{% for kbi in kb_items %}<option value='kbitem_{{ kbi.id }}'>{{ kbi.title }}</option>{% endfor %}
</optgroup>
</select>
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-arrow-circle-right"></i>&nbsp;{% trans "Go" %}</button>
</p>

View File

@ -2,6 +2,7 @@ from helpdesk.models import (
Ticket,
Queue,
KBCategory,
KBItem,
)
from helpdesk import settings as helpdesk_settings
@ -35,13 +36,20 @@ class HelpdeskUser:
else:
return all_queues
def get_kb_categories(self):
def get_allowed_kb_categories(self):
categories = []
for cat in KBCategory.objects.all():
if self.can_access_kbcategory(cat):
categories.append(cat)
return categories
def get_assigned_kb_items(self):
kbitems = []
for item in KBItem.objects.all():
if item.team and item.team.is_member(self.user):
kbitems.append(item)
return kbitems
def get_tickets_in_queues(self):
return Ticket.objects.filter(queue__in=self.get_queues())

View File

@ -21,7 +21,7 @@ def index(request):
huser = user.huser_from_request(request)
# TODO: It'd be great to have a list of most popular items here.
return render(request, 'helpdesk/kb_index.html', {
'kb_categories': huser.get_kb_categories(),
'kb_categories': huser.get_allowed_kb_categories(),
'helpdesk_settings': helpdesk_settings,
})

View File

@ -130,7 +130,7 @@ class Homepage(CreateTicketView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['kb_categories'] = huser_from_request(self.request).get_kb_categories()
context['kb_categories'] = huser_from_request(self.request).get_allowed_kb_categories()
return context

View File

@ -103,6 +103,7 @@ def dashboard(request):
showing ticket counts by queue/status, and a list of unassigned tickets
with options for them to 'Take' ownership of said tickets.
"""
huser = HelpdeskUser(request.user)
active_tickets = Ticket.objects.select_related('queue').exclude(
status__in=[Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS],
)
@ -117,13 +118,16 @@ def dashboard(request):
assigned_to=request.user,
status__in=[Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS])
user_queues = HelpdeskUser(request.user).get_queues()
user_queues = huser.get_queues()
unassigned_tickets = active_tickets.filter(
assigned_to__isnull=True,
kbitem__isnull=True,
queue__in=user_queues
)
kbitems = huser.get_assigned_kb_items()
# all tickets, reported by current user
all_tickets_reported_by_current_user = ''
email_current_user = request.user.email
@ -157,6 +161,7 @@ def dashboard(request):
'user_tickets': tickets,
'user_tickets_closed_resolved': tickets_closed_resolved,
'unassigned_tickets': unassigned_tickets,
'kbitems': kbitems,
'all_tickets_reported_by_current_user': all_tickets_reported_by_current_user,
'basic_ticket_stats': basic_ticket_stats,
})
@ -706,6 +711,13 @@ def mass_update(request):
parts = action.split('_')
user = User.objects.get(id=parts[1])
action = 'assign'
if action == 'kbitem_none':
kbitem = None
action = 'set_kbitem'
if action.startswith('kbitem_'):
parts = action.split('_')
kbitem = KBItem.objects.get(id=parts[1])
action = 'set_kbitem'
elif action == 'take':
user = request.user
action = 'assign'
@ -735,6 +747,15 @@ def mass_update(request):
public=True,
user=request.user)
f.save()
elif action == 'set_kbitem':
t.kbitem = kbitem
t.save()
f = FollowUp(ticket=t,
date=timezone.now(),
title=_('KBItem set in bulk update'),
public=False,
user=request.user)
f.save()
elif action == 'close' and t.status != Ticket.CLOSED_STATUS:
t.status = Ticket.CLOSED_STATUS
t.save()
@ -917,6 +938,7 @@ def ticket_list(request):
context,
default_tickets_per_page=request.user.usersettings_helpdesk.tickets_per_page,
user_choices=User.objects.filter(is_active=True, is_staff=True),
kb_items=KBItem.objects.all(),
queue_choices=huser.get_queues(),
status_choices=Ticket.STATUS_CHOICES,
kbitem_choices=kbitem_choices,