Update dashboard and reports to new style, add more CDN support for new javascript libraries

This commit is contained in:
Garret Wassermann 2016-09-09 02:45:12 -04:00
parent 4c89da89b5
commit d66259efdc
9 changed files with 429 additions and 173 deletions

View File

@ -19,10 +19,8 @@
<!-- Bootstrap Core CSS --> <!-- Bootstrap Core CSS -->
{% if helpdesk_settings.HELPDESK_USE_CDN %} {% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet">
{% else %} {% else %}
<script src="{% static 'helpdesk/bootstrap/bootstrap-3.3.7.min.js' %}" type='text/javascript'></script>
<link href="{% static 'helpdesk/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet"> <link href="{% static 'helpdesk/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
{% endif %} {% endif %}
@ -34,11 +32,30 @@
<link rel='stylesheet' href='{% static "helpdesk/helpdesk-extend.css" %}' type='text/css' media="screen" > <link rel='stylesheet' href='{% static "helpdesk/helpdesk-extend.css" %}' type='text/css' media="screen" >
<!-- Morris Charts CSS --> <!-- Morris Charts CSS -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
{% else %}
<link href="{% static 'helpdesk/vendor/morrisjs/morris.css' %}" rel="stylesheet"> <link href="{% static 'helpdesk/vendor/morrisjs/morris.css' %}" rel="stylesheet">
{% endif %}
<!-- Custom Fonts --> <!-- Custom Fonts -->
<link href="{% static 'helpdesk/vendor/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css"> <link href="{% static 'helpdesk/vendor/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
<!-- jQuery -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
{% else %}
<script src="{% static 'helpdesk/vendor/jquery/jquery.min.js' %}"></script>
{% endif %}
<script src='{% static "helpdesk/jquery-ui-1.12.0.min.js" %}' type='text/javascript' language='javascript'></script>
<!-- Bootstrap Core JavaScript -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
{% else %}
<script src="{% static 'helpdesk/vendor/bootstrap/js/bootstrap.min.js' %}"></script>
{% endif %}
<!-- RSS --> <!-- RSS -->
<link rel='alternate' href='{% url 'helpdesk_rss_user' user.get_username %}' type='application/rss+xml' title='{% trans "My Open Tickets" %}' /> <link rel='alternate' href='{% url 'helpdesk_rss_user' user.get_username %}' type='application/rss+xml' title='{% trans "My Open Tickets" %}' />
<link rel='alternate' href='{% url 'helpdesk_rss_activity' %}' type='application/rss+xml' title='{% trans "All Recent Activity" %}' /> <link rel='alternate' href='{% url 'helpdesk_rss_activity' %}' type='application/rss+xml' title='{% trans "All Recent Activity" %}' />
@ -98,34 +115,9 @@
</div> </div>
{% include "helpdesk/debug.html" %} {% include "helpdesk/debug.html" %}
<!-- jQuery -->
<script src="{% static 'helpdesk/vendor/jquery/jquery.min.js' %}"></script>
<script src='{% static "helpdesk/jquery-ui-1.12.0.min.js" %}' type='text/javascript' language='javascript'></script>
<!-- Bootstrap Core JavaScript -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
{% else %}
<script src="{% static 'helpdesk/vendor/bootstrap/js/bootstrap.min.js' %}"></script>
{% endif %}
<!-- Metis Menu Plugin JavaScript --> <!-- Metis Menu Plugin JavaScript -->
<script src="{% static 'helpdesk/vendor/metisMenu/metisMenu.min.js' %}"></script> <script src="{% static 'helpdesk/vendor/metisMenu/metisMenu.min.js' %}"></script>
<!-- Flot Charts JavaScript -->
<script src="{% static 'helpdesk/vendor/flot/excanvas.min.js' %}"></script>
<script src="{% static 'helpdesk/vendor/flot/jquery.flot.js' %}"></script>
<script src="{% static 'helpdesk/vendor/flot/jquery.flot.pie.js' %}"></script>
<script src="{% static 'helpdesk/vendor/flot/jquery.flot.resize.js' %}"></script>
<script src="{% static 'helpdesk/vendor/flot/jquery.flot.time.js' %}"></script>
<script src="{% static 'helpdesk/vendor/flot-tooltip/jquery.flot.tooltip.min.js' %}"></script>
<script src="{% static 'helpdesk/data/flot-data.js' %}"></script>
<!-- Morris Charts JavaScript -->
<script src="{% static 'helpdesk/vendor/raphael/raphael.min.js' %}"></script>
<script src="{% static 'helpdesk/vendor/morrisjs/morris.min.js' %}"></script>
<script src="{% static 'helpdesk/data/morris-data.js' %}"></script>
<!-- Custom Theme JavaScript --> <!-- Custom Theme JavaScript -->
<script src="{% static 'helpdesk/dist/js/sb-admin-2.js' %}"></script> <script src="{% static 'helpdesk/dist/js/sb-admin-2.js' %}"></script>

View File

@ -1,19 +1,41 @@
{% load i18n %} {% load i18n %}
<table class="table table-hover table-bordered table-striped ticket-stats">
<caption>{% trans "Current Ticket Stats" %}</caption> <div class="row">
<thead> <div class="col-lg-12">
<tr><td colspan='2'>- {% trans "Average number of days until ticket is closed (all tickets): " %}<strong style="color: red;">{{ basic_ticket_stats.average_nbr_days_until_ticket_closed }}</strong>.</td></tr> <div class="panel panel-primary">
<tr><td colspan='2'>- {% trans "Average number of days until ticket is closed (tickets opened in last 60 days): " %}<strong style="color: red;">{{ basic_ticket_stats.average_nbr_days_until_ticket_closed_last_60_days }}</strong>. <div class="panel-heading">
{% trans "Click" %} <strong><a href="{% url 'helpdesk_report_index' %}daysuntilticketclosedbymonth">here</a></strong> {% trans "for detailed average by month." %} </td></tr> {% trans "Helpdesk Summary" %}
<tr><td colspan='2'>- {% trans "Distribution of open tickets, grouped by time period:" %}</td></tr> </div>
<tr><th>{% trans "Days since opened" %}</th><th>{% trans "Number of open tickets" %}</th></tr> <!-- /.panel-heading -->
</thead> <div class="panel-body">
<tbody> {% for entry in basic_ticket_stats.open_ticket_stats %}
{% for entry in basic_ticket_stats.open_ticket_stats %} <div class="col-lg-3 col-md-6">
<tr> <div class="panel panel-{{ entry.2 }}">
<th>{{ entry.0 }}</th> <div class="panel-heading">
<td><span style="color: {{ entry.2 }};">{% if entry.1 > 0 %}<a href="{% url 'helpdesk_list' %}?{{ entry.3 }}">{{ entry.1 }}</a>{% else %}{{ entry.1 }}{% endif %}</span></td> <div class="row">
</tr> <div class="col-xs-3">
{% endfor %} <i class="fa fa-calendar fa-5x"></i>
</tbody> </div>
</table> <div class="col-xs-9 text-right">
<div class="huge">{{ entry.1 }}</div>
<div>{{ entry.0 }}</div>
</div>
</div>
</div>
{% if entry.1 > 0 %}<a href="{% url 'helpdesk_list' %}?{{ entry.3 }}">{% else %}<a href="#">{% endif %}
<div class="panel-footer">
<span class="pull-left">{% if entry.1 > 0 %}{% trans "View Tickets" %}{% else %}{% trans "No tickets in this range" %}{% endif %}</span>
{% if entry.1 > 0 %}<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>{% endif %}
<div class="clearfix"></div>
</div>
</a>
</div>
</div>
{% endfor %}
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>

View File

@ -1,17 +1,42 @@
{% load i18n %} {% load i18n %}
<table class="table table-hover table-bordered table-striped">
<caption>{% trans "Helpdesk Summary" %}</caption> <div class="row">
<thead> <div class="col-lg-12">
<tr><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th><th>{% trans "Closed" %}</th></tr> <div class="panel panel-green">
</thead> <div class="panel-heading">
<tbody> {% trans "Helpdesk Summary" %}
{% for queue in dash_tickets %} </div>
<tr>{% url 'helpdesk_list' as hdlist %} <!-- /.panel-heading -->
<th><a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></th> <div class="panel-body">
<td align="center">{% if queue.open %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td> <div class="table-responsive">
<td align="center">{% if queue.resolved %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td> <table class="table table-striped table-bordered table-hover">
<td align="center">{% if queue.closed %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=4'>{% endif %}{{ queue.closed }}{% if queue.closed %}</a>{% endif %}</td> <thead>
</tr> <tr>
{% endfor %} <th>{% trans "Queue" %}</th>
</tbody> <th>{% trans "Open" %}</th>
</table> <th>{% trans "Resolved" %}</th>
<th>{% trans "Closed" %}</th>
</tr>
</thead>
<tbody>
{% for queue in dash_tickets %}
<tr>{% url 'helpdesk_list' as hdlist %}
<td><a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></td>
<td>{% if queue.open %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
<td>{% if queue.resolved %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
<td>{% if queue.closed %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=4'>{% endif %}{{ queue.closed }}{% if queue.closed %}</a>{% endif %}</td>
</tr>
{% empty %}
<tr><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>

View File

@ -1,21 +1,46 @@
{% load i18n humanize %} {% load i18n humanize %}
<table class="table table-hover table-bordered table-striped">{% if ticket_list_caption %}
<caption>{{ ticket_list_caption }}</caption>{% endif %} <div class="row">
<thead> <div class="col-lg-12">
<tr><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr> <div class="panel panel-primary">
</thead> <div class="panel-heading">
<tbody> {% if ticket_list_caption %}{{ ticket_list_caption }}{% else %}{% trans "Your Tickets" %}{% endif %}
{% for ticket in ticket_list %} </div>
<tr class="{{ ticket.get_priority_css_class }}"> <!-- /.panel-heading -->
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th> <div class="panel-body">
<td>{{ ticket.priority }}</td> <div class="table-responsive">
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th> <table class="table table-striped table-bordered table-hover">
<td>{{ ticket.queue }}</td> <thead>
<td>{{ ticket.get_status }}</td> <tr>
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|naturaltime }}</span></td> <th>#</th>
</tr> <th>{% trans "Pr" %}</th>
{% empty %}{% if ticket_list_empty_message %} <th>{% trans "Title" %}</th>
<tr><td colspan='6'>{{ ticket_list_empty_message }}</td></tr> <th>{% trans "Queue" %}</th>
{% endif %}{% endfor %} <th>{% trans "Status" %}</th>
</tbody> <th>{% trans "Last Update" %}</th>
</table> </tr>
</thead>
<tbody>
{% for ticket in ticket_list %}
<tr class="{{ ticket.get_priority_css_class }}">
<td><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</td>
<td>{{ ticket.priority }}</td>
<td><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></td>
<td>{{ ticket.queue }}</td>
<td>{{ ticket.get_status }}</td>
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|naturaltime }}</span></td>
</tr>
{% empty %}
<tr>{% if ticket_list_empty_message %}<td colspan='6'>{{ ticket_list_empty_message }}</td>{% else %}<td colspan='6'>{% trans "You do not have any pending tickets." %}</td>{% endif %}</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>

View File

@ -1,21 +1,45 @@
{% load i18n humanize %} {% load i18n humanize %}
<table class="table table-hover table-bordered table-striped">
<caption>{% trans "Unassigned Tickets" %} {% trans "(pick up a ticket if you start to work on it)" %}</caption> <div class="row">
<thead> <div class="col-lg-12">
<tr><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Created" %}</th><th>&nbsp;</th></tr> <div class="panel panel-primary">
</thead> <div class="panel-heading">
<tbody> {% trans "Unassigned Tickets" %} {% trans "(pick up a ticket if you start to work on it)" %}
{% for ticket in unassigned_tickets %} </div>
<tr class="{{ ticket.get_priority_css_class }}"> <!-- /.panel-heading -->
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th> <div class="panel-body">
<td>{{ ticket.priority }}</td> <div class="table-responsive">
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th> <table class="table table-striped table-bordered table-hover">
<td>{{ ticket.queue }}</td> <thead>
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|naturaltime }}</span></td> <tr>
<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>#</th>
</tr> <th>{% trans "Pr" %}</th>
{% empty %} <th>{% trans "Title" %}</th>
<tr><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr> <th>{% trans "Queue" %}</th>
{% endfor %} <th>{% trans "Created" %}</th>
</tbody> <th>&nbsp;</th>
</table> </tr>
</thead>
<tbody>
{% for ticket in unassigned_tickets %}
<tr class="{{ ticket.get_priority_css_class }}">
<td><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</td>
<td>{{ ticket.priority }}</td>
<td><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></td>
<td>{{ ticket.queue }}</td>
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|naturaltime }}</span></td>
<td><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></td>
</tr>
{% empty %}
<tr><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>

