Merge pull request #1431 from gurupratap-matharu/hotfix/followup-card-colors
Hotfix/followup card colors
This commit is contained in:
@@ -819,4 +819,4 @@ class CreateChecklistForm(ChecklistForm):
|
||||
|
||||
|
||||
class FormControlDeleteFormSet(forms.BaseInlineFormSet):
|
||||
deletion_widget = forms.CheckboxInput(attrs={"class": "form-control"})
|
||||
deletion_widget = forms.CheckboxInput(attrs={"class": "form-check-input"})
|
||||
|
||||
@@ -6,7 +6,6 @@ a:not(.btn) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Bootstrap 5 removed the breadcrumb background; restore the BS4 grey */
|
||||
.breadcrumb {
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.25rem;
|
||||
@@ -82,58 +81,6 @@ table .tickettitle {
|
||||
min-width: 18rem;
|
||||
}
|
||||
|
||||
/* Follow-ups are color coded by who can see them and which way they went, so
|
||||
staff can tell an internal note from a reply to the submitter at a glance.
|
||||
The color is backed up by the badge text in each follow-up header, so it is
|
||||
never the only thing carrying the meaning. */
|
||||
.followup-item {
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
|
||||
/* Private, staff-only notes keep the plain background. */
|
||||
.followup-item-internal {
|
||||
border-left-color: #adb5bd;
|
||||
}
|
||||
|
||||
.followup-item-internal .followup-item-badge {
|
||||
background-color: #e9ecef;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Sent out to the submitter. */
|
||||
.followup-item-outbound {
|
||||
background-color: #eaf6ec;
|
||||
border-left-color: #198754;
|
||||
}
|
||||
|
||||
.followup-item-outbound .followup-item-badge {
|
||||
background-color: #d1e7dd;
|
||||
color: #0f5132;
|
||||
}
|
||||
|
||||
/* Received from the submitter. */
|
||||
.followup-item-inbound {
|
||||
background-color: #fdf6e3;
|
||||
border-left-color: #ffc107;
|
||||
}
|
||||
|
||||
.followup-item-inbound .followup-item-badge {
|
||||
background-color: #fff3cd;
|
||||
color: #664d03;
|
||||
}
|
||||
|
||||
/* list-group-item-action repaints the background on hover, which would undo
|
||||
the color coding, so darken each tint slightly instead. */
|
||||
.followup-item-outbound.list-group-item-action:hover,
|
||||
.followup-item-outbound.list-group-item-action:focus {
|
||||
background-color: #d9eddf;
|
||||
}
|
||||
|
||||
.followup-item-inbound.list-group-item-action:hover,
|
||||
.followup-item-inbound.list-group-item-action:focus {
|
||||
background-color: #faedcd;
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.kanban-drop-zone {
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.kanban-drop-zone.drag-over {
|
||||
background: rgba(var(--bs-secondary-bg-rgb), 0.5);
|
||||
outline: 2px dashed rgba(255, 255, 255, 0.3);
|
||||
background: rgb(var(--bs-secondary-bg-rgb), 0.5);
|
||||
border: 2px dashed rgb(var(--bs-secondary-color-rgb), 0.3);
|
||||
}
|
||||
|
||||
.kanban-card {
|
||||
cursor: grab;
|
||||
transition:
|
||||
|
||||
@@ -2,102 +2,121 @@
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block helpdesk_title %}{% translate "Edit Checklist" %}{% endblock %}
|
||||
{% block helpdesk_title %}
|
||||
{% translate "Edit Checklist" %}
|
||||
{% endblock helpdesk_title %}
|
||||
|
||||
{% block helpdesk_breadcrumb %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:list' %}">{% translate "Tickets" %}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:list' %}{{ ticket.id }}/">{{ ticket.queue.slug }}-{{ ticket.id }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">{{ checklist.name }}</li>
|
||||
{% endblock %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:list' %}">{% translate "Tickets" %}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:list' %}{{ ticket.id }}/">{{ ticket.queue.slug }}-{{ ticket.id }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">{{ checklist.name }}</li>
|
||||
{% endblock helpdesk_breadcrumb %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>
|
||||
{% translate "Edit Checklist" %}
|
||||
<a class="btn btn-danger float-end" href='{% url "helpdesk:delete_ticket_checklist" ticket.id checklist.id %}'>
|
||||
<i class="fas fa-trash"></i>
|
||||
{% translate "Delete checklist" %}
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 col-lg-6 mx-auto">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h1 class="fs-5 mb-0">{% translate "Edit Checklist" %}</h1>
|
||||
<div class="dropdown">
|
||||
<a class="btn bg-body-tertiary border btn-sm"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item link-danger"
|
||||
href='{% url "helpdesk:delete_ticket_checklist" ticket.id checklist.id %}'>
|
||||
<i class="fa-regular fa-trash-can"></i>
|
||||
{% translate "Delete" %}
|
||||
</a>
|
||||
</h2>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if form.non_field_errors %}
|
||||
<p class="text-danger">
|
||||
{{ form.non_field_errors }}
|
||||
</p>
|
||||
{% endif %}
|
||||
<form method='post'>
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-xs-12 mb-3">
|
||||
{{ form.name.label_tag }}
|
||||
{{ form.name }}
|
||||
{{ form.name.errors }}
|
||||
</div>
|
||||
</div>
|
||||
<h3>Tasks</h3>
|
||||
{{ formset.management_form }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-end">{% translate "Position" %}</th>
|
||||
<th>{% translate "Description" %}</th>
|
||||
<th class="text-center">{% translate "Delete?" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tasks">
|
||||
{% for form in formset %}
|
||||
{% include 'helpdesk/include/task_form_row.html' %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="button" class="btn btn-secondary" id="addRow">
|
||||
<i class="fas fa-plus"></i>
|
||||
{% translate "Add task" %}
|
||||
</button>
|
||||
<div class='buttons mb-3 text-center'>
|
||||
<a class="btn btn-link" href='{{ ticket.get_absolute_url }}'>
|
||||
<i class="fas fa-times"></i>
|
||||
{% translate "Cancel Changes" %}
|
||||
</a>
|
||||
<button type='submit' class="btn btn-primary">
|
||||
<i class="fas fa-save"></i>
|
||||
{% translate "Save Changes" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% if form.non_field_errors %}
|
||||
<p class="text-danger">{{ form.non_field_errors }}</p>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="{{ field.auto_id }}">{{ field.label }}{{ field.label_suffix }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}<span class="text-danger">{{ field.errors }}</span>{% endif %}
|
||||
{% if field.help_text %}
|
||||
<div class="form-text" id="{{ field.auto_id }}_helptext">{{ field.help_text|safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<h2 class="fs-6 mb-1">{% translate "Tasks" %}</h2>
|
||||
<small class="form-text">{% translate "Click and drag the position icon to reorder the task items." %}</small>
|
||||
{{ formset.management_form }}
|
||||
<table class="table align-middle my-3">
|
||||
<thead class="text-uppercase small">
|
||||
<tr>
|
||||
<th><span class="text-body-tertiary">{% translate "Position" %}</span></th>
|
||||
<th><span class="text-body-tertiary">{% translate "Description" %}</span></th>
|
||||
<th><span class="text-body-tertiary">{% translate "Delete?" %}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tasks">
|
||||
{% for form in formset %}
|
||||
{% include "helpdesk/include/task_form_row.html" %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="d-flex">
|
||||
<button type="button"
|
||||
class="btn bg-primary-subtle text-primary-emphasis border-primary-subtle me-auto"
|
||||
id="addRow">
|
||||
<i class="fas fa-plus"></i>
|
||||
{% translate "Add task" %}
|
||||
</button>
|
||||
<a class="btn bg-body-tertiary border me-3"
|
||||
href="{{ ticket.get_absolute_url }}">{% translate "Cancel" %}</a>
|
||||
<button type="submit" class="btn btn-success">{% translate "Save" %}</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock helpdesk_body %}
|
||||
|
||||
{% block helpdesk_js %}
|
||||
<script src="https://unpkg.com/sortablejs-make/Sortable.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>
|
||||
<script>
|
||||
const updatePosition = () => {
|
||||
$('#tasks tr').each((index, taskRow) => {
|
||||
$(taskRow).find('input[id$=position]').val(index + 1)
|
||||
})
|
||||
}
|
||||
<script src="https://unpkg.com/sortablejs-make/Sortable.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>
|
||||
<script>
|
||||
const updatePosition = () => {
|
||||
$('#tasks tr').each((index, taskRow) => {
|
||||
$(taskRow).find('input[id$=position]').val(index + 1)
|
||||
})
|
||||
}
|
||||
|
||||
$(() => {
|
||||
const idTasksTotalForms = $('#id_tasks-TOTAL_FORMS')
|
||||
$('#addRow').on('click', function() {
|
||||
const formCount = idTasksTotalForms.val()
|
||||
$('#tasks').append(`{% include 'helpdesk/include/task_form_row.html' with form=formset.empty_form %}`.replace(/__prefix__/g, formCount))
|
||||
idTasksTotalForms.val(parseInt(formCount) + 1);
|
||||
updatePosition()
|
||||
});
|
||||
$(() => {
|
||||
const idTasksTotalForms = $('#id_tasks-TOTAL_FORMS')
|
||||
$('#addRow').on('click', function() {
|
||||
const formCount = idTasksTotalForms.val()
|
||||
$('#tasks').append(`{% include 'helpdesk/include/task_form_row.html' with form=formset.empty_form %}`.replace(/__prefix__/g, formCount))
|
||||
idTasksTotalForms.val(parseInt(formCount) + 1);
|
||||
updatePosition()
|
||||
});
|
||||
|
||||
$('#tasks').sortable({
|
||||
handle: '.handle',
|
||||
onChange: updatePosition
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
$('#tasks').sortable({
|
||||
handle: '.handle',
|
||||
onChange: updatePosition
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock helpdesk_js %}
|
||||
|
||||
@@ -2,118 +2,147 @@
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block helpdesk_title %}{% translate "Checklist Templates" %}{% endblock %}
|
||||
{% block helpdesk_title %}
|
||||
{% translate "Checklist Templates" %}
|
||||
{% endblock helpdesk_title %}
|
||||
|
||||
{% block helpdesk_breadcrumb %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:system_settings' %}">{% translate "System Settings" %}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">{% translate "Checklist Templates" %}</li>
|
||||
{% endblock %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'helpdesk:system_settings' %}">{% translate "System Settings" %}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">{% translate "Checklist Templates" %}</li>
|
||||
{% endblock helpdesk_breadcrumb %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
<h2>{% translate "Maintain checklist templates" %}</h2>
|
||||
<div class="row mt-4">
|
||||
<div class="col-sm-6 col-xs-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{% if checklist_template %}
|
||||
{% translate "Edit checklist template" %}
|
||||
{% else %}
|
||||
{% translate "Create new checklist template" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="card-body">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Task</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tasks">
|
||||
{% if checklist_template %}
|
||||
{% for value in checklist_template.task_list %}
|
||||
{% include 'helpdesk/include/template_task_form_row.html' %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% include 'helpdesk/include/template_task_form_row.html' %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="button" id="addTask" class="btn btn-sm btn-secondary">
|
||||
<i class="fas fa-plus"></i>
|
||||
{% translate "Add another task" %}
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
{% if checklist_template %}
|
||||
<a href="{% url 'helpdesk:checklist_templates' %}" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i>
|
||||
{% translate "Cancel" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i>
|
||||
{% translate "Save checklist template" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<h1 class="fs-3">{% translate "Manage checklist templates" %}</h1>
|
||||
<p>{% translate "Create new or edit existing checklist templates." %}</p>
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="list-group">
|
||||
{% for checklist in checklists %}
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center{% if checklist_template.id == checklist.id %}
|
||||
active{% endif %}">
|
||||
<span class="fs-6 me-2">{{ checklist.name }}</span>
|
||||
<span class="badge bg-primary-subtle text-primary-emphasis border-primary-subtle">{{ checklist.task_list|length }} {% translate "tasks" %}</span>
|
||||
<div class="dropdown ms-auto">
|
||||
<a class="btn bg-body-tertiary border btn-sm"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
{% if checklist_template.id != checklist.id %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="{% url "helpdesk:edit_checklist_template" checklist.id %}">
|
||||
<i class="fas fa-edit me-2"></i>
|
||||
{% translate "Edit" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a class="dropdown-item link-danger"
|
||||
href="{% url "helpdesk:delete_checklist_template" checklist.id %}">
|
||||
<i class="fa-regular fa-trash-can me-2"></i>
|
||||
{% translate "Delete" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xs-12">
|
||||
<div class="list-group">
|
||||
{% for checklist in checklists %}
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center{% if checklist_template.id == checklist.id %} active{% endif %}">
|
||||
<span>
|
||||
{{ checklist.name }}
|
||||
{% if checklist_template.id != checklist.id %}
|
||||
<a class="btn btn-secondary btn-sm" href="{% url 'helpdesk:edit_checklist_template' checklist.id %}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-sm btn-danger" href="{% url 'helpdesk:delete_checklist_template' checklist.id %}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</span>
|
||||
<span class="badge text-bg-secondary rounded-pill">{{ checklist.task_list|length }} {% translate "tasks" %}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{% if checklist_template %}
|
||||
{% translate "Edit checklist template" %}
|
||||
{% else %}
|
||||
{% translate "Create new checklist template" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="card-body">
|
||||
{% csrf_token %}
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="{{ field.auto_id }}">{{ field.label }}{{ field.label_suffix }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}<span class="text-danger">{{ field.errors }}</span>{% endif %}
|
||||
{% if field.help_text %}
|
||||
<div class="form-text" id="{{ field.auto_id }}_helptext">{{ field.help_text|safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<h2 class="fs-6 mb-1">{% translate "Tasks" %}</h2>
|
||||
<small class="form-text">{% translate "Click and drag the position icon to reorder the task items." %}</small>
|
||||
<table class="table align-middle my-3">
|
||||
<thead class="text-uppercase small">
|
||||
<tr>
|
||||
<th><span class="text-body-tertiary">{% translate "Position" %}</span></th>
|
||||
<th><span class="text-body-tertiary">{% translate "Description" %}</span></th>
|
||||
<th><span class="text-body-tertiary">{% translate "Delete?" %}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tasks">
|
||||
{% if checklist_template %}
|
||||
{% for value in checklist_template.task_list %}
|
||||
{% include "helpdesk/include/template_task_form_row.html" %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% include "helpdesk/include/template_task_form_row.html" %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="d-flex">
|
||||
<button type="button"
|
||||
id="addTask"
|
||||
class="btn bg-primary-subtle text-primary-emphasis border-primary-subtle me-auto">
|
||||
<i class="fas fa-plus"></i>
|
||||
{% translate "Add task" %}
|
||||
</button>
|
||||
{% if checklist_template %}
|
||||
<a href="{% url 'helpdesk:checklist_templates' %}" class="btn bg-body-tertiary border me-3">
|
||||
{% translate "Cancel" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<button type="submit" class="btn btn-success">{% translate "Save" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock helpdesk_body %}
|
||||
|
||||
{% block helpdesk_js %}
|
||||
<script src="https://unpkg.com/sortablejs-make/Sortable.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>
|
||||
<script>
|
||||
const updateTemplateTaskList = () => {
|
||||
let tasks = []
|
||||
$('#tasks .taskInput').each((index, taskInput) => {
|
||||
tasks.push($(taskInput).val())
|
||||
})
|
||||
$('#id_task_list').val(JSON.stringify(tasks))
|
||||
}
|
||||
<script src="https://unpkg.com/sortablejs-make/Sortable.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js"></script>
|
||||
<script>
|
||||
const updateTemplateTaskList = () => {
|
||||
let tasks = []
|
||||
$('#tasks .taskInput').each((index, taskInput) => {
|
||||
tasks.push($(taskInput).val())
|
||||
})
|
||||
$('#id_task_list').val(JSON.stringify(tasks))
|
||||
}
|
||||
|
||||
const removeTask = (btn) => {
|
||||
$(btn).parents('tr').remove()
|
||||
updateTemplateTaskList()
|
||||
}
|
||||
const removeTask = (btn) => {
|
||||
$(btn).parents('tr').remove()
|
||||
updateTemplateTaskList()
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$('#addTask').on('click', () => {
|
||||
$('#tasks').append(`{% include 'helpdesk/include/template_task_form_row.html' %}`)
|
||||
})
|
||||
$(() => {
|
||||
$('#addTask').on('click', () => {
|
||||
$('#tasks').append(`{% include 'helpdesk/include/template_task_form_row.html' %}`)
|
||||
})
|
||||
|
||||
$('#tasks').sortable({
|
||||
handle: '.handle',
|
||||
onChange: updateTemplateTaskList
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
$('#tasks').sortable({
|
||||
handle: '.handle',
|
||||
onChange: updateTemplateTaskList
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n humanize %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseDates"
|
||||
@@ -11,11 +11,19 @@
|
||||
<div class="collapse row gx-3 my-3" id="collapseDates">
|
||||
<div class="col">
|
||||
<label class="form-label" for="id_date_from">{% translate "Date (From)" %}</label>
|
||||
<input class="form-control" type="text" name="date_from" value="{{ query_params.filtering.created__gte }}" id="id_date_from" />
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="date_from"
|
||||
value="{{ query_params.filtering.created__gte }}"
|
||||
id="id_date_from" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label" for="id_date_to">{% translate "Date (To)" %}</label>
|
||||
<input class="form-control" type="text" name="date_to" value="{{ query_params.filtering.created__lte }}" id="id_date_to" />
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="date_to"
|
||||
value="{{ query_params.filtering.created__lte }}"
|
||||
id="id_date_to" />
|
||||
</div>
|
||||
<div class="form-text">{% translate "Use YYYY-MM-DD date format, eg 2018-01-30" %}</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static i18n humanize in_list %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseKbitems"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n humanize %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseKeywords"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static i18n humanize in_list %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseOwner"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n humanize static in_list %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapsePriority"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static i18n humanize in_list %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseQueue"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n humanize static %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseSorting"
|
||||
@@ -11,40 +11,34 @@
|
||||
<div class="collapse show my-3" id="collapseSorting">
|
||||
<label id="sort-by" class="form-label" for="id_sort">{% translate "Sorting" %}</label>
|
||||
<select class="form-select" id="id_sort" name="sort">
|
||||
<option value='id'{% if query_params.sorting == "id" %} selected='selected'{% endif %}>
|
||||
{% translate "Ticket" %}
|
||||
</option>
|
||||
<option value='created'{% if query_params.sorting == "created" %} selected='selected'{% endif %}>
|
||||
<option value='id'{% if query_params.sorting == "id" %} selected{% endif %}>{% translate "Ticket" %}</option>
|
||||
<option value='created'{% if query_params.sorting == "created" %} selected{% endif %}>
|
||||
{% translate "Created" %}
|
||||
</option>
|
||||
<option value='last_followup'{% if query_params.sorting == "last_followup" %} selected='selected'{% endif %}>
|
||||
<option value='last_followup'{% if query_params.sorting == "last_followup" %} selected{% endif %}>
|
||||
{% translate "Last Followup" %}
|
||||
</option>
|
||||
<option value='due_date'{% if query_params.sorting == "due_date" %} selected='selected'{% endif %}>
|
||||
<option value='due_date'{% if query_params.sorting == "due_date" %} selected{% endif %}>
|
||||
{% translate "Due Date" %}
|
||||
</option>
|
||||
<option value='title'{% if query_params.sorting == "title" %} selected='selected'{% endif %}>
|
||||
{% translate "Title" %}
|
||||
</option>
|
||||
<option value='queue'{% if query_params.sorting == "queue" %} selected='selected'{% endif %}>
|
||||
{% translate "Queue" %}
|
||||
</option>
|
||||
<option value='status'{% if query_params.sorting == "status" %} selected='selected'{% endif %}>
|
||||
{% translate "Status" %}
|
||||
</option>
|
||||
<option value='priority'{% if query_params.sorting == "priority" %} selected='selected'{% endif %}>
|
||||
<option value='title'{% if query_params.sorting == "title" %} selected{% endif %}>{% translate "Title" %}</option>
|
||||
<option value='queue'{% if query_params.sorting == "queue" %} selected{% endif %}>{% translate "Queue" %}</option>
|
||||
<option value='status'
|
||||
{% if query_params.sorting == "status" %}
|
||||
selected{% endif %}>{% translate "Status" %}</option>
|
||||
<option value='priority'{% if query_params.sorting == "priority" %} selected{% endif %}>
|
||||
{% translate "Priority" %}
|
||||
</option>
|
||||
<option value='assigned_to'{% if query_params.sorting == "assigned_to" %} selected='selected'{% endif %}>
|
||||
<option value='assigned_to'{% if query_params.sorting == "assigned_to" %} selected{% endif %}>
|
||||
{% translate "Owner" %}
|
||||
</option>
|
||||
<option value='submitter_email'{% if query_params.sorting == "submitter_email" %} selected='selected'{% endif %}>
|
||||
<option value='submitter_email'{% if query_params.sorting == "submitter_email" %} selected{% endif %}>
|
||||
{% translate "Submitter E-Mail" %}
|
||||
</option>
|
||||
{% if helpdesk_settings.HELPDESK_KB_ENABLED %}
|
||||
<option value='kbitem'{% if query_params.sorting == "kbitem" %} selected='selected'{% endif %}>
|
||||
{% translate "KB Item" %}
|
||||
</option>
|
||||
<option value='kbitem'
|
||||
{% if query_params.sorting == "kbitem" %}
|
||||
selected{% endif %}>{% translate "KB Item" %}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
<div class="form-check mt-3">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static i18n humanize in_list %}
|
||||
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-secondary-subtle text-secondary-emphasis"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseStatus"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<tr>
|
||||
{{ form.id }}
|
||||
<td title="Drag & Drop" class="text-end handle">
|
||||
<i class="fas fa-grip-vertical"></i>
|
||||
{{ form.position }}
|
||||
{{ form.position.errors }}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.description }}
|
||||
{{ form.description.errors }}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.DELETE }}
|
||||
{{ form.DELETE.errors }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ form.id }}
|
||||
<td title="Drag & Drop" class="handle">
|
||||
<i class="fas fa-grip-vertical text-body-secondary"></i>
|
||||
{{ form.position }}
|
||||
{{ form.position.errors }}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.description }}
|
||||
{{ form.description.errors }}
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-check">{{ form.DELETE }}</div>
|
||||
{{ form.DELETE.errors }}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<tr>
|
||||
<td title="Drag & Drop" class="text-center handle">
|
||||
<i class="fas fa-grip-vertical"></i>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control taskInput" oninput="updateTemplateTaskList()" required value="{{ value }}">
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-sm btn-danger" onclick="removeTask(this)">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<td title="Drag & Drop" class="handle ms-3">
|
||||
<i class="fas fa-grip-vertical text-body-secondary"></i>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control taskInput" oninput="updateTemplateTaskList()" required value="{{ value }}" />
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm bg-body-tertiary border" onclick="removeTask(this)">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
{% if category.queue %}
|
||||
{% if iframe %}
|
||||
<a href="{% url 'helpdesk:submit_iframe' %}?queue={{ category.queue.pk }}&_readonly_fields_=queue&{{ query_param_string }}"
|
||||
class="btn btn-light ms-auto">
|
||||
class="btn bg-body-tertiary border ms-auto">
|
||||
{% translate "Contact a human" %}
|
||||
<i class="fa fa-envelope ms-2"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
{# Create ticket link #}
|
||||
<a href="{% url 'helpdesk:submit' %}?queue={{ category.queue.pk }}&_readonly_fields_=queue&{{ query_param_string }}"
|
||||
class="btn btn-light ms-auto">
|
||||
class="btn bg-body-tertiary border ms-auto">
|
||||
{% translate "Create Ticket" %}
|
||||
<i class="fa fa-plus ms-2"></i>
|
||||
</a>
|
||||
@@ -73,13 +73,13 @@
|
||||
{% endif %}
|
||||
{% if iframe %}
|
||||
<a href="{% url 'helpdesk:submit_iframe' %}?{% if category.queue %}queue={{ category.queue.pk }}&_readonly_fields_=queue&{% endif %}kbitem={{ item.id }}&{{ query_param_string }}"
|
||||
class="btn btn-light">
|
||||
class="btn bg-body-tertiary border">
|
||||
{% translate "Contact a human" %}
|
||||
<i class="fa fa-envelope ms-1"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url 'helpdesk:submit' %}?{% if category.queue %}queue={{ category.queue.pk }}&_readonly_fields_=queue&{% endif %}kbitem={{ item.id }}&{{ query_param_string }}"
|
||||
class="btn btn-light">
|
||||
class="btn bg-body-tertiary border">
|
||||
{% translate "Create New Ticket" %}
|
||||
<i class="fa fa-plus ms-1"></i>
|
||||
</a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n static helpdesk_staff %}
|
||||
|
||||
{% include "helpdesk/custom_navigation_header.html" %}
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary sticky-top">
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary border-bottom sticky-top">
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex align-items-center">
|
||||
<a class="navbar-brand" href="{% url 'helpdesk:home' %}">
|
||||
@@ -36,7 +36,7 @@
|
||||
<input type='hidden' name='status' value='2' />
|
||||
<input type='hidden' name='status' value='3' />
|
||||
<input type='hidden' name='search_type' value='header' />
|
||||
<button class="btn btn-outline-secondary" type="submit">
|
||||
<button class="btn bg-body-tertiary border" type="submit">
|
||||
<i class="fas fa-search"></i> {% translate "Go" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class="card-body m-3">
|
||||
<h5 class="text-center py-3">{% translate "Logout successful" %}</h5>
|
||||
<div class="d-grid gap-3 py-3">
|
||||
<a class="btn btn-outline-primary" href="{% url 'helpdesk:login' %}">
|
||||
<a class="btn btn-primary" href="{% url 'helpdesk:login' %}">
|
||||
<i class="fas fa-fw fa-sign-in-alt"></i>
|
||||
{% translate "Log In" %}
|
||||
</a>
|
||||
|
||||
@@ -32,350 +32,409 @@
|
||||
</div>
|
||||
{% else %}
|
||||
{# Nav Tabs #}
|
||||
<div class="d-flex justify-content-between align-items-center me-3">
|
||||
<ul class="nav nav-underline ms-3" id="ticketTab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active"
|
||||
id="followup-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#followup-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="followup-tab-pane"
|
||||
aria-selected="true">{% translate "Follow ups" %}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link"
|
||||
id="respond-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#respond-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="respond-tab-pane"
|
||||
aria-selected="false">{% translate "Respond" %}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{% if followups %}
|
||||
<button type="button"
|
||||
id="followup-sort-toggle"
|
||||
class="btn bg-light-subtle text-light-emphasis btn-sm"
|
||||
data-order="{% if helpdesk_settings.HELPDESK_FOLLOWUP_NEWEST_FIRST %}newest_first{% else %}oldest_first{% endif %}">
|
||||
<i class="fa-solid fa-arrow-down-short-wide me-1"></i>
|
||||
<span id="followup-sort-toggle-label">
|
||||
{% if helpdesk_settings.HELPDESK_FOLLOWUP_NEWEST_FIRST %}
|
||||
{% translate "Newest first" %}
|
||||
{% else %}
|
||||
{% translate "Oldest first" %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
{# Followup Pane #}
|
||||
{% if followups %}
|
||||
<div class="card">
|
||||
<div class="card-header bg-body-tertiary pb-0">
|
||||
<ul class="nav nav-underline" id="ticketTab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active"
|
||||
id="followup-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#followup-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="followup-tab-pane"
|
||||
aria-selected="true">{% translate "Follow ups" %}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link"
|
||||
id="respond-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#respond-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="respond-tab-pane"
|
||||
aria-selected="false">{% translate "Respond" %}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body px-0">
|
||||
<div class="tab-content" id="myTabContent">
|
||||
{% if followups %}
|
||||
{% load ticket_to_link followup_permissions %}
|
||||
|
||||
{% load ticket_to_link followup_permissions %}
|
||||
|
||||
<div class="tab-pane fade show active" id="followup-tab-pane" role="tabpanel" aria-labelledby="followup-tab" tabindex="0">
|
||||
<div class="list-group list-group-flush my-3" id="followup-list">
|
||||
{% for followup in followups %}
|
||||
<div class="list-group-item list-group-item-action followup-item followup-item-{{ followup.direction }}">
|
||||
<div class="d-flex align-items-center">
|
||||
<h6 class="mb-0">{{ followup.title|escape|num_to_link }}</h6>
|
||||
<span class="text-body-secondary ms-auto">
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET and followup.time_spent_formated %}
|
||||
<i class="fa-regular fa-clock fa-sm"></i>
|
||||
<small>{{ followup.time_spent_formated }} ·</small>
|
||||
{% endif %}
|
||||
{# Name the audience as well as coloring the row, so the #}
|
||||
{# distinction survives for color blind users and in print. #}
|
||||
<span class="badge followup-item-badge">
|
||||
{% if followup.direction == 'internal' %}
|
||||
<i class="fa-solid fa-lock fa-sm me-1"></i>{% translate "Private" %}
|
||||
{% elif followup.direction == 'outbound' %}
|
||||
<i class="fa-solid fa-arrow-right fa-sm me-1"></i>{% translate "To submitter" %}
|
||||
{% else %}
|
||||
<i class="fa-solid fa-arrow-left fa-sm me-1"></i>{% translate "From submitter" %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</span>
|
||||
{# Skip the menu entirely rather than open an empty one: most #}
|
||||
{# follow-ups offer no action to most staff members. #}
|
||||
{% if followup|can_edit_followup:request.user or followup|can_delete_followup:request.user %}
|
||||
<div class="dropdown ms-2">
|
||||
<a class="btn bg-body-tertiary btn-sm" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% if followup|can_edit_followup:request.user %}
|
||||
<li>
|
||||
<a href="{% url 'helpdesk:followup_edit' ticket.id followup.id %}" class="dropdown-item">
|
||||
<i class="fa-regular fa-edit me-1"></i>
|
||||
{% translate "Edit" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if followup|can_delete_followup:request.user %}
|
||||
<li>
|
||||
<a href="{% url 'helpdesk:followup_delete' ticket.id followup.id %}" class="dropdown-item link-danger">
|
||||
<i class="fa-regular fa-trash-can me-1"></i>
|
||||
{% translate "Delete" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<small class="text-secondary">
|
||||
{{ followup.date|naturaltime }} {% if followup.user %}· {{ followup.user }}{% endif %}
|
||||
</small>
|
||||
{% if followup.email_recipients is not None %}
|
||||
<small class="text-secondary d-block">
|
||||
<i class="fa-regular fa-envelope fa-sm me-1"></i>
|
||||
{% if followup.email_recipients %}
|
||||
{% blocktranslate with recipients=followup.email_recipients|join:", " %}Emailed: {{ recipients }}{% endblocktranslate %}
|
||||
{# Followup Pane #}
|
||||
<div class="tab-pane fade show active"
|
||||
id="followup-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="followup-tab"
|
||||
tabindex="0">
|
||||
{# sort button #}
|
||||
<div class="d-flex justify-content-end mb-2">
|
||||
<button type="button"
|
||||
id="followup-sort-toggle"
|
||||
class="btn bg-light-subtle text-light-emphasis btn-sm me-3"
|
||||
data-order="{% if helpdesk_settings.HELPDESK_FOLLOWUP_NEWEST_FIRST %}newest_first{% else %}oldest_first{% endif %}">
|
||||
<i class="fa-solid fa-arrow-down-short-wide me-1"></i>
|
||||
<span id="followup-sort-toggle-label">
|
||||
{% if helpdesk_settings.HELPDESK_FOLLOWUP_NEWEST_FIRST %}
|
||||
{% translate "Newest first" %}
|
||||
{% else %}
|
||||
{% translate "Emailed: no one" %}
|
||||
{% translate "Oldest first" %}
|
||||
{% endif %}
|
||||
</small>
|
||||
{% endif %}
|
||||
{# Ticket comments #}
|
||||
{% if followup.comment %}
|
||||
<div class="mt-3">{{ followup.get_markdown|urlizetrunc:50|num_to_link }}</div>
|
||||
{% endif %}
|
||||
{# Changes to ticket #}
|
||||
{% if followup.ticketchange_set.all %}
|
||||
<ul class="list-unstyled mt-3">
|
||||
{% for change in followup.ticketchange_set.all %}
|
||||
<li>
|
||||
{% blocktranslate with change.field as field and change.old_value as old_value and change.new_value as new_value %}
|
||||
Changed {{ field }} from {{ old_value }} to {{ new_value }}.
|
||||
{% endblocktranslate %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{# Attachments #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS and followup.followupattachment_set.all %}
|
||||
<h6 class="mt-3">{% translate "Attachments" %}</h6>
|
||||
<ul>
|
||||
{% for attachment in followup.followupattachment_set.all %}
|
||||
<li>
|
||||
<a href="{{ attachment.file.url }}" target="_blank">{{ attachment.filename }}</a>
|
||||
<small class="text-secondary">({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})</small>
|
||||
{% if followup.user and request.user == followup.user %}
|
||||
<a href="{% url 'helpdesk:attachment_del' ticket.id attachment.id %}" class="text-secondary">
|
||||
<i class="fa-regular fa-trash-can fa-sm ms-2"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Respond Pane #}
|
||||
<div class="tab-pane fade" id="respond-tab-pane" role="tabpanel" aria-labelledby="respond-tab" tabindex="0">
|
||||
<div class="card my-3 border-0">
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'helpdesk:update' ticket.id %}" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{% if preset_replies %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="id_preset">{% translate "Use a Pre-set Reply (Optional)" %}</label>
|
||||
<select class="form-select" name="preset" id="id_preset">
|
||||
<option value=''>------</option>
|
||||
{% for preset in preset_replies %}<option value="{{ preset.id }}">{{ preset.name }}</option>{% endfor %}
|
||||
</select>
|
||||
<span class="form-text">
|
||||
{% translate "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." %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Comment text box #}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="commentBox">{% translate "Comment / Resolution" %}</label>
|
||||
<textarea class="form-control" rows="3" name="comment" id="commentBox">{{ xform.comment }}</textarea>
|
||||
{% url "helpdesk:help_context" as context_help_url %}
|
||||
{% blocktranslate %}
|
||||
<p class="form-text">You can insert ticket and queue details in your message. For more information, see the <a href="{{ context_help_url }}" target="_blank">context help page.</a></p>
|
||||
{% endblocktranslate %}
|
||||
</button>
|
||||
</div>
|
||||
{# Status radio buttons #}
|
||||
<fieldset class="mb-3">
|
||||
<legend class="form-label">{% translate "New Status" %}</legend>
|
||||
{% for status_choice in ticket.get_allowed_status_flow %}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="radio"
|
||||
name="new_status"
|
||||
value="{{ status_choice.0 }}"
|
||||
id="st_{{ status_choice.1|lower }}"
|
||||
{% if not ticket.can_be_resolved %}
|
||||
disabled='disabled'{% endif %}
|
||||
{% if ticket.status == status_choice.0 %}
|
||||
checked="checked"{% endif %} />
|
||||
<label for="st_{{ status_choice.1|lower }}"
|
||||
class="form-check-label
|
||||
{% if ticket.status == status_choice.0 %}active
|
||||
{% endif %}radio-inline">{{ status_choice.1 }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if not ticket.can_be_resolved %}
|
||||
<div class="form-text">{% translate "This ticket cannot be resolved or closed until the tickets it depends on are resolved." %}</div>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{# Public update checkbox #}
|
||||
{% if helpdesk_settings.HELPDESK_UPDATE_PUBLIC_DEFAULT %}
|
||||
<input type="hidden" name="public" value="1" />
|
||||
{% else %}
|
||||
<div class="form-check mb-3">
|
||||
<input class="form-check-input" type="checkbox" name="public" value="1" id="id_public" checked="checked" />
|
||||
<label class="form-label" for="id_public">{% translate "Is this update public? (Optional)" %}</label>
|
||||
<div class="form-text">{% translate "If this is public, the submitter will be e-mailed your comment or resolution." %}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Time spent widget #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET and user.is_staff %}
|
||||
<div class="w-25 mb-3">
|
||||
<label class="form-label" for="id_time_spent">{% translate "Time spent (Optional)" %}</label>
|
||||
<input class="form-control" name="time_spent" type="time" value="{% if form.errors %}{{ xform.time_spent }}{% endif %}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Ticket Details #}
|
||||
<p>
|
||||
<a class="btn btn-light"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseDetails"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseDetails">{% translate "Update ticket details" %}</a>
|
||||
</p>
|
||||
<div class="collapse" id="collapseDetails">
|
||||
{# Extra Ticket Details form #}
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="id_title">{% translate "Title" %}</label>
|
||||
<input class="form-control" name="title" value="{{ ticket.title|escape }}" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_owner">{% translate "Owner" %}</label>
|
||||
<select class="form-select" id="id_owner" name="owner">
|
||||
<option value="0">{% translate "Unassigned" %}</option>
|
||||
{% for u in assignable_users %}
|
||||
<option value="{{ u.id }}" {% if u.id == ticket.assigned_to.id %} selected{% endif %}>{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_priority">{% translate "Priority" %}</label>
|
||||
<select class="form-select" id="id_priority" name="priority">
|
||||
{% for p in priorities %}
|
||||
{% if p.0 == ticket.priority %}
|
||||
<option value="{{ p.0 }}" selected="selected">{{ p.1 }}</option>
|
||||
{% else %}
|
||||
<option value="{{ p.0 }}">{{ p.1 }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% if queues|length > 1 %}
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_queue">{% translate "Queue" %}</label>
|
||||
<select class="form-select" id="id_queue" name="queue">
|
||||
{% for queue_id, queue_name in queues %}
|
||||
<option value="{{ queue_id }}" {% if queue_id == ticket.queue.id %} selected{% endif %}>{{ queue_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% else %}
|
||||
<input type="hidden" id="id_queue" name="queue" value="{{ ticket.queue.id }}" />
|
||||
<ul id="followup-list" class="list-group list-group-flush mb-3">
|
||||
{% for followup in followups %}
|
||||
<li class="list-group-item list-group-item-action">
|
||||
<div class="d-flex align-items-center">
|
||||
{% if followup.direction == "outbound" %}
|
||||
<span class="p-1 me-2 bg-success border border-2 border-success-subtle rounded-circle"></span>
|
||||
{% elif followup.direction == "inbound" %}
|
||||
<span class="p-1 me-2 bg-warning border border-2 border-warning-subtle rounded-circle"></span>
|
||||
{% endif %}
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_due_date">{% translate "Due on" %}</label>
|
||||
{{ form.due_date }}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{# ticket merge form #}
|
||||
{{ customfields_form }}
|
||||
<h6 class="mb-0">{{ followup.title|escape|num_to_link }}</h6>
|
||||
<span class="text-body-secondary ms-auto">
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET and followup.time_spent_formated %}
|
||||
<i class="fa-regular fa-clock fa-sm"></i>
|
||||
<small>{{ followup.time_spent_formated }} ·</small>
|
||||
{% endif %}
|
||||
{% if followup.direction == "internal" %}
|
||||
<span class="badge bg-light-subtle text-light-emphasis">
|
||||
<i class="fa-solid fa-lock fa-sm me-1"></i>{% translate "Private" %}
|
||||
</span>
|
||||
{% elif followup.direction == "outbound" %}
|
||||
<span class="badge bg-success-subtle text-success-emphasis">
|
||||
<i class="fa-solid fa-arrow-right fa-sm me-1"></i>{% translate "To submitter" %}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis">
|
||||
<i class="fa-solid fa-arrow-left fa-sm me-1"></i>{% translate "From submitter" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
{# Quick actions dropdown #}
|
||||
{% if followup|can_edit_followup:request.user or followup|can_delete_followup:request.user %}
|
||||
<div class="dropdown ms-2">
|
||||
<a class="btn bg-body-tertiary btn-sm"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="fa-solid fa-ellipsis-vertical"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% if followup|can_edit_followup:request.user %}
|
||||
<li>
|
||||
<a href="{% url 'helpdesk:followup_edit' ticket.id followup.id %}"
|
||||
class="dropdown-item small">
|
||||
<i class="fa-regular fa-edit me-1"></i>
|
||||
{% translate "Edit" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if followup|can_delete_followup:request.user %}
|
||||
<li>
|
||||
<a href="{% url 'helpdesk:followup_delete' ticket.id followup.id %}"
|
||||
class="dropdown-item link-danger text-sm">
|
||||
<i class="fa-regular fa-trash-can me-1"></i>
|
||||
{% translate "Delete" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<small class="text-body-secondary">
|
||||
{{ followup.date|naturaltime }} {% if followup.user %}· {{ followup.user }}{% endif %}
|
||||
</small>
|
||||
{% if followup.email_recipients is not None %}
|
||||
<small class="text-body-secondary d-block">
|
||||
<i class="fa-regular fa-envelope fa-sm me-1"></i>
|
||||
{% if followup.email_recipients %}
|
||||
{% blocktranslate with recipients=followup.email_recipients|join:", " %}Emailed: {{ recipients }}{% endblocktranslate %}
|
||||
{% else %}
|
||||
{% translate "Emailed: no one" %}
|
||||
{% endif %}
|
||||
</small>
|
||||
{% endif %}
|
||||
{# Ticket comments #}
|
||||
{% if followup.comment %}
|
||||
<div class="mt-3">{{ followup.get_markdown|urlizetrunc:50|num_to_link }}</div>
|
||||
{% endif %}
|
||||
{# Changes to ticket #}
|
||||
{% if followup.ticketchange_set.all %}
|
||||
<ul class="mt-3">
|
||||
{% for change in followup.ticketchange_set.all %}
|
||||
<li class="small">
|
||||
{% blocktranslate with change.field as field and change.old_value as old_value and change.new_value as new_value %}
|
||||
Changed {{ field }} from {{ old_value }} to {{ new_value }}.
|
||||
{% endblocktranslate %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{# Attachments #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS and followup.followupattachment_set.all %}
|
||||
<h6 class="mt-3">{% translate "Attachments" %}</h6>
|
||||
<ul>
|
||||
{% for attachment in followup.followupattachment_set.all %}
|
||||
<li>
|
||||
<a href="{{ attachment.file.url }}" target="_blank">{{ attachment.filename }}</a>
|
||||
<small class="text-body-secondary">({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})</small>
|
||||
{% if followup.user and request.user == followup.user %}
|
||||
<a href="{% url 'helpdesk:attachment_del' ticket.id attachment.id %}"
|
||||
class="text-body-secondary">
|
||||
<i class="fa-regular fa-trash-can fa-sm ms-2"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Respond Pane #}
|
||||
<div class="tab-pane fade" id="respond-tab-pane" role="tabpanel" aria-labelledby="respond-tab" tabindex="0">
|
||||
<div class="card border-0 mb-3">
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'helpdesk:update' ticket.id %}" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 col-lg-5">
|
||||
|
||||
{% if preset_replies %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label"
|
||||
for="id_preset">{% translate "Use a Pre-set Reply (Optional)" %}</label>
|
||||
<select class="form-select" name="preset" id="id_preset">
|
||||
<option value=''>------</option>
|
||||
{% for preset in preset_replies %}<option value="{{ preset.id }}">{{ preset.name }}</option>{% endfor %}
|
||||
</select>
|
||||
<span class="form-text">
|
||||
{% translate "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." %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Comment text box #}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="commentBox">{% translate "Comment / Resolution" %}</label>
|
||||
<textarea class="form-control"
|
||||
rows="3"
|
||||
name="comment"
|
||||
id="commentBox">{{ xform.comment }}</textarea>
|
||||
{% url "helpdesk:help_context" as context_help_url %}
|
||||
{% blocktranslate %}
|
||||
<p class="form-text">
|
||||
You can insert ticket and queue details in your message.
|
||||
For more information, see the <a href="{{ context_help_url }}" target="_blank">context help page.</a>
|
||||
</p>
|
||||
{% endblocktranslate %}
|
||||
</div>
|
||||
{# Status radio buttons #}
|
||||
<fieldset class="mb-3">
|
||||
<span class="form-label">{% translate "New Status" %}</span>
|
||||
{% for status_choice in ticket.get_allowed_status_flow %}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="radio"
|
||||
name="new_status"
|
||||
value="{{ status_choice.0 }}"
|
||||
id="st_{{ status_choice.1|lower }}"
|
||||
{% if not ticket.can_be_resolved %}disabled{% endif %}
|
||||
{% if ticket.status == status_choice.0 %}checked{% endif %} />
|
||||
{# djlint:off #}
|
||||
<label for="st_{{ status_choice.1|lower }}"
|
||||
class="form-check-label radio-inline {% if ticket.status == status_choice.0 %}active {% endif %}">
|
||||
{{ status_choice.1 }}
|
||||
</label>
|
||||
{# djlint: on #}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if not ticket.can_be_resolved %}
|
||||
<div class="form-text">{% translate "This ticket cannot be resolved or closed until the tickets it depends on are resolved." %}</div>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{# Public update checkbox #}
|
||||
{% if helpdesk_settings.HELPDESK_UPDATE_PUBLIC_DEFAULT %}
|
||||
<input type="hidden" name="public" value="1" />
|
||||
{% else %}
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
name="public"
|
||||
value="1"
|
||||
id="id_public"
|
||||
switch
|
||||
checked />
|
||||
<label class="form-label"
|
||||
for="id_public">{% translate "Is this update public? (Optional)" %}</label>
|
||||
<div class="form-text">{% translate "If this is public, the submitter will be e-mailed your comment or resolution." %}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Time spent widget #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET and user.is_staff %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="id_time_spent">{% translate "Time spent (Optional)" %}</label>
|
||||
<input class="form-control"
|
||||
name="time_spent"
|
||||
type="time"
|
||||
value="{% if form.errors %}{{ xform.time_spent }}{% endif %}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# Checklists #}
|
||||
{% if ticket.checklists.exists %}
|
||||
<p>
|
||||
<a class="btn btn-light"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseChecklists"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseChecklists">{% translate "Update checklists" %}</a>
|
||||
</p>
|
||||
<div class="collapse" id="collapseChecklists">
|
||||
<div class="row">
|
||||
{% for checklist in ticket.checklists.all %}
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card border-0 mb-3">
|
||||
<h6 class="card-title">{{ checklist }}</h6>
|
||||
<div class="list-group list-group-flush">
|
||||
{% for task in checklist.tasks.all %}
|
||||
<div class="list-group-item"
|
||||
{% if task.completion_date %}
|
||||
title="{% translate "Completed on" %} {{ task.completion_date }}"
|
||||
{% endif %}>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="task-{{ task.id }}"
|
||||
name="checklist-{{ checklist.id }}"
|
||||
value="{{ task.id }}"
|
||||
{% if task.completion_date %}
|
||||
checked{% endif %} />
|
||||
<label class="form-check-label" for="task-{{ task.id }}">{{ task }}</label>
|
||||
</div>
|
||||
{# Optional form content #}
|
||||
{# Three toggle buttons #}
|
||||
<div class="d-grid gap-2 d-md-block mb-3">
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseDetails"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseDetails">{% translate "Update ticket details" %}</a>
|
||||
{% if ticket.checklists.exists %}
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseChecklists"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseChecklists">{% translate "Update checklists" %}</a>
|
||||
{% endif %}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseAttachments"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseAttachments">{% translate "Attach File(s)" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{# Extra Ticket Details form #}
|
||||
<div class="collapse my-3" id="collapseDetails">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<div class="card card-body border-0 bg-body-tertiary">
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="id_title">{% translate "Title" %}</label>
|
||||
<input class="form-control" name="title" value="{{ ticket.title|escape }}" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_owner">{% translate "Owner" %}</label>
|
||||
<select class="form-select" id="id_owner" name="owner">
|
||||
<option value="0">{% trans "Unassigned" %}</option>
|
||||
{% for u in assignable_users %}
|
||||
<option value="{{ u.id }}"
|
||||
{% if u.id == ticket.assigned_to.id %}
|
||||
selected{% endif %}>{{ u }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_priority">{% translate "Priority" %}</label>
|
||||
<select class="form-select" id="id_priority" name="priority">
|
||||
{% for p in priorities %}
|
||||
{% if p.0 == ticket.priority %}
|
||||
<option value="{{ p.0 }}" selected="selected">{{ p.1 }}</option>
|
||||
{% else %}
|
||||
<option value="{{ p.0 }}">{{ p.1 }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% if queues|length > 1 %}
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_queue">{% translate "Queue" %}</label>
|
||||
<select class="form-select" id="id_queue" name="queue">
|
||||
{% for queue_id, queue_name in queues %}
|
||||
<option value="{{ queue_id }}"
|
||||
{% if queue_id == ticket.queue.id %}
|
||||
selected{% endif %}>{{ queue_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<input type="hidden" id="id_queue" name="queue" value="{{ ticket.queue.id }}" />
|
||||
{% endif %}
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="id_due_date">{% translate "Due on" %}</label>
|
||||
{{ form.due_date }}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{# ticket merge form #}
|
||||
{{ customfields_form }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Attachments #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
{% if form.errors.attachment %}<small class="error">{{ form.errors.attachment }}</small>{% endif %}
|
||||
<p>
|
||||
<a class="btn btn-light"
|
||||
data-bs-toggle="collapse"
|
||||
href="#collapseAttachments"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseAttachments">{% translate "Attach File(s)" %}</a>
|
||||
</p>
|
||||
<div class="collapse mb-3" id="collapseAttachments">
|
||||
<div class="add_file_fields_wrap">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="file0">{% translate "Browse..." %}</label>
|
||||
<input class="form-control" type="file" name="attachment" id="file0" multiple />
|
||||
</div>
|
||||
</div>
|
||||
<button class="add_file_field_button btn btn-outline-primary btn-sm">{% translate "Add Another File" %}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="btn btn-primary" type="submit">{% translate "Update This Ticket" %}</button>
|
||||
</form>
|
||||
{# Checklists #}
|
||||
{% if ticket.checklists.exists %}
|
||||
<div class="collapse" id="collapseChecklists">
|
||||
<div class="row">
|
||||
{% for checklist in ticket.checklists.all %}
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card border-0 mb-3">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<h6 class="mb-0">{{ checklist }}</h6>
|
||||
</li>
|
||||
{% for task in checklist.tasks.all %}
|
||||
<li class="list-group-item"
|
||||
{% if task.completion_date %}
|
||||
title="{% translate "Completed on" %} {{ task.completion_date }}"
|
||||
{% endif %}>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="task-{{ task.id }}"
|
||||
name="checklist-{{ checklist.id }}"
|
||||
value="{{ task.id }}"
|
||||
{% if task.completion_date %}
|
||||
checked{% endif %} />
|
||||
<label class="form-check-label" for="task-{{ task.id }}">{{ task }}</label>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Attachments #}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
{% if form.errors.attachment %}<small class="error">{{ form.errors.attachment }}</small>{% endif %}
|
||||
<div class="collapse mb-3" id="collapseAttachments">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 col-lg-5">
|
||||
<div class="add_file_fields_wrap">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="file0">{% translate "Browse..." %}</label>
|
||||
<input class="form-control" type="file" name="attachment" id="file0" multiple />
|
||||
</div>
|
||||
</div>
|
||||
<button class="add_file_field_button btn btn-link btn-sm"
|
||||
type="button">{% translate "Add Another File" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="btn btn-success" type="submit">{% translate "Save" %}</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade"
|
||||
@@ -398,7 +457,8 @@
|
||||
{{ checklist_form }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-secondary" href="{% url 'helpdesk:checklist_templates' %}">{% translate "Manage templates" %}</a>
|
||||
<a class="btn btn-secondary"
|
||||
href="{% url 'helpdesk:checklist_templates' %}">{% translate "Manage templates" %}</a>
|
||||
<button type="submit" class="btn btn-primary">{% translate "Add" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -409,7 +469,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block helpdesk_js %}
|
||||
<script type='text/javascript' language='javascript'>
|
||||
<script language='javascript'>
|
||||
$(function() {
|
||||
$("#id_due_date").datepicker({
|
||||
dateFormat: 'yy-mm-dd'
|
||||
@@ -417,7 +477,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type='text/javascript' language='javascript'>
|
||||
<script language='javascript'>
|
||||
$(document).ready(function() {
|
||||
$('#id_preset').change(function() {
|
||||
preset = $('#id_preset').val();
|
||||
@@ -458,7 +518,6 @@
|
||||
$button.data('order', newOrder);
|
||||
$('#followup-sort-toggle-label').text(label);
|
||||
});
|
||||
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
// lists for file input change events, then updates the associated text label
|
||||
// with the file name selected
|
||||
@@ -475,7 +534,6 @@
|
||||
});
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
// this function listens for changes on any file input, and
|
||||
// emits the appropriate event to update the input's text.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{% load i18n static humanize ticket_to_link helpdesk_util %}
|
||||
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<div class="card border-0 mb-3">
|
||||
<div class="card-body pt-0">
|
||||
{# Heading & description #}
|
||||
<div class="d-flex">
|
||||
<h2>{{ ticket.title }} <span class="badge rounded-pill bg-light-subtle text-light-emphasis">#{{ ticket.id }}</span> </h2>
|
||||
<h2>{{ ticket.title }} <span class="badge bg-body-tertiary text-secondary-emphasis border">#{{ ticket.id }}</span> </h2>
|
||||
<div class="dropdown ms-auto">
|
||||
<button class="btn bg-light-subtle text-light-emphasis dropdown-toggle"
|
||||
<button class="btn bg-body-tertiary border dropdown-toggle"
|
||||
type="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">{% translate "Actions" %}</button>
|
||||
@@ -53,7 +53,8 @@
|
||||
<hr />
|
||||
<p class="mb-0">
|
||||
{% if "Resolved" == ticket.get_status_display %}
|
||||
<a href="?close" class="alert-link">{% translate "Accept and Close" %}<i class="fa-solid fa-arrow-right ms-2"></i></a>
|
||||
<a href="?close"
|
||||
class="alert-link">{% translate "Accept and Close" %}<i class="fa-solid fa-arrow-right ms-2"></i></a>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
@@ -61,24 +62,27 @@
|
||||
{# Ticket description #}
|
||||
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-3">
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Due Date" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Due Date" %}</small>
|
||||
<p>
|
||||
{{ ticket.due_date|date:"DATETIME_FORMAT" }}
|
||||
{% if ticket.due_date %}
|
||||
<a class="link-secondary" href="#" data-bs-toggle="tooltip" data-bs-title="{{ ticket.due_date|naturaltime }}"><i class="fa-regular fa-hourglass ms-1"></i></a>
|
||||
<a class="link-secondary"
|
||||
href="#"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-title="{{ ticket.due_date|naturaltime }}"><i class="fa-regular fa-hourglass ms-1"></i></a>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Priority" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Priority" %}</small>
|
||||
<p>{{ ticket.get_priority_display }}</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Status" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Status" %}</small>
|
||||
<p>{{ ticket.get_status }}</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Assigned to" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Assigned to" %}</small>
|
||||
<form method="post" action="{% url 'helpdesk:update' ticket.id %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="ticket_id" value="{{ ticket.id }}" />
|
||||
@@ -90,17 +94,23 @@
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<div class="input-group input-group-sm">
|
||||
<select name="owner" class="form-select">
|
||||
<option value="0" {% if not ticket.assigned_to %} disabled selected{% endif %}>{% translate "Unassigned" %}</option>
|
||||
<option value="0"
|
||||
{% if not ticket.assigned_to %}
|
||||
disabled selected{% endif %}>{% translate "Unassigned" %}</option>
|
||||
{% for user in assignable_users %}
|
||||
<option value="{{ user.id }}" {% if ticket.assigned_to and ticket.assigned_to.id == user.id %}selected{% endif %}>
|
||||
<option value="{{ user.id }}"
|
||||
{% if ticket.assigned_to and ticket.assigned_to.id == user.id %}selected{% endif %}>
|
||||
{{ user.get_full_name|default:user.username }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button class="btn btn-outline-primary" type="submit" data-bs-toggle="tooltip" title="{% translate 'Save ticket assignment' %}">
|
||||
<button class="btn bg-body-tertiary border"
|
||||
type="submit"
|
||||
data-bs-toggle="tooltip"
|
||||
title="{% translate 'Save ticket assignment' %}">
|
||||
<i class="fas fa-user-check"></i>
|
||||
</button>
|
||||
<a class="btn btn-outline-primary"
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="tooltip"
|
||||
href="?take"
|
||||
title="{% translate 'Assign this ticket to ' %}{{ request.user.email }}">
|
||||
@@ -111,25 +121,29 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Submitted by" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Submitted by" %}</small>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" value="{{ ticket.submitter_email }}" aria-label="Submitter email" disabled />
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
value="{{ ticket.submitter_email }}"
|
||||
aria-label="Submitter email"
|
||||
readonly />
|
||||
{% if user.is_superuser %}
|
||||
{% if submitter_userprofile_url %}
|
||||
<a class="btn btn-outline-primary"
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="tooltip"
|
||||
href="{{ submitter_userprofile_url }}"
|
||||
title="{% translate "Edit " %}{{ ticket.submitter_email }}{% translate " user profile" %}">
|
||||
<i class="fas fa-address-book"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-outline-primary"
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="tooltip"
|
||||
href="{% url 'helpdesk:list' %}?q={{ ticket.submitter_email }}"
|
||||
title='{% translate "Display tickets filtered for " %}{{ ticket.submitter_email }}{% translate " as a keyword" %}'>
|
||||
<i class="fas fa-search"></i>
|
||||
</a>
|
||||
<a class="btn btn-outline-primary"
|
||||
<a class="btn bg-body-tertiary border"
|
||||
data-bs-toggle="tooltip"
|
||||
href='{% url 'helpdesk:email_ignore_add' %}?email={{ ticket.submitter_email }}'
|
||||
title='{% translate "Add email address for the ticket system to ignore." %}'>
|
||||
@@ -140,27 +154,27 @@
|
||||
</div>
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Time spent" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Time spent" %}</small>
|
||||
<p>{{ ticket.time_spent_formated }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Queue" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Queue" %}</small>
|
||||
<p>{{ ticket.queue }}</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Copies to" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Copies to" %}</small>
|
||||
<div class="input-group input-group-sm">
|
||||
{% if ticket.queue.enable_notifications_on_email_events %}
|
||||
<input type="text" class="form-control" value="{{ ticketcc_string }}" disabled />
|
||||
<a class="btn btn-outline-primary btn-sm"
|
||||
<input type="text" class="form-control" value="{{ ticketcc_string }}" readonly />
|
||||
<a class="btn bg-body-tertiary border btn-sm"
|
||||
data-bs-toggle='tooltip'
|
||||
href='{% url 'helpdesk:ticket_cc' ticket.id %}'
|
||||
title='{% translate "Click here to add / remove people who should receive an e-mail whenever this ticket is updated." %}'>
|
||||
<i class="fa fa-share"></i>
|
||||
</a>
|
||||
{% if SHOW_SUBSCRIBE %}
|
||||
<a class="btn btn-outline-primary btn-sm"
|
||||
<a class="btn bg-body-tertiary border btn-sm"
|
||||
data-bs-toggle='tooltip'
|
||||
href='?subscribe'
|
||||
title='{% translate "Click here to subscribe yourself to this ticket, if you want to receive an e-mail whenever this ticket is updated." %}'>
|
||||
@@ -178,7 +192,7 @@
|
||||
</div>
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_DEPENDENCIES_ON_TICKET != False %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Resolves" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Resolves" %}</small>
|
||||
<a class="link-secondary"
|
||||
data-bs-toggle="tooltip"
|
||||
href="{% url 'helpdesk:ticket_resolves_add' ticket.id %}"
|
||||
@@ -202,7 +216,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Depends on" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Depends on" %}</small>
|
||||
<a class="link-secondary ms-1"
|
||||
data-bs-toggle="tooltip"
|
||||
href="{% url 'helpdesk:ticket_dependency_add' ticket.id %}"
|
||||
@@ -226,13 +240,13 @@
|
||||
{% endif %}
|
||||
{% if ticket.kbitem %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Knowledgebase item" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Knowledgebase item" %}</small>
|
||||
<p><a href="{{ ticket.kbitem.query_url }}">{{ ticket.kbitem|truncatechars:30 }}</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ticket.ticketcustomfieldvalue_set.exists %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Additional Info" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Additional Info" %}</small>
|
||||
<ul class="list-unstyled">
|
||||
{% for customfield in ticket.ticketcustomfieldvalue_set.all %}
|
||||
<li>
|
||||
@@ -257,7 +271,7 @@
|
||||
{% endif %}
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_ATTACHMENTS %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Attachments" %}</small>
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Attachments" %}</small>
|
||||
{% with recent_attachments=ticket_attachments|slice:":3" older_attachments=ticket_attachments|slice:"3:" %}
|
||||
<ul class="list-group list-group-flush">
|
||||
{% for attachment in recent_attachments %}
|
||||
@@ -289,8 +303,8 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col">
|
||||
<small class="text-uppercase text-secondary">{% translate "Checklists" %}</small>
|
||||
<a class="ms-2" data-bs-toggle="modal" data-bs-target="#createChecklistModal" href="">
|
||||
<small class="text-uppercase text-body-secondary">{% translate "Checklists" %}</small>
|
||||
<a class="link-secondary ms-2" data-bs-toggle="modal" data-bs-target="#createChecklistModal" href="">
|
||||
<i class="fas fa-plus"></i>
|
||||
<span class="visually-hidden">{% translate "Create" %}</span>
|
||||
</a>
|
||||
@@ -307,27 +321,32 @@
|
||||
</span>
|
||||
</p>
|
||||
<div class="btn-group btn-group-sm" role="group" aria-label="Checklist actions">
|
||||
<button class="btn btn-light"
|
||||
<button class="btn bg-body-tertiary border"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#checklist{{ checklist.id }}"
|
||||
onclick="$(this).children('i').toggleClass('fa-caret-down fa-caret-up')">
|
||||
<i class="fas fa-caret-down"></i>
|
||||
</button>
|
||||
<a class="btn btn-light" href="{% url 'helpdesk:edit_ticket_checklist' ticket.id checklist.id %}">
|
||||
<a class="btn bg-body-tertiary border"
|
||||
href="{% url 'helpdesk:edit_ticket_checklist' ticket.id checklist.id %}">
|
||||
<i class="fa-regular fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse" id="checklist{{ checklist.id }}">
|
||||
<ul class="list-unstyled">
|
||||
<div class="collapse mt-3" id="checklist{{ checklist.id }}">
|
||||
<ul class="list-unstyled pe-none">
|
||||
{% for task in checklist.tasks.all %}
|
||||
<li class="mb-1" {% if task.completion_date %} title="{% translate "Completed on" %} {{ task.completion_date }}" {% endif %}>
|
||||
<li class="mb-1"
|
||||
{% if task.completion_date %}
|
||||
title="{% translate "Completed on" %} {{ task.completion_date }}"
|
||||
{% endif %}>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="task-view-{{ task.id }}"
|
||||
disabled{% if task.completion_date %}
|
||||
checked{% endif %} />
|
||||
{% if task.completion_date %}
|
||||
checked{% endif %} />
|
||||
<label class="form-check-label" for="task-view-{{ task.id }}">{{ task }}</label>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
{% block helpdesk_head %}
|
||||
{# Timeline 3 CSS #}
|
||||
{% if helpdesk_settings.HELPDESK_USE_CDN %}
|
||||
<link title="timeline-styles" rel="stylesheet" href="https://cdn.knightlab.com/libs/timeline3/latest/css/timeline.css" />
|
||||
<link title="timeline-styles"
|
||||
rel="stylesheet"
|
||||
href="https://cdn.knightlab.com/libs/timeline3/latest/css/timeline.css" />
|
||||
{% else %}
|
||||
<link title="timeline-styles" rel="stylesheet" href="{% static 'helpdesk/vendor/timeline3/css/timeline.css' %}" />
|
||||
{% endif %}
|
||||
@@ -64,7 +66,10 @@
|
||||
</ul>
|
||||
{% endif %}
|
||||
<div class="tab-content" id="tableTabContent">
|
||||
<div class="tab-pane fade show active" id="datatabletabcontents" role="tabpanel" aria-labelledby="datatabletabcontents-tab">
|
||||
<div class="tab-pane fade show active"
|
||||
id="datatabletabcontents"
|
||||
role="tabpanel"
|
||||
aria-labelledby="datatabletabcontents-tab">
|
||||
<div class="card border-0">
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'helpdesk:mass_update' %}" id="ticket_mass_update">
|
||||
@@ -93,8 +98,8 @@
|
||||
</thead>
|
||||
</table>
|
||||
{# Actions dropdown #}
|
||||
<div class="dropdown dropend" id="actions-dropdown">
|
||||
<button class="btn btn-outline-secondary border-0 dropdown-toggle"
|
||||
<div class="dropdown" id="actions-dropdown">
|
||||
<button class="btn bg-body-tertiary border dropdown-toggle"
|
||||
type="button"
|
||||
data-bs-toggle="dropdown"
|
||||
data-bs-auto-close="outside"
|
||||
@@ -145,7 +150,7 @@
|
||||
</select>
|
||||
</li>
|
||||
<li class="d-grid p-3">
|
||||
<button type="submit" class="btn btn-outline-primary">
|
||||
<button type="submit" class="btn bg-body-tertiary border">
|
||||
{% translate "Go" %}
|
||||
<i class="fa-solid fa-arrow-right"></i>
|
||||
</button>
|
||||
@@ -161,7 +166,8 @@
|
||||
{% if saved_query.user == user %}
|
||||
<p>
|
||||
{% blocktranslate with saved_query.title as query_name %}You are currently viewing saved query <strong>"{{ query_name }}"</strong>.{% endblocktranslate %}
|
||||
<a href="{% url 'helpdesk:delete_query' saved_query.id %}" class="alert-link text-decoration-underline link-offset-2">{% translate "Delete Saved Query" %}</a>
|
||||
<a href="{% url 'helpdesk:delete_query' saved_query.id %}"
|
||||
class="alert-link text-decoration-underline link-offset-2">{% translate "Delete Saved Query" %}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<hr />
|
||||
@@ -182,7 +188,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{# Filters Offcanvas #}
|
||||
<a class="btn btn-outline-secondary border-0"
|
||||
<a class="btn bg-body-tertiary border"
|
||||
id="advanced-filters"
|
||||
data-bs-toggle="offcanvas"
|
||||
href="#offcanvasFilters"
|
||||
@@ -211,14 +217,16 @@
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
<div class="offcanvas-footer">
|
||||
<div class="d-grid m-3">
|
||||
<button class="btn btn-outline-primary" type="submit" form="filtersForm">{% translate "Apply Filters" %}</button>
|
||||
</div>
|
||||
<div class="offcanvas-footer p-3 d-flex justify-content-end">
|
||||
<button type="button"
|
||||
class="btn bg-body-tertiary border me-3"
|
||||
data-bs-dismiss="offcanvas"
|
||||
aria-label="Close">{% translate "Cancel" %}</button>
|
||||
<button class="btn btn-success" type="submit" form="filtersForm">{% translate "Apply Filters" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{# Queries Offcanvas #}
|
||||
<button class="btn btn-outline-secondary border-0"
|
||||
<button class="btn bg-body-tertiary border"
|
||||
id="queries"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
@@ -273,12 +281,15 @@
|
||||
</div>
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input" type="checkbox" name="shared" id="id_shared" />
|
||||
<label class="form-label mb-0" for="id_shared">{% translate "Share this query with other users." %}</label>
|
||||
<label class="form-label mb-0"
|
||||
for="id_shared">{% translate "Share this query with other users." %}</label>
|
||||
<div class="form-text">{% translate "If you share this query, it will be visible by <em>all</em> other logged-in users." %}</div>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-outline-primary">{% translate "Save Query" %}<i class="fa-solid fa-arrow-right ms-2"></i></button>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success me-2">{% translate "Save" %}</button>
|
||||
<button class="btn bg-body-tertiary border"
|
||||
type="button"
|
||||
data-bs-dismiss="offcanvas"
|
||||
aria-label="Close">{% translate "Cancel" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
{# Use Saved query pane #}
|
||||
@@ -302,9 +313,10 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button class="btn btn-outline-primary" type="submit">{% translate "Run Query" %}<i class="fa-solid fa-arrow-right ms-2"></i></button>
|
||||
</div>
|
||||
<button class="btn btn-success me-2" type="submit">{% translate "Run Query" %}</button>
|
||||
<button class="btn bg-body-tertiary border" type="button" data-bs-dismiss="offcanvas" aria-label="Close">
|
||||
{% translate "Cancel" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -339,7 +351,7 @@
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
const renderDateTime = (data, type, row, meta) => `<span class="small text-secondary">${data}</span>`
|
||||
const renderDateTime = (data, type, row, meta) => `<span class="small text-body-secondary">${data}</span>`
|
||||
|
||||
$(document).ready(function() {
|
||||
// Ticket DataTable Initialization
|
||||
@@ -372,7 +384,7 @@
|
||||
},
|
||||
'buttons': [{
|
||||
extend: "colvis",
|
||||
className: "btn btn-outline-secondary border-0",
|
||||
className: "btn bg-body-tertiary border",
|
||||
id: "column-visibility",
|
||||
text: "Columns"
|
||||
}],
|
||||
@@ -416,7 +428,7 @@
|
||||
}, {
|
||||
data: "queue",
|
||||
render: function(data, type, row, meta) {
|
||||
return `<span class="badge text-bg-light text-secondary">${data.title}</span>`
|
||||
return `<span class="badge bg-light-subtle text-light-emphasis border border-light-subtle">${data.title}</span>`
|
||||
},
|
||||
visible: false,
|
||||
}, {
|
||||
@@ -436,19 +448,22 @@
|
||||
data: "assigned_to",
|
||||
render: function(data, type, row, meta) {
|
||||
if (data !== "None") {
|
||||
return data;
|
||||
return `<span class="small text-body-secondary">${data}</span>`
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}, {
|
||||
data: "submitter"
|
||||
data: "submitter",
|
||||
render: function(data, type, row, meta) {
|
||||
return `<span class="small text-body-secondary">${data}</span>`
|
||||
}
|
||||
}, {
|
||||
data: "last_followup",
|
||||
render: function(data, type, row) {
|
||||
let locale = navigator.language || navigator.userLanguage || window.helpdesk_settings.LANGUAGE_CODE;
|
||||
|
||||
if (isNaN(Date.parse(data))) {
|
||||
return `<span class="small text-secondary">${window.helpdesk_settings.NO_FOLLOWUP_TEXT}</span>`
|
||||
return `<span class="small text-body-secondary">${window.helpdesk_settings.NO_FOLLOWUP_TEXT}</span>`
|
||||
}
|
||||
|
||||
let date = new Date(data);
|
||||
@@ -461,7 +476,7 @@
|
||||
minute: "2-digit",
|
||||
hour12: true
|
||||
});
|
||||
return `<span class="small text-secondary">${lastFollowupDate}</span>`
|
||||
return `<span class="small text-body-secondary">${lastFollowupDate}</span>`
|
||||
}
|
||||
},
|
||||
{% if helpdesk_settings.HELPDESK_ENABLE_TIME_SPENT_ON_TICKET %}
|
||||
@@ -478,7 +493,6 @@
|
||||
],
|
||||
order: []
|
||||
});
|
||||
|
||||
{# Shortcuts to select/unselect multiple tickets #}
|
||||
$("#select_all_btn").click(function() {
|
||||
$(".ticket_multi_select").prop('checked', true);
|
||||
@@ -494,7 +508,6 @@
|
||||
|
||||
$(".buttons-colvis").removeClass('dt-button')
|
||||
$("#dt-search-0").removeClass('form-control-sm')
|
||||
|
||||
{# Timeline initialization when tab is displayed #}
|
||||
// The TL.Timeline constructor takes at least two arguments:
|
||||
// the id of the Timeline container (no '#'), and
|
||||
|
||||
@@ -85,7 +85,6 @@ class FollowUpDirectionRenderingTests(TestCase):
|
||||
|
||||
r = self.client.get(self.url)
|
||||
|
||||
self.assertContains(r, "followup-item-internal")
|
||||
self.assertContains(r, "Private")
|
||||
|
||||
def test_outbound_followup_is_labeled_to_submitter(self):
|
||||
@@ -95,7 +94,6 @@ class FollowUpDirectionRenderingTests(TestCase):
|
||||
|
||||
r = self.client.get(self.url)
|
||||
|
||||
self.assertContains(r, "followup-item-outbound")
|
||||
self.assertContains(r, "To submitter")
|
||||
|
||||
def test_inbound_followup_is_labeled_from_submitter(self):
|
||||
@@ -108,5 +106,4 @@ class FollowUpDirectionRenderingTests(TestCase):
|
||||
|
||||
r = self.client.get(self.url)
|
||||
|
||||
self.assertContains(r, "followup-item-inbound")
|
||||
self.assertContains(r, "From submitter")
|
||||
|
||||
@@ -113,7 +113,7 @@ class StaffTicketListViewTests(TestCase):
|
||||
self.assertEqual(r.context["query_params"]["sorting"], "last_followup")
|
||||
self.assertContains(
|
||||
r,
|
||||
"<option value='last_followup' selected='selected'>",
|
||||
"<option value='last_followup' selected>",
|
||||
html=False,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user