Add: delete views and jq handler

This commit is contained in:
Stepan Zhukovsky 2023-08-03 11:57:02 +09:00
parent 52ad31c845
commit 89acf8e8bb
6 changed files with 164 additions and 39 deletions

View File

@ -1,11 +1,12 @@
$(function () { $(function () {
console.log("JQ is ready to work");
// CSRF token: // CSRF token:
const csrf = $("input[name=csrfmiddlewaretoken]").val() const CSRF = $("input[name=csrfmiddlewaretoken]").val()
// -- -- -- --
function deleteArchiveListElement(id) { function deleteArchiveListElement(id) {
const archiveList = `#li-archive-${id}` const archiveList = `#li-archive-${id}`
$(archiveList).hide(1500); $(archiveList).hide(1500);
} };
$(".btn-archive-eraser").click(function (e) { $(".btn-archive-eraser").click(function (e) {
e.preventDefault(); e.preventDefault();
const archiveListElement = $(this).attr("data-jq-archive-target"); const archiveListElement = $(this).attr("data-jq-archive-target");
@ -13,18 +14,18 @@ $(function () {
type: "delete", type: "delete",
url: $(this).attr("href"), url: $(this).attr("href"),
headers: { headers: {
'X-CSRFToken':csrf, "X-CSRFToken":CSRF,
'Content-Type':'application/json' "Content-Type":"application/json"
}, },
// beforeSend: function(xhr) { // beforeSend: function(xhr) {
// xhr.setRequestHeader("X-CSRFToken", csrf); // xhr.setRequestHeader("X-CSRFToken", csrf);
// }, // },
success: function (response) { success: function (response) {
console.log(response.status) console.log(response.status);
deleteArchiveListElement(archiveListElement); deleteArchiveListElement(archiveListElement);
}, },
error: function (response) { error: function (response) {
console.log(response.status) console.log(response.status);
} }
}); });
}); });
@ -41,21 +42,44 @@ $(function () {
type: "post", type: "post",
url: $(this).attr("ticket-state-url"), url: $(this).attr("ticket-state-url"),
headers: { headers: {
'X-CSRFToken':csrf, "X-CSRFToken":CSRF,
'Content-Type':'application/json' "Content-Type":"application/json"
}, },
contentType: 'application/json', contentType: "application/json; charset=utf-8",
dataType: 'json', dataType: "json",
data: JSON.stringify({ data: JSON.stringify({
"resolved": resolved resolved: resolved,
}), }),
success: function (response) { success: function (response) {
console.log(response.status) console.log(response.resolved)
}, },
error: function (response) { error: function (response) {
console.log(response.status) console.log(response.resolved)
}
});
});
$(".btn-ticket-del").click(function (e) {
e.preventDefault();
const del_url = $(this).attr("href")
const redirect_url = $(this).attr("data-jq-ticket-del-redirect")
$.ajax({
type: "DELETE",
url: del_url,
headers: {
'X-CSRFToken':CSRF,
'Content-Type':'application/json'
},
success: function (response) {
console.log(response.status);
if (redirect_url) {
window.location.href = redirect_url;
}else {
console.log("Need delete ticket card");
}
},
error: function (response) {
console.log(response.status);
} }
}); });
}); });
console.log("JQ is ready to work");
}); });

View File

@ -0,0 +1,22 @@
{% extends 'collector/base.html' %}
{% load static %}
{% block content %}
{% include 'collector/navigation.html' %}
<div class="container mt-5">
<div class="row">
<form method="post" action="{% url 'delete' ticket.number %}">
{% csrf_token %}
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>Cancel</button>
<button
type="button"
class="btn btn-danger btn-archive-eraser"
data-bs-dismiss="modal"
>Delete</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -58,7 +58,7 @@
</ul> </ul>
<!-- Search --> <!-- Search -->
<ul class="navbar-nav flex-row flex-wrap ms-md-auto"> <ul class="navbar-nav flex-row flex-wrap ms-md-auto">
<li class="nav-item py-2 py-lg-1 col-12 col-lg-auto"> <li class="nav-item py-2 col-12 col-lg-auto">
<form class="d-flex" role="search"> <form class="d-flex" role="search">
<input <input
class="form-control me-2" class="form-control me-2"

View File