View File

@ -17,10 +17,8 @@
<!-- Bootstrap Core CSS --> <!-- Bootstrap Core CSS -->
{% if helpdesk_settings.HELPDESK_USE_CDN %} {% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet">
{% else %} {% else %}
<script src="{% static 'helpdesk/bootstrap/bootstrap-3.3.7.min.js' %}" type='text/javascript'></script>
<link href="{% static 'helpdesk/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet"> <link href="{% static 'helpdesk/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
{% endif %} {% endif %}
@ -64,12 +62,16 @@
{% include "helpdesk/debug.html" %} {% include "helpdesk/debug.html" %}
<!-- jQuery --> <!-- jQuery -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
{% else %}
<script src="{% static 'helpdesk/vendor/jquery/jquery.min.js' %}"></script> <script src="{% static 'helpdesk/vendor/jquery/jquery.min.js' %}"></script>
{% endif %}
<script src='{% static "helpdesk/jquery-ui-1.12.0.min.js" %}' type='text/javascript' language='javascript'></script> <script src='{% static "helpdesk/jquery-ui-1.12.0.min.js" %}' type='text/javascript' language='javascript'></script>
<!-- Bootstrap Core JavaScript --> <!-- Bootstrap Core JavaScript -->
{% if helpdesk_settings.HELPDESK_USE_CDN %} {% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
{% else %} {% else %}
<script src="{% static 'helpdesk/vendor/bootstrap/js/bootstrap.min.js' %}"></script> <script src="{% static 'helpdesk/vendor/bootstrap/js/bootstrap.min.js' %}"></script>
{% endif %} {% endif %}

View File

@ -9,24 +9,92 @@
<p>{% trans "You haven't created any tickets yet, so you cannot run any reports." %}</p> <p>{% trans "You haven't created any tickets yet, so you cannot run any reports." %}</p>
{% else %} {% else %}
<ul> <div class="row">
<li>{% trans "Reports By User" %}<ul> <div class="col-lg-12">
<div class="panel panel-warning">
<div class="panel-heading">
{% trans "Current Ticket Stats" %}
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td>{% trans "Average number of days until ticket is closed (all tickets): " %}</td>
<td><strong style="color: red;">{{ basic_ticket_stats.average_nbr_days_until_ticket_closed }}</strong>.</td>
</tr>
<tr>
<td>{% trans "Average number of days until ticket is closed (tickets opened in last 60 days): " %}</td>
<td><strong style="color: red;">{{ basic_ticket_stats.average_nbr_days_until_ticket_closed_last_60_days }}</strong>. {% trans "Click" %} <strong><a href="{% url 'helpdesk_report_index' %}daysuntilticketclosedbymonth">here</a></strong> {% trans "for detailed average by month." %} </td>
</tr>
</tbody>
</table>
</div>
<!-- /.table-responsive -->
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>{% trans "Queue" %}</th>
<th>{% trans "Open" %}</th>
<th>{% trans "Resolved" %}</th>
<th>{% trans "Closed" %}</th>
</tr>
</thead>
<tbody>
{% for queue in dash_tickets %}
<tr>{% url 'helpdesk_list' as hdlist %}
<td><a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></td>
<td>{% if queue.open %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
<td>{% if queue.resolved %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
<td>{% if queue.closed %}<a href='{{ hdlist }}?queue={{ queue.queue }}&status=4'>{% endif %}{{ queue.closed }}{% if queue.closed %}</a>{% endif %}</td>
</tr>
{% empty %}
<tr><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>
<li><a href='userpriority/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Priority" %}</a></li> <div class="row">
<li><a href='userqueue/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Queue" %}</a></li> <div class="col-lg-12">
<li><a href='userstatus/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Status" %}</a></li> <div class="panel panel-primary">
<li><a href='usermonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Month" %}</a></li> <div class="panel-heading">
{% trans "Generate Report" %}
</ul></li> </div>
<!-- /.panel-heading -->
<li>{% trans "Reports By Queue" %}<ul> <div class="panel-body">
<ul>
<li><a href='queuepriority/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Priority" %}</a></li> <li>{% trans "Reports By User" %}
<li><a href='queuestatus/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Status" %}</a></li> <ul>
<li><a href='queuemonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Month" %}</a></li> <li><a href='userpriority/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Priority" %}</a></li>
<li><a href='daysuntilticketclosedbymonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "Days until ticket closed by Month" %}</a></li> <li><a href='userqueue/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Queue" %}</a></li>
<li><a href='userstatus/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Status" %}</a></li>
</ul></li> <li><a href='usermonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Month" %}</a></li>
</ul> </ul>
</li>
<li>{% trans "Reports By Queue" %}
<ul>
<li><a href='queuepriority/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Priority" %}</a></li>
<li><a href='queuestatus/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Status" %}</a></li>
<li><a href='queuemonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "by Month" %}</a></li>
<li><a href='daysuntilticketclosedbymonth/{% if saved_query %}?saved_query={{ saved_query }}{% endif %}'>{% trans "Days until ticket closed by Month" %}</a></li>
</ul>
</li>
</ul>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>
{% endifequal %}{% endblock %} {% endifequal %}{% endblock %}

View File

@ -4,17 +4,38 @@
{% block helpdesk_title %}{% trans "Reports &amp; Statistics" %}{% endblock %} {% block helpdesk_title %}{% trans "Reports &amp; Statistics" %}{% endblock %}
{% block helpdesk_head %} {% block helpdesk_head %}
<!--[if IE]><script language="javascript" type="text/javascript" src="{% static "helpdesk/jquery.jqplot/excanvas.min.js" %}"></script><![endif]-->
<script src='{% static "helpdesk/jquery.jqplot/jquery.jqplot-1.0.9.min.js" %}' type='text/javascript' language='javascript'></script> <!-- Flot Charts JavaScript -->
<link rel='stylesheet' typ='text/css' href='{% static "helpdesk/jquery.jqplot/jquery.jqplot-1.0.9.min.css" %}' /> <script src="/static/helpdesk/vendor/flot/excanvas.min.js"></script>
<script type="text/javascript" src="{% static "helpdesk/jquery.jqplot/plugins/jqplot.categoryAxisRenderer.js" %}"></script> <script src="/static/helpdesk/vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="{% static "helpdesk/jquery.jqplot/plugins/jqplot.barRenderer.js" %}"></script> <script src="/static/helpdesk/vendor/flot/jquery.flot.categories.js"></script>
<script type="text/javascript" src="{% static "helpdesk/jquery.jqplot/plugins/jqplot.dateAxisRenderer.js" %}"></script> <script src="/static/helpdesk/vendor/flot/jquery.flot.pie.js"></script>
<script src="/static/helpdesk/vendor/flot/jquery.flot.resize.js"></script>
<script src="/static/helpdesk/vendor/flot/jquery.flot.time.js"></script>
<script src="/static/helpdesk/vendor/flot-tooltip/jquery.flot.tooltip.min.js"></script>
<!-- Morris Charts JavaScript -->
{% if helpdesk_settings.HELPDESK_USE_CDN %}
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
{% else %}
<script src="{% static 'helpdesk/vendor/raphael/raphael.min.js' %}"></script>
<script src="{% static 'helpdesk/vendor/morrisjs/morris.min.js' %}"></script>
{% endif %}
{% endblock %} {% endblock %}
{% block helpdesk_body %} {% block helpdesk_body %}
<h2>{% trans "Reports &amp; Statistics" %}</h2> <h2>{% trans "Reports &amp; Statistics" %}</h2>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-primary">
<div class="panel-heading">
Saved Queries
</div>
<!-- /.panel-heading -->
<div class="panel-body">
{% if user_saved_queries_ %} {% if user_saved_queries_ %}
<p>{% trans "You can run this query on filtered data by using one of your saved queries." %}</p> <p>{% trans "You can run this query on filtered data by using one of your saved queries." %}</p>
<form method='GET' action='./'> <form method='GET' action='./'>
@ -28,22 +49,59 @@
{% else %} {% else %}
<p>{% trans "Want to filter this report to just show a subset of data? Go to the Ticket List, filter your query, and save your query." %}</p> <p>{% trans "Want to filter this report to just show a subset of data? Go to the Ticket List, filter your query, and save your query." %}</p>
{% endif %} {% endif %}
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>
<table class="table table-hover table-bordered"> <div class="row">
<caption>{{ title }}</caption> <div class="col-lg-12">
<thead> <div class="panel panel-primary">
<tr>{% for h in headings %}<th>{% if forloop.first %}{{ h|title }}{% else %}{{ h }}{% endif %}</th>{% endfor %}</tr> <div class="panel-heading">
</thead> {{ title }}
<tbody> </div>
{% for d in data %} <!-- /.panel-heading -->
<tr class='row_{% cycle 'odd' 'even' %}'>{% for f in d %}<td class='report'>{{ f }}</td>{% endfor %}</tr>{% endfor %} <div class="panel-body">
</tbody> <div class="table-responsive">
</table> <table class="table table-striped table-bordered table-hover">
<thead>
<tr>{% for h in headings %}
<th>{% if forloop.first %}{{ h|title }}{% else %}{{ h }}{% endif %}</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for d in data %}<tr class='row_{% cycle 'odd' 'even' %}'>
{% for f in d %}<td class='report'>{{ f }}</td>{% endfor %}
</tr>{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
<div class="flot-chart">
<div class="flot-chart-content" id="chart-content"></div>
</div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>
<div class='jqPlot' id='placeholder' style='width: 600px; height: 400px;'></div>
{% ifequal charttype "date" %} {% ifequal charttype "date" %}
<script type='text/javascript'> <script type='text/javascript'>
$.jqplot.config.enablePlugins = true;
Morris.Line({
element: 'chart-content',
data: {% autoescape on %}{{ morrisjs_data|safe }}{% endautoescape %},
xkey: 'x',
ykeys: [{% for d in data %}{{ forloop.counter0 }}{% if not forloop.last %}, {% endif %}{% endfor %}],
labels: [{% for n in series_names %}"{{ n }}"{% if not forloop.last %}, {% endif %}{% endfor %}],
xLabels: "month"
});
/*$.jqplot.config.enablePlugins = true;
var dataset = []; var dataset = [];
{% for d in data %} {% for d in data %}
@ -67,38 +125,20 @@
min: 0 min: 0
} }
} }
}); });*/
</script> </script>
{% endifequal %} {% endifequal %}
{% ifequal charttype "bar" %} {% ifequal charttype "bar" %}
<script type='text/javascript'> <script type='text/javascript'>
$.jqplot.config.enablePlugins = true;
var dataset = [];
{% for d in data %} Morris.Bar({
dataset[{{ forloop.counter0 }}] = [{% for f in d %}{% if not forloop.first %}{{ f }}{% if not forloop.last %}, {% endif %}{% endif %}{% endfor %}];{% endfor %} element: 'chart-content',
data: {% autoescape on %}{{ morrisjs_data|safe }}{% endautoescape %},
plot = $.jqplot('placeholder', dataset, { xkey: 'x',
legend: {show: true, location: 'nw', xoffset: 55}, ykeys: [{% for d in data %}{{ forloop.counter0 }}{% if not forloop.last %}, {% endif %}{% endfor %}],
title: "{{ title }}", labels: [{% for n in series_names %}"{{ n }}"{% if not forloop.last %}, {% endif %}{% endfor %}]
seriesDefaults: { });
renderer: $.jqplot.BarRenderer,
rendererOptions: {barPadding: 8, barMargin: 20}
},
series: [{% for d in data %}
{label:'{{ d.0 }}'}{% if not forloop.last %},{% endif %}{% endfor %}
],
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: [{% for h in headings %}{% if not forloop.first %}'{{ h }}'{% if not forloop.last %}, {% endif %}{% endif %}{% endfor %}]
},
yaxis: {
min: 0
}
}
});
</script> </script>
{% endifequal %} {% endifequal %}

View File

@ -1017,10 +1017,50 @@ rss_list = staff_member_required(rss_list)
def report_index(request): def report_index(request):
number_tickets = Ticket.objects.all().count() number_tickets = Ticket.objects.all().count()
saved_query = request.GET.get('saved_query', None) saved_query = request.GET.get('saved_query', None)
user_queues = _get_user_queues(request.user)
Tickets = Ticket.objects.filter(
queue__in=user_queues,
)
basic_ticket_stats = calc_basic_ticket_stats(Tickets)
# The following query builds a grid of queues & ticket statuses,
# to be displayed to the user. EG:
# Open Resolved
# Queue 1 10 4
# Queue 2 4 12
queues = _get_user_queues(request.user).values_list('id', flat=True)
from_clause = """FROM helpdesk_ticket t,
helpdesk_queue q"""
if queues:
where_clause = """WHERE q.id = t.queue_id AND
q.id IN (%s)""" % (",".join(("%d" % pk for pk in queues)))
else:
where_clause = """WHERE q.id = t.queue_id"""
cursor = connection.cursor()
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
%s
%s
GROUP BY queue, name
ORDER BY q.id;
""" % (from_clause, where_clause))
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
return render(request, template_name='helpdesk/report_index.html', return render(request, template_name='helpdesk/report_index.html',
context = { context = {
'number_tickets': number_tickets, 'number_tickets': number_tickets,
'saved_query': saved_query, 'saved_query': saved_query,
'basic_ticket_stats': basic_ticket_stats,
'dash_tickets': dash_tickets,
}) })
report_index = staff_member_required(report_index) report_index = staff_member_required(report_index)
@ -1072,7 +1112,8 @@ 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" % (month_name(month), year)) #periods.append("%s %s" % (month_name(month), year))
periods.append("%s-%s" % (year,month))
while working: while working:
month += 1 month += 1
@ -1081,7 +1122,7 @@ def run_report(request, report):
month = 1 month = 1
if (year > last_year) or (month > last_month and year >= last_year): if (year > last_year) or (month > last_month and year >= last_year):
working = False working = False
periods.append("%s %s" % (month_name(month), year)) periods.append("%s-%s" % (year,month))
if report == 'userpriority': if report == 'userpriority':
title = _('User by Priority') title = _('User by Priority')
@ -1148,7 +1189,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' % (month_name(ticket.created.month), ticket.created.year) metric2 = u'%s-%s' % (ticket.created.year, ticket.created.month)
elif report == 'queuepriority': elif report == 'queuepriority':
metric1 = u'%s' % ticket.queue.title metric1 = u'%s' % ticket.queue.title
@ -1160,11 +1201,11 @@ 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' % (month_name(ticket.created.month), ticket.created.year) metric2 = u'%s-%s' % (ticket.created.year, ticket.created.month)
elif report == 'daysuntilticketclosedbymonth': elif report == 'daysuntilticketclosedbymonth':
metric1 = u'%s' % ticket.queue.title metric1 = u'%s' % ticket.queue.title
metric2 = u'%s %s' % (month_name(ticket.created.month), ticket.created.year) metric2 = u'%s-%s' % (ticket.created.year, ticket.created.month)
metric3 = ticket.modified - ticket.created metric3 = ticket.modified - ticket.created
metric3 = metric3.days metric3 = metric3.days
@ -1191,12 +1232,29 @@ def run_report(request, report):
data.append(summarytable[item, hdr]) data.append(summarytable[item, hdr])
table.append([item] + data) table.append([item] + data)
# Zip data and headers together in one list for Morris.js charts
# will get a list like [(Header1, Data1), (Header2, Data2)...]
seriesnum = 0
morrisjs_data = []
for label in column_headings[1:]:
seriesnum += 1
datadict = { "x": label }
for n in range(0,len(table)):
datadict[n] = table[n][seriesnum]
morrisjs_data.append(datadict)
series_names = []
for series in table:
series_names.append(series[0])
return render(request, 'helpdesk/report_output.html', return render(request, 'helpdesk/report_output.html',
{ {
'title': title, 'title': title,
'charttype': charttype, 'charttype': charttype,
'data': table, 'data': table,
'headings': column_headings, 'headings': column_headings,
'series_names': series_names,
'morrisjs_data': morrisjs_data,
'from_saved_query': from_saved_query, 'from_saved_query': from_saved_query,
'saved_query': saved_query, 'saved_query': saved_query,
}) })