From 7fe6444f8fc6c0e48f6ca777b35f048d8a32d789 Mon Sep 17 00:00:00 2001 From: Timothy Hobbs Date: Tue, 7 Jan 2020 13:33:06 +0100 Subject: [PATCH] Redo KB categories as accordion view --- helpdesk/forms.py | 19 ++++++-- helpdesk/models.py | 10 +++- helpdesk/templates/helpdesk/kb_category.html | 44 ++++++++++------- helpdesk/templates/helpdesk/kb_item.html | 51 -------------------- helpdesk/urls.py | 4 -- helpdesk/views/kb.py | 15 +++--- helpdesk/views/public.py | 10 +++- 7 files changed, 65 insertions(+), 88 deletions(-) delete mode 100644 helpdesk/templates/helpdesk/kb_item.html diff --git a/helpdesk/forms.py b/helpdesk/forms.py index a635a75b..ff76d435 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -18,7 +18,7 @@ from django.utils import timezone from helpdesk.lib import safe_template_context, process_attachments from helpdesk.models import (Ticket, Queue, FollowUp, IgnoreEmail, TicketCC, - CustomField, TicketCustomFieldValue, TicketDependency, UserSettings) + CustomField, TicketCustomFieldValue, TicketDependency, UserSettings, KBItem) from helpdesk import settings as helpdesk_settings User = get_user_model() @@ -197,7 +197,10 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form): return Queue.objects.get(id=int(self.cleaned_data['queue'])) def _create_ticket(self): - queue = self._get_queue() + queue = Queue.objects.get(id=int(self.cleaned_data['queue'])) + kbitem = None + if 'kbitem' in self.cleaned_data: + kbitem = KBItem.objects.get(id=int(self.cleaned_data['kbitem'])) ticket = Ticket(title=self.cleaned_data['title'], submitter_email=self.cleaned_data['submitter_email'], @@ -207,6 +210,7 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form): description=self.cleaned_data['body'], priority=self.cleaned_data['priority'], due_date=self.cleaned_data['due_date'], + kbitem=kbitem, ) return ticket, queue @@ -337,13 +341,22 @@ class PublicTicketForm(AbstractTicketForm): help_text=_('We will e-mail you when your ticket is updated.'), ) - def __init__(self, hidden_fields=(), readonly_fields=(), *args, **kwargs): + def __init__(self, hidden_fields=(), readonly_fields=(), kbcategory=None, *args, **kwargs): """ Add any (non-staff) custom fields that are defined to the form """ super(PublicTicketForm, self).__init__(*args, **kwargs) self._add_form_custom_fields(False) + if kbcategory: + self.fields['kbitem'] = forms.ChoiceField( + widget=forms.Select(attrs={'class': 'form-control'}), + required=False, + label=_('Knowedge Base Item'), + choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk)], + ) + + field_hide_table = { 'queue': 'HELPDESK_PUBLIC_TICKET_QUEUE', 'priority': 'HELPDESK_PUBLIC_TICKET_PRIORITY', diff --git a/helpdesk/models.py b/helpdesk/models.py index 8a200e27..09d2436b 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -559,6 +559,14 @@ class Ticket(models.Model): default=mk_secret, ) + kbitem = models.ForeignKey( + "KBItem", + blank=True, + null=True, + on_delete=models.CASCADE, + verbose_name=_('Knowledge base item the user was viewing when they created this ticket.'), + ) + @property def time_spent(self): """Return back total time spent on the ticket. This is calculated value @@ -1310,7 +1318,7 @@ class KBItem(models.Model): def get_absolute_url(self): from django.urls import reverse - return reverse('helpdesk:kb_item', args=(self.id,)) + return str(reverse('helpdesk:kb_category', args=(self.category.slug,)))+"?kbitem="+str(self.pk) def get_markdown(self): return get_markdown(self.answer) diff --git a/helpdesk/templates/helpdesk/kb_category.html b/helpdesk/templates/helpdesk/kb_category.html index f7a6a3e1..953fe183 100644 --- a/helpdesk/templates/helpdesk/kb_category.html +++ b/helpdesk/templates/helpdesk/kb_category.html @@ -19,29 +19,37 @@

{{ category.description }}

- +
{% for item in items %} -{% cycle 'one' 'two' 'three' as itemnumperrow silent %} -{% ifequal itemnumperrow 'one' %}
{% endifequal %} -
-
-
{{ item.title }}
-
-
-

{{ item.question }}

-

- {% blocktrans with item.get_absolute_url as url %} Go to answer {% endblocktrans %} -

-
-

{% trans 'Rating' %}: {{ item.score }}

-

{% trans 'Last Update' %}: {{ item.last_updated|naturaltime }}

+
+ +
+
+

{{ item.question }}

+

{{ item.get_markdown }}

+
+ {% if request.user.pk %} +
+ +
+
+ +
+ {% blocktrans with recommendations=item.recommendations votes=item.votes %}{{ recommendations }} people found this answer useful of {{votes}}. {% endblocktrans %} + {% endif %}
-

+ +
-{% ifequal itemnumperrow 'three' %}
{% endifequal %} {% endfor %} -{% ifnotequal itemnumperrow 'three' %}
{% endifnotequal %} +
{% if category.queue %} {% endif %} diff --git a/helpdesk/templates/helpdesk/kb_item.html b/helpdesk/templates/helpdesk/kb_item.html deleted file mode 100644 index c75c0777..00000000 --- a/helpdesk/templates/helpdesk/kb_item.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "helpdesk/public_base.html" %}{% load i18n %} - -{% block helpdesk_breadcrumb %} - - - -{% endblock %} - -{% block helpdesk_body %} -

{% trans 'Knowledgebase' %}: {% blocktrans with item.title as item %}{{ item }}{% endblocktrans %}

- -
-
- - {{ item.question }} -
-
-

{{ item.get_markdown }}

-
- -
- -

{% blocktrans with item.category.title as category_title and item.category.get_absolute_url as category_url %}View other {{ category_title }} articles, or continue viewing other knowledgebase articles.{% endblocktrans %}

- -{% endblock %} diff --git a/helpdesk/urls.py b/helpdesk/urls.py index c0d3223f..e183efe1 100644 --- a/helpdesk/urls.py +++ b/helpdesk/urls.py @@ -232,10 +232,6 @@ if helpdesk_settings.HELPDESK_KB_ENABLED: kb.index, name='kb_index'), - url(r'^kb/(?P[0-9]+)/$', - kb.item, - name='kb_item'), - url(r'^kb/(?P[0-9]+)/vote/$', kb.vote, name='kb_vote'), diff --git a/helpdesk/views/kb.py b/helpdesk/views/kb.py index b095ae3f..78666767 100644 --- a/helpdesk/views/kb.py +++ b/helpdesk/views/kb.py @@ -27,18 +27,15 @@ def index(request): def category(request, slug): category = get_object_or_404(KBCategory, slug__iexact=slug) items = category.kbitem_set.all() + selected_item = request.GET.get('kbitem', None) + try: + selected_item = int(selected_item) + except ValueError: + pass return render(request, 'helpdesk/kb_category.html', { 'category': category, 'items': items, - 'helpdesk_settings': helpdesk_settings, - }) - - -def item(request, item): - item = get_object_or_404(KBItem, pk=item) - return render(request, 'helpdesk/kb_item.html', { - 'category': item.category, - 'item': item, + 'selected_item': selected_item, 'helpdesk_settings': helpdesk_settings, }) diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py index 94820d13..2ffcdc38 100644 --- a/helpdesk/views/public.py +++ b/helpdesk/views/public.py @@ -21,7 +21,7 @@ from helpdesk.decorators import protect_view, is_helpdesk_staff import helpdesk.views.staff as staff from helpdesk.forms import PublicTicketForm from helpdesk.lib import text_is_spam -from helpdesk.models import CustomField, Ticket, Queue, UserSettings, KBCategory +from helpdesk.models import CustomField, Ticket, Queue, UserSettings, KBCategory, KBItem def create_ticket(request, *args, **kwargs): @@ -82,7 +82,7 @@ class BaseCreateTicketView(FormView): if request.user.is_authenticated and request.user.email: initial_data['submitter_email'] = request.user.email - query_param_fields = ['submitter_email', 'title', 'body', 'queue'] + query_param_fields = ['submitter_email', 'title', 'body', 'queue', 'kbitem'] custom_fields = ["custom_%s" % f.name for f in CustomField.objects.filter(staff_only=False)] query_param_fields += custom_fields for qpf in query_param_fields: @@ -93,6 +93,12 @@ class BaseCreateTicketView(FormView): kwargs = super().get_form_kwargs(*args, **kwargs) kwargs['hidden_fields'] = self.request.GET.get('_hide_fields_', '').split(',') kwargs['readonly_fields'] = self.request.GET.get('_readonly_fields_', '').split(',') + kbitem = self.request.GET.get('kbitem', None) + if kbitem: + try: + kwargs['kbcategory'] = KBItem.objects.get(pk=int(kbitem)) + except (ValueError, KBItem.DoesNotExist): + pass return kwargs def form_valid(self, form):