@ -86,20 +86,28 @@
<!-- Card buttons --> <!-- Card buttons -->
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<a <a
href="{{ ticket.get_absolute_url }}" href="/"
class="btn btn-outline-warning mb-1 mt-1" class="btn btn-outline-warning mb-1 mt-1"
><i class="bi bi-pencil-square"></i> Edit</a> ><i class="bi bi-pencil-square"></i> Edit</a>
<a <button
href="{{ ticket.get_absolute_url }}"
class="btn btn-outline-danger mb-1 mt-1" class="btn btn-outline-danger mb-1 mt-1"
><i class="bi bi-trash"></i> Delete</a> data-bs-toggle="modal"
data-bs-target="#modal-ticket-del"
><i class="bi bi-trash"></i> Delete
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Modal --> <!-- Modal Archive -->
{% for archive in ticket.archive_set.all %} {% for archive in ticket.archive_set.all %}
<div class="modal fade" id="modal-archive-del-{{ archive.id }}" tabindex="-1" aria-labelledby="LabelArchive-{{ archive.id }}" aria-hidden="true"> <div
class="modal fade"
id="modal-archive-del-{{ archive.id }}"
tabindex="-1"
aria-labelledby="LabelArchive-{{ archive.id }}"
aria-hidden="true"
>
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -129,6 +137,34 @@
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
<!-- Modal Ticket -->
<div class="modal fade" id="modal-ticket-del" tabindex="-1" aria-labelledby="LabelTicket" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="LabelTicket">Delete ticket #{{ ticket.number }} ?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Deleting a ticket will also permanently delete all files associated with it.</p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>Cancel</button>
<a
type="button"
href="{% url 'delete' ticket.number %}"
class="btn btn-danger btn-ticket-del"
data-bs-dismiss="modal"
data-jq-ticket-del-redirect="{% url 'tickets' %}"
>Delete</a>
</div>
</div>
</div>
</div>
</div> </div>
</section> </section>
</main> </main>

View File

@ -12,7 +12,7 @@ urlpatterns = [
path( path(
'tickets/', 'tickets/',
views.ListAllTickets.as_view(), views.ListAllTickets.as_view(),
name='index' name='tickets'
), ),
path( path(
'tickets/show/<slug:platform>/', 'tickets/show/<slug:platform>/',
@ -24,6 +24,11 @@ urlpatterns = [
views.DetailTicket.as_view(), views.DetailTicket.as_view(),
name='ticket' name='ticket'
), ),
path(
'tickets/delete/<int:ticket>/',
views.AjaxDeleteTicketHandler.as_view(),
name='delete'
),
path( path(
'archives/<path:path>', 'archives/<path:path>',
views.ArchiveHandlerView.as_view(), views.ArchiveHandlerView.as_view(),

View File

@ -1,8 +1,10 @@
import json import json
# from django.shortcuts import render # from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import FileResponse, JsonResponse, Http404 from django.http import FileResponse, HttpResponseNotAllowed, JsonResponse
from django.views import generic from django.views import generic
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from rest_framework import status from rest_framework import status
# from rest_framework.response import Response # from rest_framework.response import Response
@ -13,10 +15,7 @@ from .utils import is_ajax
class ArchiveHandlerView(LoginRequiredMixin, generic.View): class ArchiveHandlerView(LoginRequiredMixin, generic.View):
def get(self, request, path): def get(self, request, path):
try: file = get_object_or_404(Archive, file=path)
file = Archive.objects.get(file=path)
except Archive.DoesNotExist:
return Http404
return FileResponse(file.file) return FileResponse(file.file)
def delete(self, request, path): def delete(self, request, path):
@ -74,24 +73,63 @@ class DetailTicket(generic.DetailView):
model = Ticket model = Ticket
template_name = 'collector/ticket.html' template_name = 'collector/ticket.html'
context_object_name = 'ticket' context_object_name = 'ticket'
slug_field = 'number'
slug_url_kwarg = 'ticket'
def post(self, request, platform, ticket): def post(self, request, **kwargs):
if is_ajax(request): if is_ajax(request):
model = self.get_object() model = self.get_object()
if request.body: if request.body:
data = json.loads(request.body) data = json.loads(request.body)
if data.get('resolved') is True: resolved_field = data.get('resolved')
model.resolved = False if isinstance(resolved_field, bool):
model.resolved = not resolved_field
model.save() model.save()
if data.get('resolved') is False: return JsonResponse(
model.resolved = True {'resolved': not resolved_field},
model.save() status=status.HTTP_201_CREATED
return JsonResponse({'status': 201}, status=status.HTTP_201_CREATED) )
return JsonResponse(
def get_object(self, queryset=None): {'resolved': 'must be a boolean'},
return self.model.objects.get(number=self.kwargs.get('ticket')) status=status.HTTP_400_BAD_REQUEST
)
return HttpResponseNotAllowed(permitted_methods=['GET'])
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['platforms'] = Platform.objects.all() context['platforms'] = Platform.objects.all()
return context return context
class DeleteTicket(generic.DeleteView):
model = Ticket
template_name = 'collector/delete_ticket.html'
context_object_name = 'ticket'
slug_field = 'number'
slug_url_kwarg = 'ticket'
success_url = reverse_lazy('tickets')
def delete(self, request, *args, **kwargs):
if is_ajax(request):
print("HELLO FROM AJAX")
self.object = self.get_object()
self.object.delete()
return JsonResponse(
{'status': status.HTTP_200_OK},
status=status.HTTP_200_OK
)
response = super().delete(self, request, *args, **kwargs)
return response
class AjaxDeleteTicketHandler(generic.View):
def delete(self, request, ticket):
if is_ajax(request):
print("HELLO FROM AJAX")
obj = Ticket.objects.get(number=ticket)
obj.delete()
return JsonResponse(
{'status': status.HTTP_200_OK},
status=status.HTTP_200_OK
)