functional filter + add modal
This commit is contained in:
parent
4c7a81e076
commit
690bec9b24
@ -101,14 +101,23 @@ class Ticket(models.Model):
|
||||
def clean_description(self):
|
||||
cleaned_description = bleach.clean(
|
||||
self.description,
|
||||
tags=['b', 'i', 'u', 'p', 'br', 'a', 'h3', 'h4', 'h5', 'h6'],
|
||||
tags=[
|
||||
'b', 'i', 'u', 'p', 'br', 'a', 'h3', 'h4', 'h5', 'h6', 'strong',
|
||||
'figure', 'table', 'tbody', 'tr', 'td'
|
||||
],
|
||||
attributes={'a': ['href', 'title']}
|
||||
)
|
||||
return cleaned_description
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.description = self.clean_description()
|
||||
# self.edit_timestamp = timezone.now() ## TEMP COMMENT, UNCOMMENT LATER !!
|
||||
|
||||
# we must use the same datetime object, otherwise they wont match
|
||||
now = timezone.now()
|
||||
|
||||
if self._state.adding: self.create_timestamp = now
|
||||
self.edit_timestamp = now
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
|
@ -10,6 +10,7 @@ from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.template import loader
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from ..authentication.models import Department
|
||||
from .models import Ticket, TicketPriority, TicketTag
|
||||
@ -57,6 +58,7 @@ def get_tickets(request):
|
||||
print(key, values)
|
||||
|
||||
for value in values:
|
||||
if value == "all": continue # don't apply a filter if we want all
|
||||
queryset = queryset.filter(**{key: [value]})
|
||||
|
||||
tickets = queryset.order_by("-create_timestamp")
|
||||
@ -65,6 +67,7 @@ def get_tickets(request):
|
||||
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def get_filter_counts(request):
|
||||
@ -96,7 +99,34 @@ def get_filter_counts(request):
|
||||
@login_required()
|
||||
@require_POST
|
||||
def new_ticket(request):
|
||||
return JsonResponse({"placeholder": "nothing here yet"})
|
||||
print(request.POST)
|
||||
|
||||
get = lambda key: request.POST.get(key)
|
||||
getlist = lambda key: request.POST.getlist(key)
|
||||
|
||||
title = get("title")
|
||||
description = get("description")
|
||||
author_id = get("author_id")
|
||||
priority_id = get("priority_id")
|
||||
tag_ids = getlist("tag_ids[]")
|
||||
|
||||
User = get_user_model()
|
||||
author = User.objects.get(id=author_id)
|
||||
|
||||
priority = TicketPriority.objects.get(id=priority_id)
|
||||
tags = [
|
||||
tag for tag in TicketTag.objects.filter(id__in=tag_ids)
|
||||
]
|
||||
|
||||
ticket = Ticket.objects.create(
|
||||
title=title,
|
||||
description=description,
|
||||
author=author,
|
||||
priority=priority,
|
||||
)
|
||||
ticket.tags.set(tags)
|
||||
|
||||
return JsonResponse({"success": "ticket created successfully"})
|
||||
|
||||
|
||||
@login_required()
|
||||
|
@ -75,7 +75,7 @@
|
||||
<label for="filterTag-{{ tag.id }}" class="nav-link c-grey-800 cH-blue-500 actived">
|
||||
<div class="peers ai-c jc-sb">
|
||||
<div class="peer peer-greed">
|
||||
<input type="checkbox" id="filterTag-{{ tag.id }}" class="form-check-input me-2" value="{{ priority.id }}">
|
||||
<input type="checkbox" id="filterTag-{{ tag.id }}" class="form-check-input me-2" value="{{ tag.id }}">
|
||||
<span>{{ tag.title }}</span>
|
||||
</div>
|
||||
<div class="peer">
|
||||
@ -350,6 +350,20 @@
|
||||
<script>
|
||||
var displayedTicketID = -1;
|
||||
filters = {};
|
||||
editor = null;
|
||||
|
||||
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() {
|
||||
// $(".email-list-item").on("click", function() {
|
||||
@ -358,6 +372,9 @@
|
||||
|
||||
ClassicEditor
|
||||
.create( document.getElementById("newDesc"), {})
|
||||
.then( newEditor => {
|
||||
editor = newEditor;
|
||||
})
|
||||
.catch( error => {
|
||||
console.error(error)
|
||||
});
|
||||
@ -377,8 +394,8 @@
|
||||
|
||||
function setupFilter(selector, key) {
|
||||
$(selector).each(function () {
|
||||
var uuid = $(this).val();
|
||||
var input = $(this).find("input[type=checkbox], input[type=radio]");
|
||||
var uuid = input.val();
|
||||
|
||||
input.on("change", function () {
|
||||
if (input.is(":checkbox")) {
|
||||
@ -392,26 +409,64 @@
|
||||
delete filters[key];
|
||||
}
|
||||
}
|
||||
} else if (input.is(":radio") && input.is(":checked")) {
|
||||
}
|
||||
else if (input.is(":radio") && input.is(":checked")) {
|
||||
filters[key] = [uuid];
|
||||
}
|
||||
|
||||
loadAllTickets();
|
||||
console.log(JSON.stringify(filters, null, 4));
|
||||
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 'ticket-new' %}",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
|
||||
title: $("#newTitle").val(),
|
||||
description: editor.getData(),
|
||||
author_id: "{{ request.user.id }}",
|
||||
priority_id: $("#newPriority").val(),
|
||||
tag_ids: $("#newTags").val()
|
||||
},
|
||||
success: function(data) {
|
||||
loadAllTickets();
|
||||
loadFilterCounts();
|
||||
},
|
||||
error: function(data) {
|
||||
alert(JSON.stringify(data, null, 4))
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -431,7 +486,7 @@
|
||||
|
||||
function updateFilterCounts(filterType, data) {
|
||||
$("#filterSidebar .filter-" + filterType).each(function() {
|
||||
var uuid = $(this).data("uuid");
|
||||
var uuid = $(this).find("input[type=checkbox],input[type=radio]").val();
|
||||
var count = data[filterType + '_counts'][uuid];
|
||||
$(this).find(".badge").text(count);
|
||||
});
|
||||
@ -443,7 +498,7 @@
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}"
|
||||
},
|
||||
success: function(data) {
|
||||
console.log(JSON.stringify(data, null, 4));
|
||||
@ -544,6 +599,15 @@
|
||||
// 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("");
|
||||
@ -553,10 +617,6 @@
|
||||
$("#btnGroupDrop2").hide();
|
||||
$("#ticketBadges").empty().hide();
|
||||
|
||||
if (displayedTicketID === ticketID) {
|
||||
displayedTicketID = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
displayedTicketID = ticketID;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user