mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2025-02-16 18:20:48 +01:00
Allow updating task state when writing a ticket follow-up
This commit is contained in:
parent
308f69a03b
commit
11b2b36dd2
@ -6,14 +6,6 @@
|
|||||||
|
|
||||||
{% block helpdesk_title %}{{ ticket.queue.slug }}-{{ ticket.id }} : {% trans "View Ticket Details" %}{% endblock %}
|
{% block helpdesk_title %}{{ ticket.queue.slug }}-{{ ticket.id }} : {% trans "View Ticket Details" %}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_head %}
|
|
||||||
<style>
|
|
||||||
.checklist {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block h1_title %}{{ ticket.ticket_for_url }}{% endblock %}
|
{% block h1_title %}{{ ticket.ticket_for_url }}{% endblock %}
|
||||||
|
|
||||||
{% block helpdesk_breadcrumb %}
|
{% block helpdesk_breadcrumb %}
|
||||||
@ -171,7 +163,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p id='ShowFurtherOptPara'><button class="btn btn-warning btn-sm" id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</button></p>
|
<p id='ShowFurtherOptPara'><button type="button" class="btn btn-warning btn-sm" id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</button></p>
|
||||||
|
|
||||||
<div id='FurtherEditOptions' style='display: none;'>
|
<div id='FurtherEditOptions' style='display: none;'>
|
||||||
|
|
||||||
@ -193,7 +185,41 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p id='ShowFileUploadPara'><button class="btn btn-warning btn-sm" id='ShowFileUpload'>{% trans "Attach File(s) »" %}</button></p>
|
{% if ticket.checklists.exists %}
|
||||||
|
<p>
|
||||||
|
<button type="button" class="btn btn-warning btn-sm" id='ShowChecklistEditOptions'>
|
||||||
|
{% trans "Update checklists" %} »
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="checklistEdit" style="display: none">
|
||||||
|
<div class="row">
|
||||||
|
{% for checklist in ticket.checklists.all %}
|
||||||
|
<div class="col-sm-4 col-xs-12">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5>{{ checklist }}</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="list-group">
|
||||||
|
{% for task in checklist.tasks.all %}
|
||||||
|
<div class="list-group-item"{% if task.completion_date %} title="{% trans "Completed on" %} {{ task.completion_date }}" {% endif %}>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="checklist-{{ checklist.id }}" value="{{ task.id }}" {% if task.completion_date %} checked{% endif %}>
|
||||||
|
{{ task }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p id='ShowFileUploadPara'><button type="button" class="btn btn-warning btn-sm" id='ShowFileUpload'>{% trans "Attach File(s) »" %}</button></p>
|
||||||
|
|
||||||
<div id='FileUpload' style='display: none;'>
|
<div id='FileUpload' style='display: none;'>
|
||||||
|
|
||||||
@ -234,13 +260,15 @@ $( function() {
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("#ShowFurtherEditOptions").click(function() {
|
$("#ShowFurtherEditOptions").click(function() {
|
||||||
$("#FurtherEditOptions").toggle();
|
$("#FurtherEditOptions").toggle();
|
||||||
return false;
|
});
|
||||||
|
|
||||||
|
$("#ShowChecklistEditOptions").click(function() {
|
||||||
|
$("#checklistEdit").toggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#ShowFileUpload").click(function() {
|
$("#ShowFileUpload").click(function() {
|
||||||
$("#FileUpload").fadeIn();
|
$("#FileUpload").fadeIn();
|
||||||
$("#ShowFileUploadPara").hide();
|
$("#ShowFileUploadPara").hide();
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#id_preset').change(function() {
|
$('#id_preset').change(function() {
|
||||||
|
@ -178,14 +178,16 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
{% for checklist in ticket.checklists.all %}
|
{% for checklist in ticket.checklists.all %}
|
||||||
<div class="col-sm-4 col-xs-12">
|
<div class="col-sm-4 col-xs-12">
|
||||||
<div class="card checklist">
|
<div class="card mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h5>
|
<h5>
|
||||||
{{ checklist }}
|
<span data-toggle="collapse" data-target="#checklist{{ checklist.id }}" onclick="$(this).siblings('button').children('i').toggleClass('fa-caret-down fa-caret-up')">
|
||||||
|
{{ checklist }}
|
||||||
|
</span>
|
||||||
<a class="btn btn-link btn-sm" href="{% url 'helpdesk:edit_ticket_checklist' ticket.id checklist.id %}">
|
<a class="btn btn-link btn-sm" href="{% url 'helpdesk:edit_ticket_checklist' ticket.id checklist.id %}">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</a>
|
</a>
|
||||||
<button class="btn btn-secondary btn-sm float-right" data-toggle="collapse" data-target="#checklist{{ checklist.id }}" onclick="$(this).find('i').toggleClass('fa-caret-down fa-caret-up')">
|
<button class="btn btn-secondary btn-sm float-right" data-toggle="collapse" data-target="#checklist{{ checklist.id }}" onclick="$(this).children('i').toggleClass('fa-caret-down fa-caret-up')">
|
||||||
<i class="fas fa-caret-down"></i>
|
<i class="fas fa-caret-down"></i>
|
||||||
</button>
|
</button>
|
||||||
</h5>
|
</h5>
|
||||||
@ -193,31 +195,30 @@
|
|||||||
<div class="card-body collapse" id="checklist{{ checklist.id }}">
|
<div class="card-body collapse" id="checklist{{ checklist.id }}">
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for task in checklist.tasks.all %}
|
{% for task in checklist.tasks.all %}
|
||||||
<div class="list-group-item">
|
<div class="list-group-item"{% if task.completion_date %} title="{% trans "Completed on" %} {{ task.completion_date }}" {% endif %}>
|
||||||
<input type="checkbox" disabled{% if task.completion_date %} checked{% endif %}>
|
<label>
|
||||||
{{ task }}
|
<input type="checkbox" disabled{% if task.completion_date %} checked{% endif %}>
|
||||||
{% if task.completion_date %}
|
{{ task }}
|
||||||
<i>
|
</label>
|
||||||
({% trans "Completed on" %} {{ task.completion_date }})
|
|
||||||
</i>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
{% if checklist.tasks.completed.count %}
|
||||||
<div class="progress">
|
<div class="card-footer">
|
||||||
{% widthratio checklist.tasks.completed.count checklist.tasks.count 100 as width %}
|
<div class="progress">
|
||||||
<div class="progress-bar" role="progressbar" style="width: {{ width }}%" aria-valuenow="{{ width }}" aria-valuemin="0" aria-valuemax="100">
|
{% widthratio checklist.tasks.completed.count checklist.tasks.count 100 as width %}
|
||||||
{{ width }}%
|
<div class="progress-bar" role="progressbar" style="width: {{ width }}%" aria-valuenow="{{ width }}" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
{{ width }}%
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="col-sm-4 col-xs-12">
|
<div class="col-sm-4 col-xs-12">
|
||||||
<div class="card checklist">
|
<div class="card mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h5>Add a checklist</h5>
|
<h5>Add a checklist</h5>
|
||||||
</div>
|
</div>
|
||||||
|
@ -738,6 +738,14 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
owner = int(request.POST.get('owner', -1))
|
owner = int(request.POST.get('owner', -1))
|
||||||
priority = int(request.POST.get('priority', ticket.priority))
|
priority = int(request.POST.get('priority', ticket.priority))
|
||||||
|
|
||||||
|
# Check if a change happened on checklists
|
||||||
|
changes_in_checklists = False
|
||||||
|
for checklist in ticket.checklists.all():
|
||||||
|
old_completed_id = sorted(list(checklist.tasks.completed().values_list('id', flat=True)))
|
||||||
|
new_completed_id = sorted(list(map(int, request.POST.getlist(f'checklist-{checklist.id}', []))))
|
||||||
|
if old_completed_id != new_completed_id:
|
||||||
|
changes_in_checklists = True
|
||||||
|
|
||||||
time_spent = get_time_spent_from_request(request)
|
time_spent = get_time_spent_from_request(request)
|
||||||
# NOTE: jQuery's default for dates is mm/dd/yy
|
# NOTE: jQuery's default for dates is mm/dd/yy
|
||||||
# very US-centric but for now that's the only format supported
|
# very US-centric but for now that's the only format supported
|
||||||
@ -746,6 +754,7 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
no_changes = all([
|
no_changes = all([
|
||||||
not request.FILES,
|
not request.FILES,
|
||||||
not comment,
|
not comment,
|
||||||
|
not changes_in_checklists,
|
||||||
new_status == ticket.status,
|
new_status == ticket.status,
|
||||||
title == ticket.title,
|
title == ticket.title,
|
||||||
priority == int(ticket.priority),
|
priority == int(ticket.priority),
|
||||||
@ -854,6 +863,30 @@ def update_ticket(request, ticket_id, public=False):
|
|||||||
c.save()
|
c.save()
|
||||||
ticket.due_date = due_date
|
ticket.due_date = due_date
|
||||||
|
|
||||||
|
if changes_in_checklists:
|
||||||
|
for checklist in ticket.checklists.all():
|
||||||
|
new_completed_tasks = list(map(int, request.POST.getlist(f'checklist-{checklist.id}', [])))
|
||||||
|
for task in checklist.tasks.all():
|
||||||
|
changed = None
|
||||||
|
|
||||||
|
# Add completion if it was not done yet
|
||||||
|
if not task.completion_date and task.id in new_completed_tasks:
|
||||||
|
task.completion_date = timezone.now()
|
||||||
|
changed = 'completed'
|
||||||
|
# Remove it if it was done before
|
||||||
|
elif task.completion_date and task.id not in new_completed_tasks:
|
||||||
|
task.completion_date = None
|
||||||
|
changed = 'uncompleted'
|
||||||
|
|
||||||
|
# Save and add ticket change if task state has changed
|
||||||
|
if changed:
|
||||||
|
task.save(update_fields=['completion_date'])
|
||||||
|
f.ticketchange_set.create(
|
||||||
|
field=f'[{checklist.name}] {task.description}',
|
||||||
|
old_value=_('To do') if changed == 'completed' else _('Completed'),
|
||||||
|
new_value=_('Completed') if changed == 'completed' else _('To do'),
|
||||||
|
)
|
||||||
|
|
||||||
if new_status in (
|
if new_status in (
|
||||||
Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS
|
Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS
|
||||||
) and (
|
) and (
|
||||||
|
Loading…
Reference in New Issue
Block a user