forked from extern/django-helpdesk
* Updates to bring into line with django trunk
This commit is contained in:
parent
18a8814a85
commit
ad05df8dda
30
models.py
30
models.py
@ -25,7 +25,7 @@ class Queue(models.Model):
|
||||
TODO: Add e-mail inboxes (either using piped e-mail or IMAP/POP3) so we
|
||||
can automatically get tickets via e-mail.
|
||||
"""
|
||||
title = models.CharField(maxlength=100)
|
||||
title = models.CharField(max_length=100)
|
||||
slug = models.SlugField(help_text='This slug is used when building ticket ID\'s. Once set, try not to change it or e-mailing may get messy.')
|
||||
email_address = models.EmailField(blank=True, null=True, help_text='All outgoing e-mails for this queue will use this e-mail address. If you use IMAP or POP3, this shoul be the e-mail address for that mailbox.')
|
||||
escalate_days = models.IntegerField(blank=True, null=True, help_text='For tickets which are not held, how often do you wish to increase their priority? Set to 0 for no escalation.')
|
||||
@ -40,12 +40,12 @@ class Queue(models.Model):
|
||||
new_ticket_cc = models.EmailField(blank=True, null=True, help_text='If an e-mail address is entered here, then it will receive notification of all new tickets created for this queue')
|
||||
updated_ticket_cc = models.EmailField(blank=True, null=True, help_text='If an e-mail address is entered here, then it will receive notification of all activity (new tickets, closed tickets, updates, reassignments, etc) for this queue')
|
||||
|
||||
email_box_type = models.CharField(maxlength=5, choices=(('pop3', 'POP 3'),('imap', 'IMAP')), blank=True, null=True, help_text='E-Mail Server Type - Both POP3 and IMAP are supported. Select your email server type here.')
|
||||
email_box_host = models.CharField(maxlength=200, blank=True, null=True, help_text='Your e-mail server address - either the domain name or IP address. May be "localhost".')
|
||||
email_box_type = models.CharField(max_length=5, choices=(('pop3', 'POP 3'),('imap', 'IMAP')), blank=True, null=True, help_text='E-Mail Server Type - Both POP3 and IMAP are supported. Select your email server type here.')
|
||||
email_box_host = models.CharField(max_length=200, blank=True, null=True, help_text='Your e-mail server address - either the domain name or IP address. May be "localhost".')
|
||||
email_box_port = models.IntegerField(blank=True, null=True, help_text='Port number to use for accessing e-mail. Default for POP3 is "110", and for IMAP is "143". This may differ on some servers.')
|
||||
email_box_user = models.CharField(maxlength=200, blank=True, null=True, help_text='Username for accessing this mailbox.')
|
||||
email_box_pass = models.CharField(maxlength=200, blank=True, null=True, help_text='Password for the above username')
|
||||
email_box_imap_folder = models.CharField(maxlength=100, blank=True, null=True, help_text='If using IMAP, what folder do you wish to fetch messages from? This allows you to use one IMAP account for multiple queues, by filtering messages on your IMAP server into separate folders. Default: INBOX.')
|
||||
email_box_user = models.CharField(max_length=200, blank=True, null=True, help_text='Username for accessing this mailbox.')
|
||||
email_box_pass = models.CharField(max_length=200, blank=True, null=True, help_text='Password for the above username')
|
||||
email_box_imap_folder = models.CharField(max_length=100, blank=True, null=True, help_text='If using IMAP, what folder do you wish to fetch messages from? This allows you to use one IMAP account for multiple queues, by filtering messages on your IMAP server into separate folders. Default: INBOX.')
|
||||
email_box_interval = models.IntegerField(help_text='How often do you wish to check this mailbox? (in Minutes)', blank=True, null=True, default='5')
|
||||
email_box_last_check = models.DateTimeField(blank=True, null=True, editable=False) # Updated by the auto-pop3-and-imap-checker
|
||||
|
||||
@ -101,7 +101,7 @@ class Ticket(models.Model):
|
||||
(5, '5. Very Low'),
|
||||
)
|
||||
|
||||
title = models.CharField(maxlength=200)
|
||||
title = models.CharField(max_length=200)
|
||||
queue = models.ForeignKey(Queue)
|
||||
created = models.DateTimeField(blank=True)
|
||||
modified = models.DateTimeField(blank=True)
|
||||
@ -214,7 +214,7 @@ class FollowUp(models.Model):
|
||||
"""
|
||||
ticket = models.ForeignKey(Ticket)
|
||||
date = models.DateTimeField(auto_now_add=True)
|
||||
title = models.CharField(maxlength=200, blank=True, null=True)
|
||||
title = models.CharField(max_length=200, blank=True, null=True)
|
||||
comment = models.TextField(blank=True, null=True)
|
||||
public = models.BooleanField(blank=True, null=True)
|
||||
user = models.ForeignKey(User, blank=True, null=True)
|
||||
@ -247,7 +247,7 @@ class TicketChange(models.Model):
|
||||
etc) are tracked here for display purposes.
|
||||
"""
|
||||
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
||||
field = models.CharField(maxlength=100, core=True)
|
||||
field = models.CharField(max_length=100, core=True)
|
||||
old_value = models.TextField(blank=True, null=True, core=True)
|
||||
new_value = models.TextField(blank=True, null=True, core=True)
|
||||
|
||||
@ -291,8 +291,8 @@ class DynamicFileField(models.FileField):
|
||||
class Attachment(models.Model):
|
||||
followup = models.ForeignKey(FollowUp, edit_inline=models.TABULAR)
|
||||
file = DynamicFileField(upload_to='helpdesk/attachments', core=True)
|
||||
filename = models.CharField(maxlength=100)
|
||||
mime_type = models.CharField(maxlength=30)
|
||||
filename = models.CharField(max_length=100)
|
||||
mime_type = models.CharField(max_length=30)
|
||||
size = models.IntegerField(help_text='Size of this file in bytes')
|
||||
|
||||
def get_upload_to(self, field_attname):
|
||||
@ -332,7 +332,7 @@ class PreSetReply(models.Model):
|
||||
class EscalationExclusion(models.Model):
|
||||
queues = models.ManyToManyField(Queue, blank=True, null=True, help_text='Leave blank for this exclusion to be applied to all queues, or select those queues you wish to exclude with this entry.')
|
||||
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
date = models.DateField(help_text='Date on which escalation should not happen')
|
||||
|
||||
@ -348,10 +348,10 @@ class EmailTemplate(models.Model):
|
||||
them in the database.
|
||||
"""
|
||||
|
||||
template_name = models.CharField(maxlength=100, unique=True)
|
||||
template_name = models.CharField(max_length=100, unique=True)
|
||||
|
||||
subject = models.CharField(maxlength=100, help_text=u'This will be prefixed with "[ticket.ticket] ticket.title". We recommend something simple such as "(Updated") or "(Closed)" - the same context is available as in plain_text, below.')
|
||||
heading = models.CharField(maxlength=100, help_text=u'In HTML e-mails, this will be the heading at the top of the email - the same context is available as in plain_text, below.')
|
||||
subject = models.CharField(max_length=100, help_text=u'This will be prefixed with "[ticket.ticket] ticket.title". We recommend something simple such as "(Updated") or "(Closed)" - the same context is available as in plain_text, below.')
|
||||
heading = models.CharField(max_length=100, help_text=u'In HTML e-mails, this will be the heading at the top of the email - the same context is available as in plain_text, below.')
|
||||
plain_text = models.TextField(help_text=u'The context available to you includes {{ ticket }}, {{ queue }}, and depending on the time of the call: {{ resolution }} or {{ comment }}.')
|
||||
html = models.TextField(help_text=u'The same context is available here as in plain_text, above.')
|
||||
|
||||
|
@ -1,32 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block helpdesk_title %}Helpdesk{% endblock %}</title>
|
||||
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
||||
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='My Open Tickets' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "recent" %}' type='application/rss+xml' title='All Recent Activity' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='Unassigned Tickets' />
|
||||
{% block helpdesk_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id='container'>
|
||||
<div id='header'>
|
||||
<h1>Helpdesk</h1>
|
||||
<ul>
|
||||
<li><a href='{% url helpdesk_home %}'>Dashboard</a></li>
|
||||
<li><a href='{% url helpdesk_list %}'>Tickets</a></li>
|
||||
<li><a href='{% url helpdesk_submit %}'>New Ticket</a></li>
|
||||
<li><a href='{% url helpdesk_report_index %}'>Stats</a></li>
|
||||
<li><a href='{% url logout %}'>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='Search...' id='search_query' onFocus='s = document.getElementById("search_query");if (s.value == "Search...") { s.value = ""; }' /><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /></form></li>{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div id='body'>
|
||||
{% block helpdesk_body %}{% endblock %}
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>Powered by <a href='http://www.jutda.com.au/'>Jutda HelpDesk</a>. <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='RSS Feeds' border='0' />RSS Feeds</a> <a href='{% url helpdesk_api_help %}'>API</a></p>
|
||||
</div>
|
||||
</div>{% include "helpdesk/debug.html" %}
|
||||
</body>
|
||||
<!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">
|
||||
<head>
|
||||
<title>{% block helpdesk_title %}Helpdesk{% endblock %} Powered by Jutda Helpdesk</title>
|
||||
<script src='{{ MEDIA_URL }}/helpdesk/jquery.js' type='text/javascript' language='javascript'></script>
|
||||
<link rel='stylesheet' href='{{ MEDIA_URL }}/helpdesk/helpdesk.css' type='text/css' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "user" %}{{ user.username }}/' type='application/rss+xml' title='My Open Tickets' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "recent" %}' type='application/rss+xml' title='All Recent Activity' />
|
||||
<link rel='alternate' href='{% url helpdesk_rss "unassigned" %}' type='application/rss+xml' title='Unassigned Tickets' />
|
||||
{% block helpdesk_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id='container'>
|
||||
<div id='header'>
|
||||
<h1>Helpdesk</h1>
|
||||
<ul>
|
||||
<li><a href='{% url helpdesk_home %}'>Dashboard</a></li>
|
||||
<li><a href='{% url helpdesk_list %}'>Tickets</a></li>
|
||||
<li><a href='{% url helpdesk_submit %}'>New Ticket</a></li>
|
||||
<li><a href='{% url helpdesk_report_index %}'>Stats</a></li>
|
||||
<li><a href='{% url logout %}'>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='Search...' id='search_query' onFocus='s = document.getElementById("search_query");if (s.value == "Search...") { s.value = ""; }' /><input type='hidden' name='status' value='1' /><input type='hidden' name='status' value='2' /><input type='hidden' name='status' value='3' /></form></li>{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div id='body'>
|
||||
{% block helpdesk_body %}{% endblock %}
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>Powered by <a href='http://www.jutda.com.au/'>Jutda HelpDesk</a>. <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='RSS Icon' title='RSS Feeds' border='0' />RSS Feeds</a> <a href='{% url helpdesk_api_help %}'>API</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% include "helpdesk/debug.html" %}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,12 +1,14 @@
|
||||
{% extends "helpdesk/base.html" %}
|
||||
|
||||
{% block helpdesk_title %}Helpdesk{% endblock %}
|
||||
|
||||
{% block helpdesk_head %}
|
||||
<script src="http://media.jutda.com.au/helpdesk/nicEdit.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
nic = new nicEditor({buttonList: ['bold','italic','underline','strikeThrough','undo','redo','subscript','superscript','html']}).panelInstance('id_body');
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
@ -19,35 +21,29 @@
|
||||
<dl>
|
||||
<dt><label for='id_queue'>{{ form.queue.label }}</label></dt>
|
||||
<dd>{{ form.queue }}</dd>
|
||||
{% if form.queue.errors %}
|
||||
<dd class='error'>{{ form.queue.errors }}</dd>{% endif %}
|
||||
{% if form.queue.errors %}<dd class='error'>{{ form.queue.errors }}</dd>{% endif %}
|
||||
|
||||
<dt><label for='id_title'>{{ form.title.label }}</label></dt>
|
||||
<dd>{{ form.title }}</dd>
|
||||
{% if form.title.errors %}
|
||||
<dd class='error'>{{ form.title.errors }}</dd>{% endif %}
|
||||
{% if form.title.errors %}<dd class='error'>{{ form.title.errors }}</dd>{% endif %}
|
||||
|
||||
<dt><label for='id_submitter_email'>{{ form.submitter_email.label }}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||
<dd>{{ form.submitter_email }}</dd>
|
||||
{% if form.submitter_email.errors %}
|
||||
<dd class='error'>{{ form.submitter_email.errors }}</dd>{% endif %}
|
||||
{% if form.submitter_email.errors %}<dd class='error'>{{ form.submitter_email.errors }}</dd>{% endif %}
|
||||
<dd class='form_help_text'>{{ form.submitter_email.help_text }}</dd>
|
||||
|
||||
<dt><label for='id_body'>{{ form.body.label }}</label></dt>
|
||||
<dd>{{ form.body }}</dd>
|
||||
{% if form.body.errors %}
|
||||
<dd class='error'>{{ form.body.errors }}</dd>{% endif %}
|
||||
{% if form.body.errors %}<dd class='error'>{{ form.body.errors }}</dd>{% endif %}
|
||||
|
||||
<dt><label for='id_assigned_to'>{{ form.assigned_to.label }}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||
<dd>{{ form.assigned_to }}</dd>
|
||||
{% if form.assigned_to.errors %}
|
||||
<dd class='error'>{{ form.assigned_to.errors }}</dd>{% endif %}
|
||||
{% if form.assigned_to.errors %}<dd class='error'>{{ form.assigned_to.errors }}</dd>{% endif %}
|
||||
<dd class='form_help_text'>{{ form.assigned_to.help_text }}</dd>
|
||||
|
||||
<dt><label for='id_priority'>{{ form.priority.label }}</label></dt>
|
||||
<dd>{{ form.priority }}</dd>
|
||||
{% if form.priority.errors %}
|
||||
<dd class='error'>{{ form.priority.errors }}</dd>{% endif %}
|
||||
{% if form.priority.errors %}<dd class='error'>{{ form.priority.errors }}</dd>{% endif %}
|
||||
<dd class='form_help_text'>{{ form.priority.help_text }}</dd>
|
||||
</dl>
|
||||
|
||||
|
@ -1,30 +1,30 @@
|
||||
{% if debug %}
|
||||
<div id="debug" style='clear: both;padding-top: 200px'>
|
||||
<h2>Queries</h2>
|
||||
<p>
|
||||
{{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}
|
||||
{% ifnotequal sql_queries|length 0 %}
|
||||
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.display=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
|
||||
{% endifnotequal %}
|
||||
</p>
|
||||
<table id="debugQueryTable" style="display: none;">
|
||||
<col width="1"></col>
|
||||
<col></col>
|
||||
<col width="1"></col>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">SQL</th>
|
||||
<th scope="col">Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for query in sql_queries %}<tr class="{% cycle odd,even %}">
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ query.sql|escape }}</td>
|
||||
<td>{{ query.time }}</td>
|
||||
</tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if debug %}
|
||||
<div id="debug" style='clear: both;padding-top: 200px'>
|
||||
<h2>Queries</h2>
|
||||
<p>
|
||||
{{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}
|
||||
{% ifnotequal sql_queries|length 0 %}
|
||||
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.display=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
|
||||
{% endifnotequal %}
|
||||
</p>
|
||||
<table id="debugQueryTable" style="display: none;">
|
||||
<col width="1"></col>
|
||||
<col></col>
|
||||
<col width="1"></col>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">SQL</th>
|
||||
<th scope="col">Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for query in sql_queries %}<tr class="{% cycle odd,even %}">
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ query.sql|escape }}</td>
|
||||
<td>{{ query.time }}</td>
|
||||
</tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -1,4 +1,5 @@
|
||||
{% extends "helpdesk/base.html" %}
|
||||
|
||||
{% block helpdesk_title %}Delete Ticket{% endblock %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
@ -7,5 +8,6 @@
|
||||
<p>Are you sure you want to delete this ticket (<em>{{ ticket.title }}</em>)? All traces of the ticket, including followups, attachments, and updates will be irreversably removed.</p>
|
||||
|
||||
<p><a href='../'>No, Don't Delete It</a></p>
|
||||
|
||||
<form method='post' action='./'><input type='submit' value='Yes - Delete It' /></form>
|
||||
{% endblock %}
|
||||
|
@ -72,14 +72,14 @@
|
||||
<th colspan='2'>Description</th>
|
||||
</tr>
|
||||
<tr class='row_even'>
|
||||
<td colspan='2'>{{ ticket.description }}</td>
|
||||
<td colspan='2'>{{ ticket.description|safe }}</td>
|
||||
</tr>
|
||||
|
||||
{% if ticket.resolution %}<tr class='row_odd'>
|
||||
<th colspan='2'>Resolution{% ifequal ticket.get_status_display "Resolved" %} <a href='?close'><img src='{{ MEDIA_URL }}/helpdesk/buttons/accept.png' alt='Accept' title='Accept and Close' width='60' height='15' /></a>{% endifequal %}</th>
|
||||
</tr>
|
||||
<tr class='row_even'>
|
||||
<td colspan='2'>{{ ticket.resolution }}</td>
|
||||
<td colspan='2'>{{ ticket.resolution|safe }}</td>
|
||||
</tr>{% endif %}
|
||||
|
||||
</table>
|
||||
@ -90,7 +90,7 @@
|
||||
{% for followup in ticket.followup_set.all %}
|
||||
<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'>(Private)</span>{% endif %}</span></div>
|
||||
{% if followup.comment %}{{ followup.comment|num_to_link }}{% endif %}
|
||||
{% if followup.comment %}{{ followup.comment|num_to_link|safe }}{% endif %}
|
||||
{% for change in followup.ticketchange_set.all %}
|
||||
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
||||
<li>Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.</li>
|
||||
|
Loading…
Reference in New Issue
Block a user