Added buttons to move to the next or prev ticket from the current selected ticket. Also segmented JS into functions.
368 lines
11 KiB
JavaScript
368 lines
11 KiB
JavaScript
var displayedTicketID = -1;
|
|
filters = {};
|
|
editor = null;
|
|
searchTimeout = null;
|
|
loadingTickets = false;
|
|
|
|
const formControls = [
|
|
{
|
|
id: "newTitle",
|
|
validation: function(element) {
|
|
const value = element.val();
|
|
return (!element.attr("required") || value.trim() !== "")
|
|
},
|
|
errorMessage: function(element) {
|
|
return "This field is required."
|
|
}
|
|
}
|
|
];
|
|
|
|
$(document).ready(function() {
|
|
ClassicEditor
|
|
.create( document.getElementById("newDesc"), {})
|
|
.then( newEditor => {
|
|
editor = newEditor;
|
|
})
|
|
.catch( error => {
|
|
console.error(error)
|
|
});
|
|
|
|
$("#searchTickets").keyup(() => {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(() => {
|
|
console.debug("searching");
|
|
value = $("#searchTickets").val();
|
|
if (value === "") {
|
|
console.debug("deleted search filters");
|
|
delete filters["search"];
|
|
}
|
|
else {
|
|
console.debug("updated search filters");
|
|
filters["search"] = value;
|
|
}
|
|
|
|
loadAllTickets();
|
|
}, 500);
|
|
})
|
|
|
|
setupFilter("#filterSidebar .filter-department", "author__department__in");
|
|
setupFilter("#filterSidebar .filter-tag", "tags__in")
|
|
setupFilter("#filterSidebar .filter-priority", "priority__in")
|
|
|
|
loadFilterCounts();
|
|
loadAllTickets();
|
|
});
|
|
|
|
function setupFilter(selector, key) {
|
|
$(selector).each(function () {
|
|
var input = $(this).find("input[type=checkbox], input[type=radio]");
|
|
var uuid = input.val();
|
|
|
|
input.on("change", function () {
|
|
|
|
if (input.is(":checkbox")) {
|
|
|
|
if ($(this).is(":checked")) {
|
|
filters[key] = filters[key] || [];
|
|
filters[key].push(uuid);
|
|
}
|
|
else {
|
|
filters[key] = filters[key].filter(id => id !== uuid);
|
|
if (filters[key].length === 0) {
|
|
delete filters[key];
|
|
}
|
|
}
|
|
}
|
|
else if (input.is(":radio") && input.is(":checked")) {
|
|
filters[key] = [uuid];
|
|
}
|
|
|
|
console.debug(`Filter applied '${key}' as '${uuid}'`)
|
|
loadAllTickets();
|
|
});
|
|
});
|
|
}
|
|
|
|
function validateForm() {
|
|
|
|
$("#ticketModal form").find(".form-control,.form-select").removeClass("is-valid is-invalid");
|
|
$("#ticketModal form .invalid-feedback").text("");
|
|
|
|
var valid = true;
|
|
|
|
formControls.forEach(function(control) {
|
|
var element = $("#" + control.id);
|
|
if (!control.validation(element)) {
|
|
element.addClass("is-invalid");
|
|
element.siblings(".invalid-feedback").text(control.errorMessage(element));
|
|
valid = false;
|
|
}
|
|
else {
|
|
element.addClass("is-valid");
|
|
}
|
|
});
|
|
|
|
return valid;
|
|
}
|
|
|
|
$("#ticketModal form").on("submit", function(event) {
|
|
event.preventDefault();
|
|
|
|
if (!validateForm()) {
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: URL_NewTicket,
|
|
type: "POST",
|
|
dataType: "json",
|
|
data: {
|
|
csrfmiddlewaretoken: CSRFMiddlewareToken,
|
|
title: $("#newTitle").val(),
|
|
description: editor.getData(),
|
|
author_id: CurrentUserID,
|
|
priority_id: $("#newPriority").val(),
|
|
tag_ids: $("#newTags").val()
|
|
},
|
|
success: function(data) {
|
|
loadAllTickets();
|
|
loadFilterCounts();
|
|
},
|
|
error: function(data) {
|
|
alert(JSON.stringify(data, null, 4))
|
|
}
|
|
});
|
|
});
|
|
|
|
function getOrdinalSuffix(day) {
|
|
if (day >= 11 && day <= 13) {
|
|
return day + 'th';
|
|
} else {
|
|
switch (day % 10) {
|
|
case 1: return day + 'st';
|
|
case 2: return day + 'nd';
|
|
case 3: return day + 'rd';
|
|
default: return day + 'th';
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateFilterCounts(filterType, data) {
|
|
$("#filterSidebar .filter-" + filterType).each(function() {
|
|
var uuid = $(this).find("input[type=checkbox],input[type=radio]").val();
|
|
var count = data[filterType + '_counts'][uuid];
|
|
$(this).find(".badge").text(count);
|
|
});
|
|
}
|
|
|
|
function loadFilterCounts() {
|
|
$.ajax({
|
|
url: URL_FilterCounts,
|
|
type: "GET",
|
|
success: function(data) {
|
|
updateFilterCounts('priority', data);
|
|
updateFilterCounts('tag', data);
|
|
updateFilterCounts('department', data);
|
|
$("#filterPriorityAll .badge").text(data.ticket_count);
|
|
$("#ticketCounts .total").text(data.ticket_count)
|
|
},
|
|
error: function(data) {
|
|
console.error(JSON.stringify(data, null, 4))
|
|
}
|
|
});
|
|
}
|
|
|
|
function timestampToHumanDate(timestamp, wasYesterday) {
|
|
if (wasYesterday) {
|
|
var day = getOrdinalSuffix(timestamp.getDate());
|
|
var month = timestamp.toLocaleString('en-GB', { month: 'short' });
|
|
var year = timestamp.toLocaleString('en-GB', { year: 'numeric' });
|
|
var time = timestamp.toLocaleString('en-GB', { hour: 'numeric', minute: 'numeric' });
|
|
return time + ', ' + day + ' ' + month + ' ' + year;
|
|
}
|
|
|
|
var hours = timestamp.getUTCHours();
|
|
var minutes = timestamp.getUTCMinutes();
|
|
return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0');
|
|
}
|
|
|
|
function loadAllTickets() {
|
|
if (loadingTickets === true) {
|
|
return;
|
|
}
|
|
|
|
$("#ticketsContainer .content").empty();
|
|
$("#ticketsContainer .none-found").hide();
|
|
$("#ticketsContainer .loading").show();
|
|
|
|
loadingTickets = true;
|
|
// alert(JSON.stringify(filters, null, 4));
|
|
|
|
$.ajax({
|
|
url: URL_Tickets,
|
|
type: "GET",
|
|
dataType: "json",
|
|
data: filters,
|
|
success: function(data) {
|
|
loadingTickets = false;
|
|
console.log(JSON.stringify(data, null, 4))
|
|
|
|
$("#ticketCounts .current").text(data.length);
|
|
$("#ticketsContainer .loading").hide();
|
|
|
|
if (data.length === 0) $("#ticketsContainer .none-found").show();
|
|
else $("#ticketsContainer .none-found").hide();
|
|
|
|
data.forEach(function(ticket) {
|
|
var timestamp = new Date(ticket.timestamp);
|
|
var formattedTime = timestampToHumanDate(timestamp, ticket.was_yesterday);
|
|
|
|
if (ticket.is_edited) {
|
|
formattedTime += " • edited";
|
|
}
|
|
|
|
var item = $(`
|
|
<div class="email-list-item peers fxw-nw p-20 bdB bgcH-grey-100 cur-p" data-ticket-id="${ticket.uuid}" data-author-icon="${ticket.author.icon}">
|
|
<div class="peer mR-10">
|
|
<img src="${ticket.author.icon}" alt="" class="w-2r h-2r bdrs-50p me-2" style="object-fit: cover;">
|
|
</div>
|
|
<div class="peer peer-greed ov-h">
|
|
<div class="peers ai-c">
|
|
<div class="peer peer-greed">
|
|
<h6 class="ticket-author">${ticket.author.forename} ${ticket.author.surname}</h6>
|
|
</div>
|
|
<div class="peer">
|
|
<small class="ticket-timestamp">${formattedTime}</small>
|
|
</div>
|
|
</div>
|
|
<h5 class="fsz-def tt-c c-grey-900 ticket-title">${ticket.title}</h5>
|
|
<span class="whs-nw w-100 ov-h tov-e d-b ticket-desc">${ticket.description}</span>
|
|
</div>
|
|
</div>
|
|
`);
|
|
|
|
|
|
$("#ticketsContainer .content").append(item);
|
|
});
|
|
|
|
applyTicketClickFunction();
|
|
},
|
|
error: function(data) {
|
|
loadingTickets = false;
|
|
alert(JSON.stringify(data, null, 4));
|
|
console.error(`${data.responseJSON.error}\n${data.responseJSON.detail}`);
|
|
}
|
|
});
|
|
}
|
|
|
|
function applyTicketClickFunction() {
|
|
$(".email-list-item").on("click", function(e) {
|
|
e.preventDefault();
|
|
displayTicket(this);
|
|
$('.email-content').toggleClass('open');
|
|
});
|
|
}
|
|
|
|
function reloadCurrentTicket() {
|
|
displayTicket($(".email-list-item.bgc-grey-100"));
|
|
}
|
|
|
|
function changeTicket(next=true) {
|
|
var selectedTicket = $(".email-list-item.bgc-grey-100");
|
|
|
|
if (!selectedTicket.length) {
|
|
displayTicket($(".email-list-item").first());
|
|
return;
|
|
}
|
|
|
|
if (next) {
|
|
displayTicket(selectedTicket.next());
|
|
}
|
|
else {
|
|
displayTicket(selectedTicket.prev());
|
|
}
|
|
|
|
if (!$('.email-content').hasClass('open')) {
|
|
$('.email-content').addClass('open');
|
|
}
|
|
}
|
|
|
|
function displayTicket(ticketElement) {
|
|
ticket = $(ticketElement);
|
|
ticketID = ticket.data("ticket-id");
|
|
|
|
// $(".back-to-mailbox").off("click").on("click", function(event) {
|
|
// event.preventDefault();
|
|
// $('.email-content').toggleClass('open');
|
|
// displayTicket(ticketElement);
|
|
// });
|
|
|
|
|
|
if (displayedTicketID === ticketID) {
|
|
// displayedTicketID = -1;
|
|
return;
|
|
}
|
|
|
|
ticket.siblings().removeClass("bgc-grey-100");
|
|
ticket.addClass("bgc-grey-100");
|
|
|
|
$("#ticketTitle").text("")
|
|
$("#ticketDesc").empty();
|
|
$("#ticketAuthor").text("");
|
|
$("#ticketAuthorImg").hide();
|
|
$("#ticketAuthorImg").prop("src", "");
|
|
$("#ticketTimestamp").text("");
|
|
$("#btnGroupDrop2").hide();
|
|
$("#ticketBadges").empty().hide();
|
|
|
|
|
|
displayedTicketID = ticketID;
|
|
|
|
$.ajax({
|
|
url: URL_Tickets,
|
|
type: 'get',
|
|
dataType: 'json',
|
|
data: {
|
|
uuid__in: [ticketID]
|
|
},
|
|
success: function (data) {
|
|
console.log(JSON.stringify(data, null, 4));
|
|
|
|
var ticket = data[0];
|
|
var author = ticket.author;
|
|
var department = author.department;
|
|
var priority = ticket.priority;
|
|
|
|
$("#ticketTitle").text(ticket.title);
|
|
$("#ticketDesc").append($(`<div class="w-100">${ticket.description}</div>`));
|
|
$("#ticketAuthor").text(`${author.forename} ${author.surname}`);
|
|
$("#ticketAuthorImg").show();
|
|
$("#ticketAuthorImg").prop("src", author.icon);
|
|
$("#btnGroupDrop2").show();
|
|
$("#ticketBadges").show();
|
|
|
|
$("#ticketBadges").append($(`<div class="badge me-1" style="color: ${priority.colour}; background-color: ${priority.backgroundcolour};">${priority.title} Priority <i class="ti-control-record "></i></div>`));
|
|
|
|
if (department != null) {
|
|
$("#ticketBadges").append($(`<div class="badge bgc-deep-purple-500 me-1">${department.title}</div>`));
|
|
}
|
|
|
|
ticket.tags.forEach(function(tag) {
|
|
$("#ticketBadges").append($(`<div class="badge me-1" style="color: ${tag.colour}; background-color: ${tag.backgroundcolour};">${tag.title} <i class="ti-tag"></i></div>`));
|
|
});
|
|
|
|
// timestamp
|
|
var timestamp = new Date(ticket.timestamp);
|
|
var formattedTime = timestampToHumanDate(timestamp, ticket.was_yesterday);
|
|
|
|
if (ticket.is_edited) {
|
|
formattedTime += " • edited";
|
|
}
|
|
|
|
$("#ticketTimestamp").text(formattedTime);
|
|
},
|
|
error: function(message) {
|
|
alert(JSON.stringify(message, null, 4));
|
|
}
|
|
});
|
|
} |