forked from extern/django-helpdesk
Merge pull request #1 from auto-mat/kb_forms
Vylepšení znalostní báze pro DPNK 2020
This commit is contained in:
commit
4acbb32ef5
@ -70,7 +70,7 @@ class FollowUpAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(KBItem)
|
||||
class KBItemAdmin(admin.ModelAdmin):
|
||||
list_display = ('category', 'title', 'last_updated', 'team', )
|
||||
list_display = ('category', 'title', 'last_updated', 'team', 'order', 'enabled')
|
||||
inlines = [KBIAttachmentInline]
|
||||
readonly_fields = ('voted_by', 'downvoted_by')
|
||||
|
||||
@ -93,6 +93,10 @@ class IgnoreEmailAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'queue_list', 'email_address', 'keep_in_mailbox')
|
||||
|
||||
|
||||
@admin.register(KBCategory)
|
||||
class KBCategoryAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'title', 'slug', 'public')
|
||||
|
||||
|
||||
admin.site.register(PreSetReply)
|
||||
admin.site.register(EscalationExclusion)
|
||||
admin.site.register(KBCategory)
|
||||
|
@ -183,8 +183,8 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form):
|
||||
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)],
|
||||
label=_('Knowledge Base Item'),
|
||||
choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk, enabled=True)],
|
||||
)
|
||||
|
||||
def _add_form_custom_fields(self, staff_only_filter=None):
|
||||
|
33
helpdesk/migrations/0030_add_kbcategory_name.py
Normal file
33
helpdesk/migrations/0030_add_kbcategory_name.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Generated by Django 2.2.10 on 2020-02-25 11:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
def copy_title(apps, schema_editor):
|
||||
KBCategory = apps.get_model("helpdesk", "KBCategory")
|
||||
KBCategory.objects.update(name=models.F('title'))
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('helpdesk', '0029_kbcategory_public'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='kbcategory',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Name of the category'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='kbcategory',
|
||||
name='title',
|
||||
field=models.CharField(max_length=100, verbose_name='Title on knowledgebase page'),
|
||||
),
|
||||
migrations.RunPython(copy_title, migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name='kbcategory',
|
||||
name='name',
|
||||
field=models.CharField(blank=False, max_length=100, null=False, verbose_name='Name of the category'),
|
||||
),
|
||||
]
|
22
helpdesk/migrations/0031_auto_20200225_1440.py
Normal file
22
helpdesk/migrations/0031_auto_20200225_1440.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Generated by Django 2.2.10 on 2020-02-25 13:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('helpdesk', '0030_add_kbcategory_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='kbitem',
|
||||
options={'ordering': ('order', 'title'), 'verbose_name': 'Knowledge base item', 'verbose_name_plural': 'Knowledge base items'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='kbitem',
|
||||
name='order',
|
||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Order'),
|
||||
),
|
||||
]
|
18
helpdesk/migrations/0032_kbitem_enabled.py
Normal file
18
helpdesk/migrations/0032_kbitem_enabled.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.2.10 on 2020-02-25 13:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('helpdesk', '0031_auto_20200225_1440'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='kbitem',
|
||||
name='enabled',
|
||||
field=models.BooleanField(default=True, verbose_name='Enabled to display to users'),
|
||||
),
|
||||
]
|
@ -1215,8 +1215,13 @@ class KBCategory(models.Model):
|
||||
listing of questions & answers.
|
||||
"""
|
||||
|
||||
name = models.CharField(
|
||||
_('Name of the category'),
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
title = models.CharField(
|
||||
_('Title'),
|
||||
_('Title on knowledgebase page'),
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
@ -1242,7 +1247,7 @@ class KBCategory(models.Model):
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return '%s' % self.title
|
||||
return '%s' % self.name
|
||||
|
||||
class Meta:
|
||||
ordering = ('title',)
|
||||
@ -1312,6 +1317,17 @@ class KBItem(models.Model):
|
||||
null=True,
|
||||
)
|
||||
|
||||
order = models.PositiveIntegerField(
|
||||
_('Order'),
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
enabled = models.BooleanField(
|
||||
_('Enabled to display to users'),
|
||||
default=True,
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.last_updated:
|
||||
self.last_updated = timezone.now()
|
||||
@ -1328,7 +1344,7 @@ class KBItem(models.Model):
|
||||
return '%s: %s' % (self.category.title, self.title)
|
||||
|
||||
class Meta:
|
||||
ordering = ('title',)
|
||||
ordering = ('order', 'title',)
|
||||
verbose_name = _('Knowledge base item')
|
||||
verbose_name_plural = _('Knowledge base items')
|
||||
|
||||
|
@ -242,6 +242,10 @@ body.fixed-nav.sidebar-toggled #content-wrapper {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-body-icon {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
|
@ -27,3 +27,6 @@
|
||||
|
||||
<!-- Custom Theme JavaScript -->
|
||||
<script src="{% static 'helpdesk/js/sb-admin.js' %}"></script>
|
||||
|
||||
{% block js_bottom %}
|
||||
{% endblock %}
|
||||
|
@ -1,35 +1,42 @@
|
||||
{% load i18n %}
|
||||
<h2>{% trans 'Knowledgebase Category' %}:{% blocktrans with category.title as kbcat %}{{ kbcat }}{% endblocktrans %}</h2>
|
||||
<p>{{ category.description }}</p>
|
||||
{% block header %}
|
||||
<h2>{% blocktrans with category.title as kbcat %}{{ kbcat }}{% endblocktrans %}</h2>
|
||||
{{ category.description|linebreaks }}
|
||||
{% endblock %}
|
||||
|
||||
{% block item_list %}
|
||||
<div id="accordion">
|
||||
{% for item in items %}
|
||||
<div class="card mb-3">
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#collapse{{item.id}}" aria-expanded="true" aria-controls="collapse{{item.id}}">
|
||||
<div class="btn btn-link" data-toggle="collapse" data-target="#collapse{{item.id}}" role="region" aria-expanded="true" aria-controls="collapse{{item.id}}">
|
||||
<div class="card-header" id="header{{item.id}}">
|
||||
<h5 class="mb-0">
|
||||
{{ item.title }}
|
||||
</h5>
|
||||
</div>
|
||||
</button>
|
||||
<div id="collapse{{item.id}}" class="collapse {% if item.id == selected_item %}show{% endif %}" aria-labelledby="header{{item.id}}" data-parent="#accordion">
|
||||
</div>
|
||||
<div id="collapse{{item.id}}" class="collapse {% if item.id == selected_item %}show{% endif %}" role="region" aria-labelledby="header{{item.id}}" data-parent="#accordion">
|
||||
{% block card_body %}
|
||||
<div class="card-body">
|
||||
<p class="card-text">{{ item.question }}</p>
|
||||
<p>{{ item.get_markdown }}</p>
|
||||
<div class="card-answer">
|
||||
{{ item.get_markdown }}
|
||||
</div>
|
||||
<div class="row">
|
||||
{% if request.user.pk %}
|
||||
<div class="col-sm">
|
||||
<a href='{% url "helpdesk:kb_vote" item.pk %}?vote=up'><button type="button" class="btn btn-success btn-circle btn-xl"><i class="fa fa-thumbs-up fa-lg"></i></button></a>
|
||||
<a href='{% url "helpdesk:kb_vote" item.pk %}?vote=down'><button type="button" class="btn btn-danger btn-circle btn-xl"><i class="fa fa-thumbs-down fa-lg"></i></button></a>
|
||||
<a href='{% url "helpdesk:kb_vote" item.pk %}?vote=up'><div class="btn btn-success btn-circle btn-xl"><i class="fa fa-thumbs-up fa-lg"></i></div></a>
|
||||
<a href='{% url "helpdesk:kb_vote" item.pk %}?vote=down'><div class="btn btn-danger btn-circle btn-xl"><i class="fa fa-thumbs-down fa-lg"></i></div></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if staff %}
|
||||
<a href='{% url 'helpdesk:list' %}?kbitem={{item.id}}' class="col-sm">
|
||||
<button type="button" class="btn btn-success btn-circle btn-xl float-right"><i class="fa fa-search fa-lg"></i> {{item.num_open_tickets}} {% trans 'open tickets' %}</button>
|
||||
<div class="btn btn-success btn-circle btn-xl float-right"><i class="fa fa-search fa-lg"></i> {{item.num_open_tickets}} {% trans 'open tickets' %}</div>
|
||||
</a>
|
||||
|
||||
{% endif %}
|
||||
<a href='{% if iframe %}{% url 'helpdesk:submit_iframe' %}{% else %}{% url 'helpdesk:submit' %}{%endif%}?{% if category.queue %}queue={{category.queue.pk}};_readonly_fields_=queue;{%endif%}kbitem={{item.id}};{{query_param_string}}' class="col-sm">
|
||||
<button type="button" class="btn btn-success btn-circle btn-xl float-right"><i class="fa fa-envelope fa-lg"></i> {% trans 'Contact a human' %}</button>
|
||||
<div class="btn btn-success btn-circle btn-xl float-right"><i class="fa fa-envelope fa-lg"></i> {% trans 'Contact a human' %}</div>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
@ -39,12 +46,18 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block footer %}
|
||||
{% endblock %}
|
||||
{% if category.queue %}
|
||||
<a href='{% if iframe %}{% url 'helpdesk:submit_iframe' %}{% else %}{% url 'helpdesk:submit' %}{%endif%}?queue={{category.queue.pk}};_readonly_fields_=queue;{{query_param_string}}'>
|
||||
<button type="button" class="btn btn-danger btn-circle btn-xl float-right"><i class="fa fa-envelope fa-lg"></i> {% trans 'Contact a human' %}</button>
|
||||
{% block submit_button %}
|
||||
<div class="btn btn-danger btn-circle btn-xl float-right"><i class="fa fa-envelope fa-lg"></i> {% trans 'Contact a human' %}</div>
|
||||
{% endblock %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -1,5 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% load saved_queries %}
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
{% include 'helpdesk/base-head.html' %}
|
||||
{% block helpdesk_head %}{% endblock %}
|
||||
|
@ -3,7 +3,9 @@
|
||||
{% with request|load_helpdesk_settings as helpdesk_settings %}
|
||||
|
||||
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||
{% block form_header %}
|
||||
<p>{% trans "Unless otherwise stated, all fields are required." %} {% trans "Please provide as descriptive a title and description as possible." %}</p>
|
||||
{% endblock %}
|
||||
<form method='post' enctype='multipart/form-data'>
|
||||
{{ form|bootstrap4form }}
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block"><i class="fa fa-send"></i> {% trans "Submit Ticket" %}</button>
|
||||
|
@ -1,5 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% load saved_queries %}
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
{% include 'helpdesk/base-head.html' %}
|
||||
</head>
|
||||
|
@ -30,7 +30,7 @@ def category(request, slug, iframe=False):
|
||||
category = get_object_or_404(KBCategory, slug__iexact=slug)
|
||||
if not user.huser_from_request(request).can_access_kbcategory(category):
|
||||
raise Http404
|
||||
items = category.kbitem_set.all()
|
||||
items = category.kbitem_set.filter(enabled=True)
|
||||
selected_item = request.GET.get('kbitem', None)
|
||||
try:
|
||||
selected_item = int(selected_item)
|
||||
|
Loading…
Reference in New Issue
Block a user