forked from extern/django-helpdesk
Merge branch 'kotowicz-master', manually merging conflicts in these files:
helpdesk/lib.py helpdesk/templates/helpdesk/ticket_desc_table.html helpdesk/views/staff.py
This commit is contained in:
commit
533fdc8c2a
@ -11,6 +11,7 @@ from datetime import datetime
|
|||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.forms import extras
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
@ -57,7 +58,10 @@ class EditTicketForm(forms.ModelForm):
|
|||||||
instanceargs['max_digits'] = field.max_length
|
instanceargs['max_digits'] = field.max_length
|
||||||
elif field.data_type == 'list':
|
elif field.data_type == 'list':
|
||||||
fieldclass = forms.ChoiceField
|
fieldclass = forms.ChoiceField
|
||||||
instanceargs['choices'] = field.choices_as_array
|
if field.empty_selection_list:
|
||||||
|
choices = field.choices_as_array
|
||||||
|
choices.insert(0, ('','---------' ) )
|
||||||
|
instanceargs['choices'] = choices
|
||||||
elif field.data_type == 'boolean':
|
elif field.data_type == 'boolean':
|
||||||
fieldclass = forms.BooleanField
|
fieldclass = forms.BooleanField
|
||||||
elif field.data_type == 'date':
|
elif field.data_type == 'date':
|
||||||
@ -113,19 +117,20 @@ class TicketForm(forms.Form):
|
|||||||
title = forms.CharField(
|
title = forms.CharField(
|
||||||
max_length=100,
|
max_length=100,
|
||||||
required=True,
|
required=True,
|
||||||
widget=forms.TextInput(),
|
widget=forms.TextInput(attrs={'size':'60'}),
|
||||||
label=_('Summary of the problem'),
|
label=_('Summary of the problem'),
|
||||||
)
|
)
|
||||||
|
|
||||||
submitter_email = forms.EmailField(
|
submitter_email = forms.EmailField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Submitter E-Mail Address'),
|
label=_('Submitter E-Mail Address'),
|
||||||
|
widget=forms.TextInput(attrs={'size':'60'}),
|
||||||
help_text=_('This e-mail address will receive copies of all public '
|
help_text=_('This e-mail address will receive copies of all public '
|
||||||
'updates to this ticket.'),
|
'updates to this ticket.'),
|
||||||
)
|
)
|
||||||
|
|
||||||
body = forms.CharField(
|
body = forms.CharField(
|
||||||
widget=forms.Textarea(),
|
widget=forms.Textarea(attrs={'cols': 47, 'rows': 15}),
|
||||||
label=_('Description of Issue'),
|
label=_('Description of Issue'),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@ -190,11 +195,15 @@ class TicketForm(forms.Form):
|
|||||||
instanceargs['max_digits'] = field.max_length
|
instanceargs['max_digits'] = field.max_length
|
||||||
elif field.data_type == 'list':
|
elif field.data_type == 'list':
|
||||||
fieldclass = forms.ChoiceField
|
fieldclass = forms.ChoiceField
|
||||||
instanceargs['choices'] = field.choices_as_array
|
if field.empty_selection_list:
|
||||||
|
choices = field.choices_as_array
|
||||||
|
choices.insert(0, ('','---------' ) )
|
||||||
|
instanceargs['choices'] = choices
|
||||||
elif field.data_type == 'boolean':
|
elif field.data_type == 'boolean':
|
||||||
fieldclass = forms.BooleanField
|
fieldclass = forms.BooleanField
|
||||||
elif field.data_type == 'date':
|
elif field.data_type == 'date':
|
||||||
fieldclass = forms.DateField
|
fieldclass = forms.DateField
|
||||||
|
instanceargs['widget'] = extras.SelectDateWidget
|
||||||
elif field.data_type == 'time':
|
elif field.data_type == 'time':
|
||||||
fieldclass = forms.TimeField
|
fieldclass = forms.TimeField
|
||||||
elif field.data_type == 'datetime':
|
elif field.data_type == 'datetime':
|
||||||
@ -399,9 +408,9 @@ class PublicTicketForm(forms.Form):
|
|||||||
instanceargs['max_digits'] = field.max_length
|
instanceargs['max_digits'] = field.max_length
|
||||||
elif field.data_type == 'list':
|
elif field.data_type == 'list':
|
||||||
fieldclass = forms.ChoiceField
|
fieldclass = forms.ChoiceField
|
||||||
choices = []
|
if field.empty_selection_list:
|
||||||
for line in field.list_values.split("\n"):
|
choices = field.choices_as_array
|
||||||
choices.append((line, line))
|
choices.insert(0, ('','---------' ) )
|
||||||
instanceargs['choices'] = choices
|
instanceargs['choices'] = choices
|
||||||
elif field.data_type == 'boolean':
|
elif field.data_type == 'boolean':
|
||||||
fieldclass = forms.BooleanField
|
fieldclass = forms.BooleanField
|
||||||
|
@ -57,7 +57,13 @@ def send_templated_mail(template_name, email_context, recipients, sender=None, b
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
context = Context(email_context)
|
context = Context(email_context)
|
||||||
locale = context['queue'].get('locale', 'en')
|
|
||||||
|
if hasattr(context['queue'], 'locale'):
|
||||||
|
locale = getattr(context['queue'], 'locale', '')
|
||||||
|
else:
|
||||||
|
locale = context['queue'].get('locale', 'en')
|
||||||
|
if not locale:
|
||||||
|
locale = 'en'
|
||||||
|
|
||||||
t = None
|
t = None
|
||||||
try:
|
try:
|
||||||
@ -102,7 +108,8 @@ def send_templated_mail(template_name, email_context, recipients, sender=None, b
|
|||||||
).render(context)
|
).render(context)
|
||||||
|
|
||||||
if isinstance(recipients,(str,unicode)):
|
if isinstance(recipients,(str,unicode)):
|
||||||
recipients = recipients.split(',')
|
if recipients.find(','):
|
||||||
|
recipients = recipients.split(',')
|
||||||
elif type(recipients) != list:
|
elif type(recipients) != list:
|
||||||
recipients = [recipients,]
|
recipients = [recipients,]
|
||||||
|
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1176,6 +1176,11 @@ class CustomField(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
empty_selection_list = models.BooleanField(
|
||||||
|
_('Add empty first choice to List?'),
|
||||||
|
help_text=_('Only for List: adds an empty first entry to the choices list, which enforces that the user makes an active choice.'),
|
||||||
|
)
|
||||||
|
|
||||||
list_values = models.TextField(
|
list_values = models.TextField(
|
||||||
_('List Values'),
|
_('List Values'),
|
||||||
help_text=_('For list fields only. Enter one option per line.'),
|
help_text=_('For list fields only. Enter one option per line.'),
|
||||||
|
@ -28,5 +28,96 @@ if type(DEFAULT_USER_SETTINGS) != type(dict()):
|
|||||||
'tickets_per_page': 25
|
'tickets_per_page': 25
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' generic options - visible on all pages '''
|
||||||
|
# redirect to login page instead of the default homepage when users visits "/"?
|
||||||
|
HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = getattr(settings, 'HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT', False)
|
||||||
|
|
||||||
|
# customize helpdesk name on a few pages, i.e., your organization.
|
||||||
|
HELPDESK_PREPEND_ORG_NAME = getattr(settings, 'HELPDESK_PREPEND_ORG_NAME', False)
|
||||||
|
|
||||||
# show knowledgebase links?
|
# show knowledgebase links?
|
||||||
HELPDESK_KB_ENABLED = getattr(settings, 'HELPDESK_KB_ENABLED', True)
|
HELPDESK_KB_ENABLED = getattr(settings, 'HELPDESK_KB_ENABLED', True)
|
||||||
|
|
||||||
|
# show extended navigation by default, to all users, irrespective of staff status?
|
||||||
|
HELPDESK_NAVIGATION_ENABLED = getattr(settings, 'HELPDESK_NAVIGATION_ENABLED', False)
|
||||||
|
|
||||||
|
# show 'stats' link in navigation bar?
|
||||||
|
HELPDESK_NAVIGATION_STATS_ENABLED = getattr(settings, 'HELPDESK_NAVIGATION_STATS_ENABLED', True)
|
||||||
|
|
||||||
|
# set this to an email address inside your organization and a footer below
|
||||||
|
# the 'Powered by django-helpdesk' will be shown, telling the user whom to contact
|
||||||
|
# in case they have technical problems.
|
||||||
|
HELPDESK_SUPPORT_PERSON = getattr(settings, 'HELPDESK_SUPPORT_PERSON', False)
|
||||||
|
|
||||||
|
# show dropdown list of languages that ticket comments can be translated into?
|
||||||
|
HELPDESK_TRANSLATE_TICKET_COMMENTS = getattr(settings, 'HELPDESK_TRANSLATE_TICKET_COMMENTS', False)
|
||||||
|
|
||||||
|
# list of languages to offer. if set to false, all default google translate languages will be shown.
|
||||||
|
HELPDESK_TRANSLATE_TICKET_COMMENTS_LANG = getattr(settings, 'HELPDESK_TRANSLATE_TICKET_COMMENTS_LANG', ["en", "de", "fr", "ru"])
|
||||||
|
|
||||||
|
# show link to 'change password' on 'User Settings' page?
|
||||||
|
HELPDESK_SHOW_CHANGE_PASSWORD = getattr(settings, 'HELPDESK_SHOW_CHANGE_PASSWORD', False)
|
||||||
|
|
||||||
|
# allow user to override default layout for 'followups' - work in progress.
|
||||||
|
HELPDESK_FOLLOWUP_MOD = getattr(settings, 'HELPDESK_FOLLOWUP_MOD', False)
|
||||||
|
|
||||||
|
# show custom welcome message in dashboard?
|
||||||
|
HELPDESK_CUSTOM_WELCOME = getattr(settings, 'HELPDESK_CUSTOM_WELCOME', False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' options for public pages '''
|
||||||
|
# show 'view a ticket' section on public page?
|
||||||
|
HELPDESK_VIEW_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_VIEW_A_TICKET_PUBLIC', True)
|
||||||
|
|
||||||
|
# show 'submit a ticket' section on public page?
|
||||||
|
HELPDESK_SUBMIT_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_SUBMIT_A_TICKET_PUBLIC', True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' options for update_ticket views '''
|
||||||
|
# allow non-staff users to interact with tickets? this will also change how 'staff_member_required'
|
||||||
|
# in staff.py will be defined.
|
||||||
|
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, 'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', False)
|
||||||
|
|
||||||
|
# show edit buttons in ticket follow ups.
|
||||||
|
HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, 'HELPDESK_HIDE_EDIT_BUTTON_FOLLOW_UP', True)
|
||||||
|
|
||||||
|
# show ticket edit button on top of ticket description.
|
||||||
|
HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP', True)
|
||||||
|
|
||||||
|
# show ticket delete button on top of ticket description.
|
||||||
|
HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP', True)
|
||||||
|
|
||||||
|
# show hold / unhold button on top of ticket description.
|
||||||
|
HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP', True)
|
||||||
|
|
||||||
|
# make all updates public by default? this will hide the 'is this update public' checkbox
|
||||||
|
HELPDESK_UPDATE_PUBLIC_DEFAULT = getattr(settings, 'HELPDESK_UPDATE_PUBLIC_DEFAULT', True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' options for staff.create_ticket view '''
|
||||||
|
# hide the 'assigned to' / 'Case owner' field from the 'create_ticket' view?
|
||||||
|
HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO = getattr(settings, 'HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO', False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' options for dashboard '''
|
||||||
|
# show delete button next to unassigned tickets
|
||||||
|
HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED = getattr(settings, 'HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED', True)
|
||||||
|
|
||||||
|
# hide empty queues in dashboard overview?
|
||||||
|
HELPDESK_DASHBOARD_HIDE_EMPTY_QUEUES = getattr(settings, 'HELPDESK_DASHBOARD_HIDE_EMPTY_QUEUES', True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' options for footer '''
|
||||||
|
# show 'API' link at bottom of page
|
||||||
|
HELPDESK_FOOTER_SHOW_API_LINK = getattr(settings, 'HELPDESK_FOOTER_SHOW_API_LINK', True)
|
||||||
|
|
||||||
|
# show / hide 'change language' link at bottom of page
|
||||||
|
HELPDESK_FOOTER_SHOW_CHANGE_LANGUAGE_LINK = getattr(settings, 'HELPDESK_FOOTER_SHOW_CHANGE_LANGUAGE_LINK', False)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ table {
|
|||||||
border: solid #444 1px;
|
border: solid #444 1px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
padding: 2px 3px;
|
padding: 0px 3px;
|
||||||
margin: 0px 2px;
|
margin: 0px 2px;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
line-height: 12pt;
|
line-height: 12pt;
|
||||||
@ -159,16 +159,29 @@ div.followup {
|
|||||||
padding:0 0 2px;
|
padding:0 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.followup .title {
|
div.followup_mod {
|
||||||
|
width: auto;
|
||||||
|
border: solid #666 1px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0px 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.followup .title, div.followup_mod .title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.followup .title span {
|
div.followup .title span, div.followup_mod .title span {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.followup_mod small {
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
span.private {
|
span.private {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
@ -267,3 +280,34 @@ span.priority5 {
|
|||||||
a.followup-edit {
|
a.followup-edit {
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tooltips for link hover */
|
||||||
|
a.tooltip, a.tooltip:link, a.tooltip:visited, a.tooltip:active {
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tooltip:hover {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tooltip span {
|
||||||
|
display: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.tooltip:hover span {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 25px;
|
||||||
|
left: 0;
|
||||||
|
width: 250px;
|
||||||
|
z-index: 10;
|
||||||
|
color: #000000;
|
||||||
|
border:1px solid #000000;
|
||||||
|
background: #FFFFCC;
|
||||||
|
font: 12px Verdana, sans-serif;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
1546
helpdesk/static/helpdesk/jquery.translate-debug-all.js
Normal file
1546
helpdesk/static/helpdesk/jquery.translate-debug-all.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,5 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% trans "Powered by <a href='https://github.com/rossp/django-helpdesk'>django-helpdesk</a>." %}
|
{% trans "Powered by <a href='https://github.com/rossp/django-helpdesk'>django-helpdesk</a>." %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_SUPPORT_PERSON %}
|
||||||
|
<p>{% trans "For technical support please contact:" %} <a href='mailto:{{ helpdesk_settings.HELPDESK_SUPPORT_PERSON }}'>{{ helpdesk_settings.HELPDESK_SUPPORT_PERSON }}</a></p>
|
||||||
|
{% endif %}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load saved_queries %}
|
{% load saved_queries %}
|
||||||
|
{% load load_helpdesk_settings %}
|
||||||
|
{% with request|load_helpdesk_settings as helpdesk_settings %}
|
||||||
{% with request|saved_queries as user_saved_queries_ %}
|
{% with request|saved_queries as user_saved_queries_ %}
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
@ -7,20 +9,71 @@
|
|||||||
<title>{% block helpdesk_title %}Helpdesk{% endblock %} :: {% trans "Powered by django-helpdesk" %}</title>
|
<title>{% block helpdesk_title %}Helpdesk{% endblock %} :: {% trans "Powered by django-helpdesk" %}</title>
|
||||||
<script src='{{ STATIC_URL }}helpdesk/jquery-1.5.min.js' type='text/javascript' language='javascript'></script>
|
<script src='{{ STATIC_URL }}helpdesk/jquery-1.5.min.js' type='text/javascript' language='javascript'></script>
|
||||||
<script src='{{ STATIC_URL }}helpdesk/jquery-ui-1.8.9.custom.min.js' type='text/javascript' language='javascript'></script>
|
<script src='{{ STATIC_URL }}helpdesk/jquery-ui-1.8.9.custom.min.js' type='text/javascript' language='javascript'></script>
|
||||||
|
{% comment %}
|
||||||
|
<script src='{{ STATIC_URL }}helpdesk/jquery.translate-debug-all.js' type='text/javascript' language='javascript'></script>
|
||||||
|
{% endcomment %}
|
||||||
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/helpdesk.css' type='text/css' />
|
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/helpdesk.css' type='text/css' />
|
||||||
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/jquery-smoothness-theme/jquery-ui-1.8.9.custom.css' type='text/css' />
|
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/jquery-smoothness-theme/jquery-ui-1.8.9.custom.css' type='text/css' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='{% trans "My Open Tickets" %}' />
|
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='{% trans "My Open Tickets" %}' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "recent_activity" %}' type='application/rss+xml' title='{% trans "All Recent Activity" %}' />
|
<link rel='alternate' href='{% url helpdesk_rss "recent_activity" %}' type='application/rss+xml' title='{% trans "All Recent Activity" %}' />
|
||||||
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='{% trans "Unassigned Tickets" %}' />
|
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='{% trans "Unassigned Tickets" %}' />
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
// replace display while hovering over menu item
|
// replace display while hovering over menu item
|
||||||
$('li.headerlink').hover(
|
$('li.headerlink').hover(
|
||||||
function() { $('ul', this).css('display', 'block'); },
|
function() { $('ul', this).css('display', 'block'); },
|
||||||
function() { $('ul', this).css('display', 'none'); });
|
function() { $('ul', this).css('display', 'none'); });
|
||||||
|
|
||||||
|
{% if helpdesk_settings.HELPDESK_TRANSLATE_TICKET_COMMENTS %}
|
||||||
|
// add translate functionality - google translate V1 is deprecated
|
||||||
|
$.translate.load(bingID);
|
||||||
|
$.translate(function(){ //when the Language API is loaded
|
||||||
|
$.translate().ui({
|
||||||
|
tags: ["select", "option"],
|
||||||
|
// a function that filters the languages:
|
||||||
|
{% if helpdesk_settings.HELPDESK_TRANSLATE_TICKET_COMMENTS_LANG %}
|
||||||
|
filter: {{ helpdesk_settings.HELPDESK_TRANSLATE_TICKET_COMMENTS_LANG|safe }},
|
||||||
|
{% else %}
|
||||||
|
// all languages
|
||||||
|
filter: $.translate.isTranslatable,
|
||||||
|
{% endif %}
|
||||||
|
//a function that returns the text to display based on the language code:
|
||||||
|
label: $.translate.toNativeLanguage ||
|
||||||
|
function(langCode, lang){
|
||||||
|
return $.translate.capitalize(lang);
|
||||||
|
},
|
||||||
|
// whether to include the UNKNOWN:"" along with the languages:
|
||||||
|
includeUnknown: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
.click(function(){ // when selecting a language - 'change' is not enough, because your first language in the menu might be your target language
|
||||||
|
$('#translate_block').translate( '', $(this).val(), { // translate from current language to the selected language
|
||||||
|
not: '.option, select, pre, .translate_dropdown', // exclude these elements
|
||||||
|
fromOriginal: true, // always translate from original version (even after the page has been translated)
|
||||||
|
async: true, // this prevents the browser from freezing on larger sites by executing each DOM filtering iteration with a delay
|
||||||
|
toggle: true, // all translation will be cached (stored with $.data) and used if it's found, or translated to otherwise
|
||||||
|
walk: true // finds elements having textnodes and translates only their content; on very large and complex pages this might take some time
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.appendTo('#translate_dropdown'); // insert the dropdown menu to the page
|
||||||
|
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
/* hide google translate top bar */
|
||||||
|
.goog-te-banner-frame {display: none !important;}
|
||||||
|
.goog-te-balloon-frame {display: none !important;}
|
||||||
|
/* hide google translate tooltips (generated for every translated item) */
|
||||||
|
.goog-tooltip {display: none !important; }
|
||||||
|
</style>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* header */
|
/* header */
|
||||||
@ -51,10 +104,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
<p>{% include "helpdesk/attribution.html" %}<a href='{% url helpdesk_rss_index %}'><img src='{{ STATIC_URL }}helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a> <a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a> <a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a> {% if user.is_superuser %}<a href='{% url helpdesk_system_settings %}'>{% trans "System Settings" %}</a>{% endif %}</p>
|
<p>{% include "helpdesk/attribution.html" %}
|
||||||
|
<a href='{% url helpdesk_rss_index %}'><img src='{{ STATIC_URL }}helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a>
|
||||||
|
{% if helpdesk_settings.HELPDESK_FOOTER_SHOW_API_LINK %}<a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a>{% endif %}
|
||||||
|
<a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a>
|
||||||
|
{% if helpdesk_settings.HELPDESK_FOOTER_SHOW_CHANGE_LANGUAGE_LINK %}
|
||||||
|
<a href='{% url helpdesk_public_change_language %}?return_to={{ request.path }}'>{% trans "Change Language" %}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.is_superuser %}<a href='{% url helpdesk_system_settings %}'>{% trans "System Settings" %}</a>{% endif %}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include "helpdesk/debug.html" %}
|
{% include "helpdesk/debug.html" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
{% if field.is_hidden %}
|
{% if field.is_hidden %}
|
||||||
{{ field }}
|
{{ field }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<dt><label for='id_{{ field.name }}'>{{ field.label }}</label>{% if not field.field.required %} <span class='form_optional'>{% trans "(Optional)" %}</span>{% endif %}</dt>
|
<dt><label for='id_{{ field.name }}'>{% trans field.label %}</label>{% if not field.field.required %} <span class='form_optional'>{% trans "(Optional)" %}</span>{% endif %}</dt>
|
||||||
<dd>{{ field }}</dd>
|
<dd>{{ field }}</dd>
|
||||||
{% if field.errors %}<dd class='error'>{{ field.errors }}</dd>{% endif %}
|
{% if field.errors %}<dd class='error'>{{ field.errors }}</dd>{% endif %}
|
||||||
{% if field.help_text %}<dd class='form_help_text'>{{ field.help_text }}</dd>{% endif %}</label>
|
{% if field.help_text %}<dd class='form_help_text'>{% trans field.help_text %}</dd>{% endif %}</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -1,28 +1,59 @@
|
|||||||
{% extends "helpdesk/base.html" %}{% load i18n %}
|
{% extends "helpdesk/base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}{% trans "Helpdesk Dashboard" %}{% endblock %}
|
{% block helpdesk_title %}{{ helpdesk_settings.HELPDESK_PREPEND_ORG_NAME|default:'' }} {% trans "Helpdesk Dashboard" %}{% endblock %}
|
||||||
{% block helpdesk_head %}
|
{% block helpdesk_head %}
|
||||||
<script type='text/javascript' language='javascript' src='{{ STATIC_URL }}helpdesk/hover.js'></script>
|
<script type='text/javascript' language='javascript' src='{{ STATIC_URL }}helpdesk/hover.js'></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
|
|
||||||
<table width='40%' align='left'>
|
<div style='float:left; width:auto; margin-right:10px;'>
|
||||||
<tr class='row_tablehead'><td colspan='4'>{% trans "Helpdesk Summary" %}</td></tr>
|
<table width='100%'>
|
||||||
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th></tr>
|
<tr class='row_tablehead'><td colspan='5'>{% trans "Helpdesk Summary" %}</td></tr>
|
||||||
|
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th><th>{% trans "Closed" %}</th></tr>
|
||||||
{% for queue in dash_tickets %}
|
{% for queue in dash_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover '>
|
<tr class='row_{% cycle odd,even %} row_hover '>
|
||||||
<th><a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></th>
|
<th><a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></th>
|
||||||
<td>{% if queue.open %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
|
<td align="center">{% if queue.open %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
|
||||||
<td>{% if queue.resolved %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
|
<td align="center">{% if queue.resolved %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
|
||||||
|
<td align="center">{% if queue.closed %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=4'>{% endif %}{{ queue.closed }}{% if queue.closed %}</a>{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{% if helpdesk_settings.HELPDESK_CUSTOM_WELCOME %}
|
||||||
|
<p>{% trans "Welcome to your Helpdesk Dashboard! From here you can quickly see tickets submitted by you, tickets you are working on, and those tickets that have no owner." %}</p>
|
||||||
|
{% else %}
|
||||||
|
<p>{% trans "Welcome to your Helpdesk Dashboard! From here you can quickly see your own tickets, and those tickets that have no owner. Why not pick up an orphan ticket and sort it out for a customer?" %}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% if all_tickets_reported_by_current_user %}
|
||||||
|
<br style='clear: both;' />
|
||||||
|
|
||||||
|
<table width='100%'>
|
||||||
|
<tr class='row_tablehead'><td colspan='6'>{% trans "All Tickets submitted by you" %}</td></tr>
|
||||||
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||||
|
{% for ticket in all_tickets_reported_by_current_user %}
|
||||||
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||||
|
<td>{{ ticket.get_priority_span }}</td>
|
||||||
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
|
<td>{{ ticket.queue }}</td>
|
||||||
|
<td>{{ ticket.get_status }}</td>
|
||||||
|
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|timesince }}</span></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<p style='margin-left: 42%;'>{% trans "Welcome to your Helpdesk Dashboard! From here you can quickly see your own tickets, and those tickets that have no owner. Why not pick up an orphan ticket and sort it out for a customer?" %}</p>
|
|
||||||
|
|
||||||
<br style='clear: both;' />
|
<br style='clear: both;' />
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Your Tickets" %}</td></tr>
|
<tr class='row_tablehead'><td colspan='6'>{% trans "Open Tickets assigned to you (you are working on this ticket)" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||||
{% for ticket in user_tickets %}
|
{% for ticket in user_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
@ -39,8 +70,10 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<br style='clear: both;' />
|
||||||
|
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Unassigned Tickets" %}</td></tr>
|
<tr class='row_tablehead'><td colspan='6'>{% trans "Unassigned Tickets" %} {% trans "(pick up a ticket if you start to work on it)" %}</td></tr>
|
||||||
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Created" %}</th><th> </th></tr>
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Created" %}</th><th> </th></tr>
|
||||||
{% for ticket in unassigned_tickets %}
|
{% for ticket in unassigned_tickets %}
|
||||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
@ -49,7 +82,7 @@
|
|||||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
<td>{{ ticket.queue }}</td>
|
<td>{{ ticket.queue }}</td>
|
||||||
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|timesince }} ago</span></td>
|
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|timesince }} ago</span></td>
|
||||||
<th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a> | <a href='{% url helpdesk_delete ticket.id %}'><span class='button button_delete'>{% trans "Delete" %}</span></a></th>
|
<th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a> {% if helpdesk_settings.HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED %}| <a href='{% url helpdesk_delete ticket.id %}'><span class='button button_delete'>{% trans "Delete" %}</span></a>{% endif %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if not unassigned_tickets %}
|
{% if not unassigned_tickets %}
|
||||||
@ -57,4 +90,24 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
{% if user_tickets_closed_resolved %}
|
||||||
|
<br style='clear: both;' />
|
||||||
|
|
||||||
|
<table width='100%'>
|
||||||
|
<tr class='row_tablehead'><td colspan='6'>{% trans "Closed & resolved Tickets you used to work on" %}</td></tr>
|
||||||
|
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||||
|
{% for ticket in user_tickets_closed_resolved %}
|
||||||
|
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||||
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||||
|
<td>{{ ticket.get_priority_span }}</td>
|
||||||
|
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||||
|
<td>{{ ticket.queue }}</td>
|
||||||
|
<td>{{ ticket.get_status }}</td>
|
||||||
|
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|timesince }}</span></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if user.is_staff %}
|
{% if helpdesk_settings.HELPDESK_NAVIGATION_ENABLED and user.is_authenticated or user.is_staff %}
|
||||||
<ul id="dropdown">
|
<ul id="dropdown">
|
||||||
<li><a href='{% url helpdesk_dashboard %}'>{% trans "Dashboard" %}</a></li>
|
<li><a href='{% url helpdesk_dashboard %}'>{% trans "Dashboard" %}</a></li>
|
||||||
<li><a href='{% url helpdesk_list %}'>{% trans "Tickets" %}</a></li>
|
<li><a href='{% url helpdesk_list %}'>{% trans "Tickets" %}</a></li>
|
||||||
<li><a href='{% url helpdesk_submit %}'>{% trans "New Ticket" %}</a></li>
|
<li><a href='{% url helpdesk_submit %}'>{% trans "New Ticket" %}</a></li>
|
||||||
|
{% if helpdesk_settings.HELPDESK_NAVIGATION_STATS_ENABLED %}
|
||||||
<li><a href='{% url helpdesk_report_index %}'>{% trans "Stats" %}</a></li>
|
<li><a href='{% url helpdesk_report_index %}'>{% trans "Stats" %}</a></li>
|
||||||
|
{% endif %}
|
||||||
{% if user_saved_queries_ %}
|
{% if user_saved_queries_ %}
|
||||||
<li class="headerlink"><a>Load Saved Query</a>
|
<li class="headerlink"><a>{% trans "Load Saved Query" %}</a>
|
||||||
<ul>
|
<ul>
|
||||||
{% for q in user_saved_queries_ %}
|
{% for q in user_saved_queries_ %}
|
||||||
<li><a href="{% url helpdesk_list %}?saved_query={{ q.id }}">{{ q.title }}
|
<li><a href="{% url helpdesk_list %}?saved_query={{ q.id }}">{{ q.title }}
|
||||||
@ -18,12 +20,16 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href='{% url logout %}'>{% trans "Logout" %}</a></li>
|
<li><a href='{% url logout %}'>{% trans "Logout" %}</a></li>
|
||||||
{% if not query %}<li><form id='searchform' method='get' action='{% url helpdesk_list %}'><input type='text' name='q' size='10' class='input' value='{% trans "Search..." %}' id='search_query' onFocus='s=document.getElementById("search_query");if (s.value == "{% trans "Search..." %}") { s.value = ""; }' title='{% trans "Enter a keyword, or a ticket number to jump straight to that ticket." %}'/><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /><input type='hidden' name='search_type' value='header' />{% csrf_token %}</form></li>{% endif %}
|
{% if not query %}<li><form id='searchform' method='get' action='{% url helpdesk_list %}'><input type='text' name='q' size='4' class='input' value='{% trans "Search..." %}' id='search_query' onFocus='s=document.getElementById("search_query");if (s.value == "{% trans "Search..." %}") { s.value = ""; }' title='{% trans "Enter a keyword, or a ticket number to jump straight to that ticket." %}'/><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /><input type='hidden' name='search_type' value='header' />{% csrf_token %}</form></li>{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<ul>
|
<ul>
|
||||||
|
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||||
<li><a href='{% url helpdesk_home %}'>{% trans "Submit A Ticket" %}</a></li>
|
<li><a href='{% url helpdesk_home %}'>{% trans "Submit A Ticket" %}</a></li>
|
||||||
|
{% endif %}
|
||||||
{% if helpdesk_settings.HELPDESK_KB_ENABLED %}<li><a href='{% url helpdesk_kb_index %}'>{% trans "Knowledgebase" %}</a></li>{% endif %}
|
{% if helpdesk_settings.HELPDESK_KB_ENABLED %}<li><a href='{% url helpdesk_kb_index %}'>{% trans "Knowledgebase" %}</a></li>{% endif %}
|
||||||
<li><a href='{% url login %}?next={% url helpdesk_dashboard %}'>{% trans "Log In" %}</a></li>
|
{% if not request.path == '/helpdesk/login/' or user.is_authenticated %}
|
||||||
|
<li>{% if user.is_authenticated %}<a href='{% url logout %}'>{% trans "Logout" %}</a>{% else %}<a href='{% url login %}?next={% if next %}{{ next|escape }}{% else %}{% url helpdesk_dashboard %}{% endif %}'>{% trans "Log In" %}</a>{% endif %}</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{% load i18n %}<html>
|
{% load i18n %}
|
||||||
|
{% load load_helpdesk_settings %}
|
||||||
|
{% with request|load_helpdesk_settings as helpdesk_settings %}
|
||||||
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{% block helpdesk_title %}{% trans "Helpdesk" %}{% endblock %}</title>
|
<title>{% block helpdesk_title %}{{ helpdesk_settings.HELPDESK_PREPEND_ORG_NAME|default:'' }} {% trans "Helpdesk" %}{% endblock %}</title>
|
||||||
<script src='{{ STATIC_URL }}helpdesk/jquery-1.5.min.js' type='text/javascript' language='javascript'></script>
|
<script src='{{ STATIC_URL }}helpdesk/jquery-1.5.min.js' type='text/javascript' language='javascript'></script>
|
||||||
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/helpdesk.css' type='text/css' />
|
<link rel='stylesheet' href='{{ STATIC_URL }}helpdesk/helpdesk.css' type='text/css' />
|
||||||
{% block helpdesk_head %}{% endblock %}
|
{% block helpdesk_head %}{% endblock %}
|
||||||
@ -8,7 +11,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id='container'>
|
<div id='container'>
|
||||||
<div id='header'>
|
<div id='header'>
|
||||||
<h1>{% trans "Helpdesk" %}</h1>
|
<h1>{{ helpdesk_settings.HELPDESK_PREPEND_ORG_NAME|default:'' }} {% trans "Helpdesk" %}</h1>
|
||||||
{% include "helpdesk/navigation.html" %}
|
{% include "helpdesk/navigation.html" %}
|
||||||
</div>
|
</div>
|
||||||
<div id='body'>
|
<div id='body'>
|
||||||
@ -20,3 +23,4 @@
|
|||||||
</div>{% include "helpdesk/debug.html" %}
|
</div>{% include "helpdesk/debug.html" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
{% endwith %}
|
||||||
|
18
helpdesk/templates/helpdesk/public_change_language.html
Normal file
18
helpdesk/templates/helpdesk/public_change_language.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
|
{% block helpdesk_title %}{% trans "View a Ticket" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block helpdesk_body %}
|
||||||
|
<h3>{% trans "Change the display language" %}</h3>
|
||||||
|
<form action="/i18n/setlang/" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input name="next" type="hidden" value="{{ next|default:"/" }}" />
|
||||||
|
<select name="language">
|
||||||
|
{% get_language_info_list for LANGUAGES as languages %}
|
||||||
|
{% for language in languages %}
|
||||||
|
<option value="{{ language.code }}"{% if LANGUAGE_CODE = language.code %} selected{% endif %}>{{ language.name_local }} ({{ language.code }})</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="Go" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -1,6 +1,7 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_VIEW_A_TICKET_PUBLIC %}
|
||||||
<h2>{% trans "View a Ticket" %}</h2>
|
<h2>{% trans "View a Ticket" %}</h2>
|
||||||
|
|
||||||
<form method='get' action='{% url helpdesk_public_view %}'>
|
<form method='get' action='{% url helpdesk_public_view %}'>
|
||||||
@ -16,7 +17,9 @@
|
|||||||
<input type='submit' value='{% trans "View Ticket" %}' />
|
<input type='submit' value='{% trans "View Ticket" %}' />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{% csrf_token %}</form>
|
{% csrf_token %}</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||||
<h2 name='submit'>{% trans "Submit a Ticket" %}</h2>
|
<h2 name='submit'>{% trans "Submit a Ticket" %}</h2>
|
||||||
|
|
||||||
<p>{% trans "All fields are required. Please provide as descriptive a title and description as possible." %}</p>
|
<p>{% trans "All fields are required. Please provide as descriptive a title and description as possible." %}</p>
|
||||||
@ -42,4 +45,10 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{% csrf_token %}</form>
|
{% csrf_token %}</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not helpdesk_settings.HELPDESK_VIEW_A_TICKET_PUBLIC and not helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||||
|
<h2>{% trans "Please use button at upper right to login first." %}</h2>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||||
{% block helpdesk_title %}{% trans "Helpdesk Login" %}{% endblock %}
|
{% block helpdesk_title %}{{ helpdesk_settings.HELPDESK_PREPEND_ORG_NAME|default:'' }} {% trans "Helpdesk Login" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
<h2>{% trans "Login" %}</h2>
|
|
||||||
|
|
||||||
<p>{% trans "To log in and begin responding to cases, simply enter your username and password below." %}</p>
|
{% if request.user.is_authenticated %}
|
||||||
|
<meta http-equiv="REFRESH" content="0;url={% url helpdesk_home %}">
|
||||||
|
{% else %}
|
||||||
|
<h2>{% trans "Login" %}</h2>
|
||||||
|
|
||||||
<form method='post' action='./'>
|
<p>{% trans "To log in and begin responding to cases, simply enter your username and password below." %}</p>
|
||||||
{% if form.errors %}<p>{% trans "Your username and password didn't match. Please try again." %}</p>{% endif %}
|
|
||||||
<dl>
|
<form method='post' action='./'>
|
||||||
<dt><label>{% trans "Username" %}</label></dt>
|
{% if form.errors %}<p>{% trans "Your username and password didn't match. Please try again." %}</p>{% endif %}
|
||||||
<dd>{{ form.username }}</dd>
|
<dl>
|
||||||
<dt><label>{% trans "Password" %}</label></dt>
|
<dt><label>{% trans "Username" %}</label></dt>
|
||||||
<dd>{{ form.password }}</dd>
|
<dd>{{ form.username }}</dd>
|
||||||
</dl>
|
<dt><label>{% trans "Password" %}</label></dt>
|
||||||
<input type='submit' value='{% trans "Login" %}' />
|
<dd>{{ form.password }}</dd>
|
||||||
<input type="hidden" name="next" value="{% if next %}{{ next }}{% else %}../{% endif %}" />
|
</dl>
|
||||||
{% csrf_token %}</form>
|
<input type='submit' value='{% trans "Login" %}' />
|
||||||
|
<input type="hidden" name="next" value="{% if next %}{{ next }}{% else %}../{% endif %}" />
|
||||||
|
{% csrf_token %}</form>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -41,6 +41,22 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}
|
{% block helpdesk_body %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_TRANSLATE_TICKET_COMMENTS %}
|
||||||
|
{% comment %}
|
||||||
|
<div id='translate_dropdown'>{% trans "Translate ticket comments into" %} </div>
|
||||||
|
<div id='translate_block'>
|
||||||
|
{% endcomment %}
|
||||||
|
<div id="google_translate_element"></div><script>
|
||||||
|
function googleTranslateElementInit() {
|
||||||
|
new google.translate.TranslateElement({
|
||||||
|
pageLanguage: 'auto',
|
||||||
|
includedLanguages: 'en,fr,de,ru',
|
||||||
|
autoDisplay: false,
|
||||||
|
layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL
|
||||||
|
}, 'google_translate_element');
|
||||||
|
}
|
||||||
|
</script><script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% include "helpdesk/ticket_desc_table.html" %}
|
{% include "helpdesk/ticket_desc_table.html" %}
|
||||||
|
|
||||||
@ -48,11 +64,28 @@
|
|||||||
<h3>{% trans "Follow-Ups" %}</h3>
|
<h3>{% trans "Follow-Ups" %}</h3>
|
||||||
{% load ticket_to_link %}
|
{% load ticket_to_link %}
|
||||||
{% for followup in ticket.followup_set.all %}
|
{% for followup in ticket.followup_set.all %}
|
||||||
<div class='followup'>
|
{% if helpdesk_settings.HELPDESK_FOLLOWUP_MOD %}
|
||||||
<div class='title'>
|
<div class='followup_mod'>
|
||||||
{{ followup.title }} <span class='byline'>{% if followup.user %}by {{ followup.user }}{% endif %} <span title='{{ followup.date|date:"r" }}'>{{ followup.date|timesince }} ago</span>{% if not followup.public %} <span class='private'>({% trans "Private" %})</span>{% endif %}</span>
|
<div class='title'>
|
||||||
<a href="{% url helpdesk_followup_edit ticket.id followup.id %}" class='followup-edit'><img width="60" height="15" title="Edit" alt="Edit" src="{{ STATIC_URL }}helpdesk/buttons/edit.png"></a>
|
<span class='byline'>{{ followup.user.get_full_name }} {{ followup.date }} ({{ followup.date|timesince }} ago)</span> <small>{{ followup.title }}</small>
|
||||||
</div>
|
{% if not followup.public %} <span class='private'>({% trans "Private" %})</span>{% endif %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP %}
|
||||||
|
{% if followup.user and request.user == followup.user and not followup.ticketchange_set.all %}
|
||||||
|
<a href="{% url helpdesk_followup_edit ticket.id followup.id %}" class='followup-edit'><img width="60" height="15" title="Edit" alt="Edit" src="{{ STATIC_URL }}helpdesk/buttons/edit.png"></a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class='followup'>
|
||||||
|
<div class='title'>
|
||||||
|
{{ followup.title }} <span class='byline'>{% if followup.user %}by {{ followup.user }}{% endif %} <span title='{{ followup.date|date:"r" }}'>{{ followup.date|timesince }} ago</span>{% if not followup.public %} <span class='private'>({% trans "Private" %})</span>{% endif %}</span>
|
||||||
|
{% if helpdesk_settings.HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP %}
|
||||||
|
{% if followup.user and request.user == followup.user and not followup.ticketchange_set.all %}
|
||||||
|
<a href="{% url helpdesk_followup_edit ticket.id followup.id %}" class='followup-edit'><img width="60" height="15" title="Edit" alt="Edit" src="{{ STATIC_URL }}helpdesk/buttons/edit.png"></a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<span class='followup-desc'>{% if followup.comment %}{{ followup.comment|force_escape|urlizetrunc:50|num_to_link|linebreaksbr }}{% endif %}</span>
|
<span class='followup-desc'>{% if followup.comment %}{{ followup.comment|force_escape|urlizetrunc:50|num_to_link|linebreaksbr }}{% endif %}</span>
|
||||||
{% for change in followup.ticketchange_set.all %}
|
{% for change in followup.ticketchange_set.all %}
|
||||||
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
||||||
@ -60,12 +93,19 @@
|
|||||||
{% if forloop.last %}</div></ul>{% endif %}
|
{% if forloop.last %}</div></ul>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
||||||
<li><a href='{{ attachment.file.url }}'>{{ attachment.filename }}</a> ({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})</li>
|
<li><a href='{{ attachment.file.url }}'>{{ attachment.filename }}</a> ({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})
|
||||||
|
{% if followup.user and request.user == followup.user %}
|
||||||
|
<a href='{% url helpdesk_attachment_del ticket.id attachment.id %}'>delete</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
{% if forloop.last %}</ul></div>{% endif %}
|
{% if forloop.last %}</ul></div>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_TRANSLATE_TICKET_COMMENTS %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<h3>{% trans "Respond to this ticket" %}</h3>
|
<h3>{% trans "Respond to this ticket" %}</h3>
|
||||||
|
|
||||||
@ -73,9 +113,11 @@
|
|||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<dl>
|
<dl>
|
||||||
|
{% if preset_replies %}
|
||||||
<dt><label for='id_preset'>{% trans "Use a Pre-set Reply" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_preset'>{% trans "Use a Pre-set Reply" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||||
<dd><select name='preset' id='id_preset'><option value=''>------</option>{% for preset in preset_replies %}<option value='{{ preset.id }}'>{{ preset.name }}</option>{% endfor %}</select></dd>
|
<dd><select name='preset' id='id_preset'><option value=''>------</option>{% for preset in preset_replies %}<option value='{{ preset.id }}'>{{ preset.name }}</option>{% endfor %}</select></dd>
|
||||||
<dd class='form_help_text'>{% trans "Selecting a pre-set reply will over-write your comment below. You can then modify the pre-set reply to your liking before saving this update." %}</dd>
|
<dd class='form_help_text'>{% trans "Selecting a pre-set reply will over-write your comment below. You can then modify the pre-set reply to your liking before saving this update." %}</dd>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<dt><label for='commentBox'>{% trans "Comment / Resolution" %}</label></dt>
|
<dt><label for='commentBox'>{% trans "Comment / Resolution" %}</label></dt>
|
||||||
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
||||||
@ -109,9 +151,13 @@
|
|||||||
<input type='radio' name='new_status' value='5' id='st_duplicate' checked='checked'><label for='st_duplicate'>{% trans "Duplicate" %}</label></dd>
|
<input type='radio' name='new_status' value='5' id='st_duplicate' checked='checked'><label for='st_duplicate'>{% trans "Duplicate" %}</label></dd>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
|
||||||
|
{% if helpdesk_settings.HELPDESK_UPDATE_PUBLIC_DEFAULT %}
|
||||||
|
<input type='hidden' name='public' value='1'>
|
||||||
|
{% else %}
|
||||||
<dt><label for='id_public'>{% trans "Is this update public?" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
<dt><label for='id_public'>{% trans "Is this update public?" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||||
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dD>
|
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dd>
|
||||||
<dd class='form_help_text'>{% trans "If this is public, the submitter will be e-mailed your comment or resolution." %}</dd>
|
<dd class='form_help_text'>{% trans "If this is public, the submitter will be e-mailed your comment or resolution." %}</dd>
|
||||||
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p id='ShowFurtherOptPara'><a href='#' id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</a></p>
|
<p id='ShowFurtherOptPara'><a href='#' id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</a></p>
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}] <span class='ticket_toolbar'><a class="ticket-edit" href='{% url helpdesk_edit ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a><a class="ticket-delete" href='{% url helpdesk_delete ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>{% if ticket.on_hold %}<a class="ticket-hold" href='unhold/'>{% trans "Unhold" %}</a>{% else %}<a class="ticket-hold" href='hold/'>{% trans "Hold" %}</a>{% endif %}</span></td></tr>
|
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}] <span class='ticket_toolbar'>
|
||||||
|
{% if helpdesk_settings.HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP %}
|
||||||
|
<a href='{% url helpdesk_edit ticket.id %}' class="ticket-edit"><img src='{{ STATIC_URL }}helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a>
|
||||||
|
{% endif %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP %}
|
||||||
|
<a href='{% url helpdesk_delete ticket.id %}' class="ticket-delete"><img src='{{ STATIC_URL }}helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>
|
||||||
|
{% endif %}
|
||||||
|
{% if helpdesk_settings.HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP %}
|
||||||
|
{% if ticket.on_hold %}<a href='unhold/' class="ticket-hold">{% trans "Unhold" %}</a>{% else %}<a href='hold/' class="ticket-hold">{% trans "Hold" %}</a>{% endif %}
|
||||||
|
{% endif %}</span></td></tr>
|
||||||
<tr class='row_columnheads'><th colspan='2'>{% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}</th></tr>
|
<tr class='row_columnheads'><th colspan='2'>{% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}</th></tr>
|
||||||
|
|
||||||
<tr class='{% cycle 'row_odd' 'row_even' as rowcolors %}'>
|
<tr class='{% cycle 'row_odd' 'row_even' as rowcolors %}'>
|
||||||
@ -25,7 +34,7 @@
|
|||||||
|
|
||||||
<tr class='{% cycle rowcolors %}'>
|
<tr class='{% cycle rowcolors %}'>
|
||||||
<th>{% trans "Copies To" %}</th>
|
<th>{% trans "Copies To" %}</th>
|
||||||
<td>{% for ticketcc in ticket.ticketcc_set.all %}{{ ticketcc.display }}{% if not forloop.last %}, {% endif %}{% endfor %} <strong><a href='{% url helpdesk_ticket_cc ticket.id %}'>{% trans "Manage" %}</a></strong></td>
|
<td>{% for ticketcc in ticket.ticketcc_set.all %}{{ ticketcc.display }}{% if not forloop.last %}, {% endif %}{% endfor %} <strong><a class='tooltip' href='{% url helpdesk_ticket_cc ticket.id %}'>{% trans "Manage" %}<span>{% trans "Click here to add / remove people who should receive an e-mail whenever this ticket is updated." %}</span></a></strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% if tags_enabled %}
|
{% if tags_enabled %}
|
||||||
@ -44,7 +53,7 @@
|
|||||||
{% empty %}
|
{% empty %}
|
||||||
<p>{% trans "This ticket has no dependencies." %}</p>
|
<p>{% trans "This ticket has no dependencies." %}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<p><a href='{% url helpdesk_ticket_dependency_add ticket.id %}'>{% trans "Add Dependency" %}</a></p>
|
<p><a class='tooltip' href='{% url helpdesk_ticket_dependency_add ticket.id %}'>{% trans "Add Dependency" %}<span>{% trans "Click on 'Add Dependency', if you want to make this ticket dependent on another ticket. A ticket may not be closed until all tickets it depends on are closed." %}</span></a></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -2,10 +2,20 @@
|
|||||||
|
|
||||||
{% block helpdesk_title %}{% trans "Change User Settings" %}{% endblock %}
|
{% block helpdesk_title %}{% trans "Change User Settings" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_body %}{% blocktrans %}
|
{% block helpdesk_body %}
|
||||||
|
{% if show_password_change_link %}
|
||||||
|
{% url auth_password_change as password_change_url %}
|
||||||
|
<h2>Change Password</h2>
|
||||||
|
<p>
|
||||||
|
Change your password <a href="{{ password_change_url }}" title="change your password">here</a>.
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% blocktrans %}
|
||||||
<h2>User Settings</h2>
|
<h2>User Settings</h2>
|
||||||
|
|
||||||
<p>Use the following options to change the way your helpdesk system works for you. These settings do not impact any other user.</p>{% endblocktrans %}
|
<p>Use the following options to change the way your helpdesk system works for you. These settings do not impact any other user.</p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
<form method='post' action='./'>
|
<form method='post' action='./'>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
21
helpdesk/templatetags/load_helpdesk_settings.py
Normal file
21
helpdesk/templatetags/load_helpdesk_settings.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
"""
|
||||||
|
django-helpdesk - A Django powered ticket tracker for small enterprise.
|
||||||
|
|
||||||
|
templatetags/load_helpdesk_settings.py - returns the settings as defined in
|
||||||
|
django-helpdesk/helpdesk/settings.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.template import Library
|
||||||
|
from helpdesk import settings as helpdesk_settings_config
|
||||||
|
|
||||||
|
def load_helpdesk_settings(request):
|
||||||
|
try:
|
||||||
|
return helpdesk_settings_config
|
||||||
|
except Exception, e:
|
||||||
|
import sys
|
||||||
|
print >> sys.stderr, "'load_helpdesk_settings' template tag (django-helpdesk) crashed with following error:"
|
||||||
|
print >> sys.stderr, e
|
||||||
|
return ''
|
||||||
|
|
||||||
|
register = Library()
|
||||||
|
register.filter('load_helpdesk_settings', load_helpdesk_settings)
|
@ -81,6 +81,10 @@ urlpatterns = patterns('helpdesk.views.staff',
|
|||||||
'ticket_dependency_del',
|
'ticket_dependency_del',
|
||||||
name='helpdesk_ticket_dependency_del'),
|
name='helpdesk_ticket_dependency_del'),
|
||||||
|
|
||||||
|
url(r'^tickets/(?P<ticket_id>[0-9]+)/attachment_delete/(?P<attachment_id>[0-9]+)/$',
|
||||||
|
'attachment_del',
|
||||||
|
name='helpdesk_attachment_del'),
|
||||||
|
|
||||||
url(r'^raw/(?P<type>\w+)/$',
|
url(r'^raw/(?P<type>\w+)/$',
|
||||||
'raw_details',
|
'raw_details',
|
||||||
name='helpdesk_raw'),
|
name='helpdesk_raw'),
|
||||||
@ -130,6 +134,10 @@ urlpatterns += patterns('helpdesk.views.public',
|
|||||||
url(r'^view/$',
|
url(r'^view/$',
|
||||||
'view_ticket',
|
'view_ticket',
|
||||||
name='helpdesk_public_view'),
|
name='helpdesk_public_view'),
|
||||||
|
|
||||||
|
url(r'^change_language/$',
|
||||||
|
'change_language',
|
||||||
|
name='helpdesk_public_change_language'),
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns += patterns('',
|
urlpatterns += patterns('',
|
||||||
|
@ -22,7 +22,10 @@ from helpdesk.models import Ticket, Queue, UserSettings
|
|||||||
|
|
||||||
|
|
||||||
def homepage(request):
|
def homepage(request):
|
||||||
if request.user.is_staff:
|
if not request.user.is_authenticated() and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT:
|
||||||
|
return HttpResponseRedirect(reverse('login'))
|
||||||
|
|
||||||
|
if (request.user.is_staff or (request.user.is_authenticated() and helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE)):
|
||||||
try:
|
try:
|
||||||
if getattr(request.user.usersettings.settings, 'login_view_ticketlist', False):
|
if getattr(request.user.usersettings.settings, 'login_view_ticketlist', False):
|
||||||
return HttpResponseRedirect(reverse('helpdesk_list'))
|
return HttpResponseRedirect(reverse('helpdesk_list'))
|
||||||
@ -108,10 +111,16 @@ def view_ticket(request):
|
|||||||
|
|
||||||
return update_ticket(request, ticket_id, public=True)
|
return update_ticket(request, ticket_id, public=True)
|
||||||
|
|
||||||
|
# redirect user back to this ticket if possible.
|
||||||
|
redirect_url = ''
|
||||||
|
if helpdesk_settings.HELPDESK_NAVIGATION_ENABLED:
|
||||||
|
redirect_url = reverse('helpdesk_view', args=[ticket_id])
|
||||||
|
|
||||||
return render_to_response('helpdesk/public_view_ticket.html',
|
return render_to_response('helpdesk/public_view_ticket.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
'ticket': ticket,
|
'ticket': ticket,
|
||||||
'helpdesk_settings': helpdesk_settings,
|
'helpdesk_settings': helpdesk_settings,
|
||||||
|
'next': redirect_url,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return render_to_response('helpdesk/public_view_form.html',
|
return render_to_response('helpdesk/public_view_form.html',
|
||||||
@ -122,3 +131,10 @@ def view_ticket(request):
|
|||||||
'helpdesk_settings': helpdesk_settings,
|
'helpdesk_settings': helpdesk_settings,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
def change_language(request):
|
||||||
|
return_to = ''
|
||||||
|
if request.GET.has_key('return_to'):
|
||||||
|
return_to = request.GET['return_to']
|
||||||
|
|
||||||
|
return render_to_response('helpdesk/public_change_language.html',
|
||||||
|
RequestContext(request, {'next': return_to}))
|
||||||
|
@ -23,19 +23,26 @@ from django.shortcuts import render_to_response, get_object_or_404
|
|||||||
from django.template import loader, Context, RequestContext
|
from django.template import loader, Context, RequestContext
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
|
from django import forms
|
||||||
|
|
||||||
from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm, EditFollowUpForm, TicketDependencyForm
|
from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm, EditFollowUpForm, TicketDependencyForm
|
||||||
from helpdesk.lib import send_templated_mail, query_to_dict, apply_query, safe_template_context
|
from helpdesk.lib import send_templated_mail, query_to_dict, apply_query, safe_template_context
|
||||||
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC, TicketDependency
|
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC, TicketDependency
|
||||||
from helpdesk.settings import HAS_TAG_SUPPORT
|
from helpdesk.settings import HAS_TAG_SUPPORT
|
||||||
|
from helpdesk import settings as helpdesk_settings
|
||||||
|
|
||||||
if HAS_TAG_SUPPORT:
|
if HAS_TAG_SUPPORT:
|
||||||
from tagging.models import Tag, TaggedItem
|
from tagging.models import Tag, TaggedItem
|
||||||
|
|
||||||
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_staff)
|
if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||||
superuser_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_superuser)
|
# treat 'normal' users like 'staff'
|
||||||
|
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active)
|
||||||
|
else:
|
||||||
|
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_staff)
|
||||||
|
|
||||||
|
|
||||||
|
superuser_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_superuser)
|
||||||
|
|
||||||
|
|
||||||
def dashboard(request):
|
def dashboard(request):
|
||||||
"""
|
"""
|
||||||
@ -44,18 +51,33 @@ def dashboard(request):
|
|||||||
with options for them to 'Take' ownership of said tickets.
|
with options for them to 'Take' ownership of said tickets.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# open & reopened tickets, assigned to current user
|
||||||
tickets = Ticket.objects.filter(
|
tickets = Ticket.objects.filter(
|
||||||
assigned_to=request.user,
|
assigned_to=request.user,
|
||||||
).exclude(
|
).exclude(
|
||||||
status=Ticket.CLOSED_STATUS,
|
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# closed & resolved tickets, assigned to current user
|
||||||
|
tickets_closed_resolved = Ticket.objects.filter(
|
||||||
|
assigned_to=request.user,
|
||||||
|
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS])
|
||||||
|
|
||||||
unassigned_tickets = Ticket.objects.filter(
|
unassigned_tickets = Ticket.objects.filter(
|
||||||
assigned_to__isnull=True,
|
assigned_to__isnull=True,
|
||||||
).exclude(
|
).exclude(
|
||||||
status=Ticket.CLOSED_STATUS,
|
status=Ticket.CLOSED_STATUS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# all tickets, reported by current user
|
||||||
|
all_tickets_reported_by_current_user = ''
|
||||||
|
email_current_user = request.user.email
|
||||||
|
if email_current_user:
|
||||||
|
all_tickets_reported_by_current_user = Ticket.objects.filter(
|
||||||
|
submitter_email=email_current_user,
|
||||||
|
).order_by('status')
|
||||||
|
|
||||||
|
|
||||||
# The following query builds a grid of queues & ticket statuses,
|
# The following query builds a grid of queues & ticket statuses,
|
||||||
# to be displayed to the user. EG:
|
# to be displayed to the user. EG:
|
||||||
# Open Resolved
|
# Open Resolved
|
||||||
@ -63,23 +85,42 @@ def dashboard(request):
|
|||||||
# Queue 2 4 12
|
# Queue 2 4 12
|
||||||
|
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
cursor.execute("""
|
if helpdesk_settings.HELPDESK_DASHBOARD_HIDE_EMPTY_QUEUES:
|
||||||
SELECT q.id as queue,
|
cursor.execute("""
|
||||||
q.title AS name,
|
SELECT q.id as queue,
|
||||||
COUNT(CASE t.status WHEN '1' THEN t.id WHEN '2' THEN t.id END) AS open,
|
q.title AS name,
|
||||||
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved
|
COUNT(CASE t.status WHEN '1' THEN t.id WHEN '2' THEN t.id END) AS open,
|
||||||
FROM helpdesk_ticket t,
|
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved,
|
||||||
helpdesk_queue q
|
COUNT(CASE t.status WHEN '4' THEN t.id END) AS closed
|
||||||
WHERE q.id = t.queue_id
|
FROM helpdesk_ticket t,
|
||||||
GROUP BY queue, name
|
helpdesk_queue q
|
||||||
ORDER BY q.id;
|
WHERE q.id = t.queue_id
|
||||||
""")
|
GROUP BY queue, name
|
||||||
|
ORDER BY q.id;
|
||||||
|
""")
|
||||||
|
else:
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT q.id as queue,
|
||||||
|
q.title AS name,
|
||||||
|
COUNT(CASE t.status WHEN '1' THEN t.id WHEN '2' THEN t.id END) AS open,
|
||||||
|
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved,
|
||||||
|
COUNT(CASE t.status WHEN '4' THEN t.id END) AS closed
|
||||||
|
FROM helpdesk_queue q
|
||||||
|
LEFT OUTER JOIN helpdesk_ticket t
|
||||||
|
ON q.id = t.queue_id
|
||||||
|
GROUP BY queue, name
|
||||||
|
ORDER BY q.id;
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
||||||
|
|
||||||
return render_to_response('helpdesk/dashboard.html',
|
return render_to_response('helpdesk/dashboard.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
'user_tickets': tickets,
|
'user_tickets': tickets,
|
||||||
|
'user_tickets_closed_resolved': tickets_closed_resolved,
|
||||||
'unassigned_tickets': unassigned_tickets,
|
'unassigned_tickets': unassigned_tickets,
|
||||||
|
'all_tickets_reported_by_current_user': all_tickets_reported_by_current_user,
|
||||||
'dash_tickets': dash_tickets,
|
'dash_tickets': dash_tickets,
|
||||||
}))
|
}))
|
||||||
dashboard = staff_member_required(dashboard)
|
dashboard = staff_member_required(dashboard)
|
||||||
@ -127,9 +168,18 @@ def followup_edit(request, ticket_id, followup_id, ):
|
|||||||
new_status = form.cleaned_data['new_status']
|
new_status = form.cleaned_data['new_status']
|
||||||
#will save previous date
|
#will save previous date
|
||||||
old_date = followup.date
|
old_date = followup.date
|
||||||
followup.delete()
|
|
||||||
new_followup = FollowUp(title=title, date=old_date, ticket=_ticket, comment=comment, public=public, new_status=new_status, )
|
new_followup = FollowUp(title=title, date=old_date, ticket=_ticket, comment=comment, public=public, new_status=new_status, )
|
||||||
|
# keep old user if one did exist before.
|
||||||
|
if followup.user:
|
||||||
|
new_followup.user = followup.user
|
||||||
new_followup.save()
|
new_followup.save()
|
||||||
|
# get list of old attachments & link them to new_followup
|
||||||
|
attachments = Attachment.objects.filter(followup = followup)
|
||||||
|
for attachment in attachments:
|
||||||
|
attachment.followup = new_followup
|
||||||
|
attachment.save()
|
||||||
|
# delete old followup
|
||||||
|
followup.delete()
|
||||||
return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket.id]))
|
return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket.id]))
|
||||||
|
|
||||||
def view_ticket(request, ticket_id):
|
def view_ticket(request, ticket_id):
|
||||||
@ -169,7 +219,7 @@ def view_ticket(request, ticket_id):
|
|||||||
return render_to_response('helpdesk/ticket.html',
|
return render_to_response('helpdesk/ticket.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
'ticket': ticket,
|
'ticket': ticket,
|
||||||
'active_users': User.objects.filter(is_active=True).filter(is_staff=True).order_by('username'),
|
'active_users': User.objects.filter(is_active=True).order_by('username'),
|
||||||
'priorities': Ticket.PRIORITY_CHOICES,
|
'priorities': Ticket.PRIORITY_CHOICES,
|
||||||
'preset_replies': PreSetReply.objects.filter(Q(queues=ticket.queue) | Q(queues__isnull=True)),
|
'preset_replies': PreSetReply.objects.filter(Q(queues=ticket.queue) | Q(queues__isnull=True)),
|
||||||
'tags_enabled': HAS_TAG_SUPPORT,
|
'tags_enabled': HAS_TAG_SUPPORT,
|
||||||
@ -178,7 +228,7 @@ view_ticket = staff_member_required(view_ticket)
|
|||||||
|
|
||||||
|
|
||||||
def update_ticket(request, ticket_id, public=False):
|
def update_ticket(request, ticket_id, public=False):
|
||||||
if not (public or (request.user.is_authenticated() and request.user.is_active and request.user.is_staff)):
|
if not (public or (request.user.is_authenticated() and request.user.is_active and (request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE))):
|
||||||
return HttpResponseForbidden(_('Sorry, you need to login to do that.'))
|
return HttpResponseForbidden(_('Sorry, you need to login to do that.'))
|
||||||
|
|
||||||
ticket = get_object_or_404(Ticket, id=ticket_id)
|
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||||
@ -195,6 +245,10 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
# comment.
|
# comment.
|
||||||
from django.template import loader, Context
|
from django.template import loader, Context
|
||||||
context = safe_template_context(ticket)
|
context = safe_template_context(ticket)
|
||||||
|
# this line sometimes creates problems if code is sent as a comment.
|
||||||
|
# if comment contains some django code, like "why does {% if bla %} crash",
|
||||||
|
# then the following line will give us a crash, since django expects {% if %}
|
||||||
|
# to be closed with an {% endif %} tag.
|
||||||
comment = loader.get_template_from_string(comment).render(Context(context))
|
comment = loader.get_template_from_string(comment).render(Context(context))
|
||||||
|
|
||||||
if owner is None and ticket.assigned_to:
|
if owner is None and ticket.assigned_to:
|
||||||
@ -202,7 +256,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
|
|
||||||
f = FollowUp(ticket=ticket, date=datetime.now(), comment=comment)
|
f = FollowUp(ticket=ticket, date=datetime.now(), comment=comment)
|
||||||
|
|
||||||
if request.user.is_staff:
|
if request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||||
f.user = request.user
|
f.user = request.user
|
||||||
|
|
||||||
f.public = public
|
f.public = public
|
||||||
@ -217,6 +271,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
}
|
}
|
||||||
ticket.assigned_to = new_user
|
ticket.assigned_to = new_user
|
||||||
reassigned = True
|
reassigned = True
|
||||||
|
# user changed owner to 'unassign'
|
||||||
elif owner == 0 and ticket.assigned_to is not None:
|
elif owner == 0 and ticket.assigned_to is not None:
|
||||||
f.title = _('Unassigned')
|
f.title = _('Unassigned')
|
||||||
ticket.assigned_to = None
|
ticket.assigned_to = None
|
||||||
@ -289,7 +344,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
c.save()
|
c.save()
|
||||||
ticket.tags = tags
|
ticket.tags = tags
|
||||||
|
|
||||||
if f.new_status == Ticket.RESOLVED_STATUS:
|
if new_status == Ticket.RESOLVED_STATUS:
|
||||||
ticket.resolution = comment
|
ticket.resolution = comment
|
||||||
|
|
||||||
messages_sent_to = []
|
messages_sent_to = []
|
||||||
@ -377,7 +432,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
|
|
||||||
ticket.save()
|
ticket.save()
|
||||||
|
|
||||||
if request.user.is_staff:
|
if request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||||
return HttpResponseRedirect(ticket.get_absolute_url())
|
return HttpResponseRedirect(ticket.get_absolute_url())
|
||||||
else:
|
else:
|
||||||
return HttpResponseRedirect(ticket.ticket_url)
|
return HttpResponseRedirect(ticket.ticket_url)
|
||||||
@ -421,7 +476,8 @@ def mass_update(request):
|
|||||||
# Send email to Submitter, Owner, Queue CC
|
# Send email to Submitter, Owner, Queue CC
|
||||||
context = safe_template_context(t)
|
context = safe_template_context(t)
|
||||||
context.update(
|
context.update(
|
||||||
resolution=t.resolution,
|
resolution = t.resolution,
|
||||||
|
queue = t.queue,
|
||||||
)
|
)
|
||||||
|
|
||||||
messages_sent_to = []
|
messages_sent_to = []
|
||||||
@ -694,6 +750,8 @@ def create_ticket(request):
|
|||||||
form = TicketForm(initial=initial_data)
|
form = TicketForm(initial=initial_data)
|
||||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
||||||
form.fields['assigned_to'].choices = [('', '--------')] + [[u.id, u.username] for u in User.objects.filter(is_active=True).order_by('username')]
|
form.fields['assigned_to'].choices = [('', '--------')] + [[u.id, u.username] for u in User.objects.filter(is_active=True).order_by('username')]
|
||||||
|
if helpdesk_settings.HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO:
|
||||||
|
form.fields['assigned_to'].widget = forms.HiddenInput()
|
||||||
|
|
||||||
return render_to_response('helpdesk/create_ticket.html',
|
return render_to_response('helpdesk/create_ticket.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
@ -823,7 +881,7 @@ def run_report(request, report):
|
|||||||
periods = []
|
periods = []
|
||||||
year, month = first_year, first_month
|
year, month = first_year, first_month
|
||||||
working = True
|
working = True
|
||||||
periods.append("%s %s" % (months[month], year))
|
periods.append("%s %s" % (months[month - 1], year))
|
||||||
|
|
||||||
while working:
|
while working:
|
||||||
month += 1
|
month += 1
|
||||||
@ -893,7 +951,7 @@ def run_report(request, report):
|
|||||||
|
|
||||||
elif report == 'usermonth':
|
elif report == 'usermonth':
|
||||||
metric1 = u'%s' % ticket.get_assigned_to
|
metric1 = u'%s' % ticket.get_assigned_to
|
||||||
metric2 = u'%s %s' % (months[ticket.created.month], ticket.created.year)
|
metric2 = u'%s %s' % (months[ticket.created.month - 1], ticket.created.year)
|
||||||
|
|
||||||
elif report == 'queuepriority':
|
elif report == 'queuepriority':
|
||||||
metric1 = u'%s' % ticket.queue.title
|
metric1 = u'%s' % ticket.queue.title
|
||||||
@ -905,7 +963,7 @@ def run_report(request, report):
|
|||||||
|
|
||||||
elif report == 'queuemonth':
|
elif report == 'queuemonth':
|
||||||
metric1 = u'%s' % ticket.queue.title
|
metric1 = u'%s' % ticket.queue.title
|
||||||
metric2 = u'%s %s' % (months[ticket.created.month], ticket.created.year)
|
metric2 = u'%s %s' % (months[ticket.created.month - 1], ticket.created.year)
|
||||||
|
|
||||||
summarytable[metric1, metric2] += 1
|
summarytable[metric1, metric2] += 1
|
||||||
|
|
||||||
@ -974,9 +1032,16 @@ def user_settings(request):
|
|||||||
else:
|
else:
|
||||||
form = UserSettingsForm(s.settings)
|
form = UserSettingsForm(s.settings)
|
||||||
|
|
||||||
|
user = User.objects.get(id = request.user.id)
|
||||||
|
show_password_change_link = 0
|
||||||
|
# we don't want non-local users to see the 'change password' link.
|
||||||
|
if helpdesk_settings.HELPDESK_SHOW_CHANGE_PASSWORD and user.has_usable_password():
|
||||||
|
show_password_change_link = 1
|
||||||
|
|
||||||
return render_to_response('helpdesk/user_settings.html',
|
return render_to_response('helpdesk/user_settings.html',
|
||||||
RequestContext(request, {
|
RequestContext(request, {
|
||||||
'form': form,
|
'form': form,
|
||||||
|
'show_password_change_link': show_password_change_link,
|
||||||
}))
|
}))
|
||||||
user_settings = staff_member_required(user_settings)
|
user_settings = staff_member_required(user_settings)
|
||||||
|
|
||||||
@ -1086,3 +1151,10 @@ def ticket_dependency_del(request, ticket_id, dependency_id):
|
|||||||
}))
|
}))
|
||||||
ticket_dependency_del = staff_member_required(ticket_dependency_del)
|
ticket_dependency_del = staff_member_required(ticket_dependency_del)
|
||||||
|
|
||||||
|
def attachment_del(request, ticket_id, attachment_id):
|
||||||
|
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||||
|
attachment = get_object_or_404(Attachment, id=attachment_id)
|
||||||
|
attachment.delete()
|
||||||
|
return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket_id]))
|
||||||
|
attachment_del = staff_member_required(attachment_del)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user