diff --git a/apps/api/serializers.py b/apps/api/serializers.py index 782242d..52ec57d 100644 --- a/apps/api/serializers.py +++ b/apps/api/serializers.py @@ -152,5 +152,5 @@ class TicketSerializer(DynamicModelSerializer): fields = ( "uuid", "title", "description", "author", "create_timestamp", "edit_timestamp", "is_edited", "was_yesterday", "is_older_than_day", - "timestamp", "priority", "tags", "short_description" + "timestamp", "priority", "tags", "short_description", "string_datetime" ) diff --git a/apps/home/models.py b/apps/home/models.py index 5ab3b1c..6eea00a 100644 --- a/apps/home/models.py +++ b/apps/home/models.py @@ -1,5 +1,6 @@ # -*- encoding: utf-8 -*- +import logging import bleach from uuid import uuid4 from datetime import timedelta, datetime @@ -9,6 +10,8 @@ from django.conf import settings from django.utils import timezone from django.utils.translation import gettext_lazy as _ +log = logging.getLogger(__name__) + class TicketPriority(models.Model): uuid = models.UUIDField(primary_key=True, default=uuid4, editable=False) @@ -152,7 +155,7 @@ class Ticket(models.Model): @property def was_yesterday(self) -> bool: - """_summary_ + """Returns a boolean dependent on if `self.timestamp` is from before midnight yesterday. Returns ------- @@ -165,6 +168,45 @@ class Ticket(models.Model): return self.timestamp < midnight_today + @property + def string_datetime(self) -> str: + """Provides a human readable string representation of `self.timestamp` that should be displayed + to represent the ticket's age. + + Returns + ------- + str + The string representation of `self.timestamp`. + """ + + difference = timezone.now() - self.timestamp + + days = difference.days + hours = difference.total_seconds() // 3600 + minutes = difference.total_seconds() // 60 + seconds = difference.total_seconds() + + hours, minutes, seconds = map(int, (hours, minutes, seconds)) + + if seconds < 60: + value, unit = seconds, "second" + + elif minutes < 60: + value, unit = minutes, "minute" + + elif hours < 24: + value, unit = hours, "hour" + + elif days < 7: + value, unit = days, "day" + + else: + return self.timestamp.strftime("%Y-%m-%d") + + if value > 1: + unit += "s" + + return f"{value} {unit} ago" @property def timestamp(self) -> datetime: diff --git a/apps/static/css/index.css b/apps/static/css/index.css index 9e95908..d9abc4f 100644 --- a/apps/static/css/index.css +++ b/apps/static/css/index.css @@ -113,10 +113,21 @@ body { .ticket-item:hover { background-color: var(--bs-tertiary-bg); } - +/* .ticket-item .ticket-item-indicator { - width: 5px; - height: 100%; + writing-mode: vertical-rl; + text-orientation: upright; +} */ + +.ticket-item .ticket-item-complex { + transition: all 0.3s ease; + overflow: hidden; + width: 2rem; +} + +#ticketsContainer:not(.complex-items) .ticket-item .ticket-item-complex { + margin: 0 !important; + width: 0 !important; } .ticket-item .ticket-item-icon { diff --git a/apps/static/js/tickets.js b/apps/static/js/tickets.js index f0c18c9..575460e 100644 --- a/apps/static/js/tickets.js +++ b/apps/static/js/tickets.js @@ -1,7 +1,8 @@ -var filters = {"order": "-edit_timestamp"}; +var filters = {"ordering": "-edit_timestamp"}; global_loadingTickets = false; searchTimeout = null; pagination = {}; + complexItems = false; $(document).ready(function() { initSearchBar(); @@ -220,7 +221,7 @@ function loadTicketItems(page=1) { filters["page"] = page; var fetchFilters = { ...filters }; - fetchFilters["only_fields"] = "uuid,title,short_description,author,priority,tags,timestamp,was_yesterday,is_edited,author__forename,author__surname,author__department,author__icon"; + fetchFilters["only_fields"] = "uuid,title,short_description,author,priority,tags,timestamp,is_edited,author__forename,author__surname,author__department,author__icon,string_datetime"; fetchTicketsPromise(fetchFilters).then((response) => { // Update the counts to show how many tickets were found @@ -256,17 +257,10 @@ function loadTicketItems(page=1) { // Iterate over and handle each ticket response.results.forEach(function(ticket) { - // Create a formatted version of the ticket's timestamp - const timestamp = new Date(ticket.timestamp); - var formattedTime = timestampToHumanDate(timestamp, ticket.was_yesterday); - - // Mark the ticket if it is edited - if (ticket.is_edited) formattedTime += " • edited"; - // Create a copy of the template using the ticket data var template = $($("#ticketItemTemplate").html()); template.find(".ticket-item-author").text(`${ticket.author.forename} ${ticket.author.surname}`); - template.find(".ticket-item-datetime").text(formattedTime); + template.find(".ticket-item-datetime").text(ticket.string_datetime); template.find(".ticket-item-title").text(ticket.title); template.find(".ticket-item-desc").html(ticket.short_description); template.find(".ticket-item-icon").attr("src", ticket.author.icon); @@ -280,16 +274,20 @@ function loadTicketItems(page=1) { template.find(".ticket-item-tags").append(tagTemplate); }); - var priorityElem = template.find(".ticket-item-indicator"); + var priorityElem = template.find(".ticket-item-priority"); + // priorityElem.text(ticket.priority.title); + priorityElem.css("color", ticket.priority.colour); priorityElem.css("background-color", ticket.priority.backgroundcolour); - priorityElem.attr("data-title", ticket.priority.title + " Priority"); - // Add the priority using the badge template - var priorityTemplate = $($("#ticketContentBadgeTemplate").html()); - priorityTemplate.find(".ticket-content-badge-text").text(ticket.priority.title + " Priority"); - priorityTemplate.css({ "color": ticket.priority.colour, "background-color": ticket.priority.backgroundcolour }); - priorityTemplate.removeClass("rounded-pill").addClass("rounded-1"); - template.find(".ticket-item-priority").append(priorityTemplate); + var departmentElem = template.find(".ticket-item-department"); + departmentElem.addClass("bgc-orange-100 c-orange-700") + + // // Add the priority using the badge template + // var priorityTemplate = $($("#ticketContentBadgeTemplate").html()); + // priorityTemplate.find(".ticket-content-badge-text").text(ticket.priority.title + " Priority"); + // priorityTemplate.css({ "color": ticket.priority.colour, "background-color": ticket.priority.backgroundcolour }); + // priorityTemplate.removeClass("rounded-pill").addClass("rounded-1"); + // template.find(".ticket-item-priority").append(priorityTemplate); // Add the content to the interface $("#ticketsContainer .content").append(template); @@ -315,17 +313,10 @@ function loadTicketContent(uuid) { fetchTicketsPromise({uuid: uuid}).then((response) => { ticket = response.results[0]; - // Create a formatted version of the ticket's timestamp - const timestamp = new Date(ticket.timestamp); - var formattedTime = timestampToHumanDate(timestamp, ticket.was_yesterday); - - // Mark the ticket if it is edited - if (ticket.is_edited) formattedTime += " • edited"; - // Create a copy of the template using the ticket data var template = $($("#ticketContentTemplate").html()); template.find(".ticket-content-author").text(`${ticket.author.forename} ${ticket.author.surname}`); - template.find(".ticket-content-datetime").text(formattedTime); + template.find(".ticket-content-datetime").text(ticket.string_datetime); template.find(".ticket-content-title").text(ticket.title); template.find(".ticket-content-desc").html(ticket.description); template.find(".ticket-content-icon").attr("src", ticket.author.icon); @@ -377,4 +368,15 @@ function fetchTicketsPromise(queryFilters) { // Prevent certain dropdowns from closing when the user clicks. $(".dropdown-menu.prevent-click-close").on("click", function(e) { e.stopPropagation(); -}); \ No newline at end of file +}); + +function toggleComplexItems() { + complexItems = !complexItems; + + if (complexItems) { + $("#ticketsContainer").addClass("complex-items"); + } + else { + $("#ticketsContainer").removeClass("complex-items"); + } +} \ No newline at end of file diff --git a/apps/templates/home/tickets.html b/apps/templates/home/tickets.html index 14585b4..e00b8b9 100644 --- a/apps/templates/home/tickets.html +++ b/apps/templates/home/tickets.html @@ -77,25 +77,6 @@ - @@ -167,7 +148,7 @@