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):
|
def clean_description(self):
|
||||||
cleaned_description = bleach.clean(
|
cleaned_description = bleach.clean(
|
||||||
self.description,
|
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']}
|
attributes={'a': ['href', 'title']}
|
||||||
)
|
)
|
||||||
return cleaned_description
|
return cleaned_description
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.description = self.clean_description()
|
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)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -10,6 +10,7 @@ from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
|||||||
from django.template import loader
|
from django.template import loader
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from ..authentication.models import Department
|
from ..authentication.models import Department
|
||||||
from .models import Ticket, TicketPriority, TicketTag
|
from .models import Ticket, TicketPriority, TicketTag
|
||||||
@ -57,6 +58,7 @@ def get_tickets(request):
|
|||||||
print(key, values)
|
print(key, values)
|
||||||
|
|
||||||
for value in values:
|
for value in values:
|
||||||
|
if value == "all": continue # don't apply a filter if we want all
|
||||||
queryset = queryset.filter(**{key: [value]})
|
queryset = queryset.filter(**{key: [value]})
|
||||||
|
|
||||||
tickets = queryset.order_by("-create_timestamp")
|
tickets = queryset.order_by("-create_timestamp")
|
||||||
@ -65,6 +67,7 @@ def get_tickets(request):
|
|||||||
|
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@require_POST
|
@require_POST
|
||||||
def get_filter_counts(request):
|
def get_filter_counts(request):
|
||||||
@ -96,7 +99,34 @@ def get_filter_counts(request):
|
|||||||
@login_required()
|
@login_required()
|
||||||
@require_POST
|
@require_POST
|
||||||
def new_ticket(request):
|
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()
|
@login_required()
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
<label for="filterTag-{{ tag.id }}" class="nav-link c-grey-800 cH-blue-500 actived">
|
<label for="filterTag-{{ tag.id }}" class="nav-link c-grey-800 cH-blue-500 actived">
|
||||||
<div class="peers ai-c jc-sb">
|
<div class="peers ai-c jc-sb">
|
||||||
<div class="peer peer-greed">
|
<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>
|
<span>{{ tag.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="peer">
|
<div class="peer">
|
||||||
@ -350,6 +350,20 @@
|
|||||||
<script>
|
<script>
|
||||||
var displayedTicketID = -1;
|
var displayedTicketID = -1;
|
||||||
filters = {};
|
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() {
|
$(document).ready(function() {
|
||||||
// $(".email-list-item").on("click", function() {
|
// $(".email-list-item").on("click", function() {
|
||||||
@ -358,6 +372,9 @@
|
|||||||
|
|
||||||
ClassicEditor
|
ClassicEditor
|
||||||
.create( document.getElementById("newDesc"), {})
|
.create( document.getElementById("newDesc"), {})
|
||||||
|
.then( newEditor => {
|
||||||
|
editor = newEditor;
|
||||||
|
})
|
||||||
.catch( error => {
|
.catch( error => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
});
|
});
|
||||||
@ -377,8 +394,8 @@
|
|||||||
|
|
||||||
function setupFilter(selector, key) {
|
function setupFilter(selector, key) {
|
||||||
$(selector).each(function () {
|
$(selector).each(function () {
|
||||||
var uuid = $(this).val();
|
|
||||||
var input = $(this).find("input[type=checkbox], input[type=radio]");
|
var input = $(this).find("input[type=checkbox], input[type=radio]");
|
||||||
|
var uuid = input.val();
|
||||||
|
|
||||||
input.on("change", function () {
|
input.on("change", function () {
|
||||||
if (input.is(":checkbox")) {
|
if (input.is(":checkbox")) {
|
||||||
@ -392,26 +409,64 @@
|
|||||||
delete filters[key];
|
delete filters[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (input.is(":radio") && input.is(":checked")) {
|
}
|
||||||
|
else if (input.is(":radio") && input.is(":checked")) {
|
||||||
filters[key] = [uuid];
|
filters[key] = [uuid];
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAllTickets();
|
|
||||||
console.log(JSON.stringify(filters, null, 4));
|
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) {
|
$("#ticketModal form").on("submit", function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!validateForm()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "{% url 'ticket-new' %}",
|
url: "{% url 'ticket-new' %}",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: {
|
data: {
|
||||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
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) {
|
function updateFilterCounts(filterType, data) {
|
||||||
$("#filterSidebar .filter-" + filterType).each(function() {
|
$("#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];
|
var count = data[filterType + '_counts'][uuid];
|
||||||
$(this).find(".badge").text(count);
|
$(this).find(".badge").text(count);
|
||||||
});
|
});
|
||||||
@ -443,7 +498,7 @@
|
|||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: {
|
data: {
|
||||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
csrfmiddlewaretoken: "{{ csrf_token }}"
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
console.log(JSON.stringify(data, null, 4));
|
console.log(JSON.stringify(data, null, 4));
|
||||||
@ -544,6 +599,15 @@
|
|||||||
// displayTicket(ticketElement);
|
// displayTicket(ticketElement);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
if (displayedTicketID === ticketID) {
|
||||||
|
// displayedTicketID = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ticket.siblings().removeClass("bgc-grey-100");
|
||||||
|
ticket.addClass("bgc-grey-100");
|
||||||
|
|
||||||
$("#ticketTitle").text("")
|
$("#ticketTitle").text("")
|
||||||
$("#ticketDesc").empty();
|
$("#ticketDesc").empty();
|
||||||
$("#ticketAuthor").text("");
|
$("#ticketAuthor").text("");
|
||||||
@ -553,10 +617,6 @@
|
|||||||
$("#btnGroupDrop2").hide();
|
$("#btnGroupDrop2").hide();
|
||||||
$("#ticketBadges").empty().hide();
|
$("#ticketBadges").empty().hide();
|
||||||
|
|
||||||
if (displayedTicketID === ticketID) {
|
|
||||||
displayedTicketID = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayedTicketID = ticketID;
|
displayedTicketID = ticketID;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user