Compare commits

...

2 Commits

Author SHA1 Message Date
ce56c3a774 Create: switch ticket status ajax handler 2023-08-01 20:13:04 +09:00
d2bc9aba7f Add: resolved switcher to template 2023-08-01 16:55:07 +09:00
7 changed files with 118 additions and 46 deletions

View File

@ -1,31 +0,0 @@
$(function () {
function deleteArchiveListElement(id) {
const archiveList = `#li-archive-${id}`
$(archiveList).remove()
}
$(".btn-archive-eraser").click(function (e) {
e.preventDefault();
const csrf = $("input[name=csrfmiddlewaretoken]").val()
console.log(csrf)
const archiveListElement = $(this).attr("data-jq-archive-target");
$.ajax({
type: "delete",
url: $(this).attr("href"),
headers: {
'X-CSRFToken':csrf,
'Content-Type':'application/json'
},
// beforeSend: function(xhr) {
// xhr.setRequestHeader("X-CSRFToken", csrf);
// },
success: function (response) {
console.log(response)
deleteArchiveListElement(archiveListElement);
},
error: function (response) {
console.log(response)
}
});
});
console.log("JQ is ready to work");
});

View File

@ -0,0 +1,61 @@
$(function () {
// CSRF token:
const csrf = $("input[name=csrfmiddlewaretoken]").val()
function deleteArchiveListElement(id) {
const archiveList = `#li-archive-${id}`
$(archiveList).hide(1500);
}
$(".btn-archive-eraser").click(function (e) {
e.preventDefault();
const archiveListElement = $(this).attr("data-jq-archive-target");
$.ajax({
type: "delete",
url: $(this).attr("href"),
headers: {
'X-CSRFToken':csrf,
'Content-Type':'application/json'
},
// beforeSend: function(xhr) {
// xhr.setRequestHeader("X-CSRFToken", csrf);
// },
success: function (response) {
console.log(response.status)
deleteArchiveListElement(archiveListElement);
},
error: function (response) {
console.log(response.status)
}
});
});
$("#ticket-state").click(function () {
console.log('Press');
let resolved = false;
if ($(this).attr("checked")) {
console.log('Find it!!!')
resolved = true;
} else {
resolved = false;
}
$.ajax({
type: "post",
url: $(this).attr("ticket-state-url"),
headers: {
'X-CSRFToken':csrf,
'Content-Type':'application/json'
},
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({
"resolved": resolved
}),
success: function (response) {
console.log(response.status)
},
error: function (response) {
console.log(response.status)
}
});
});
console.log("JQ is ready to work");
});

View File

@ -8,26 +8,32 @@
rel="stylesheet" rel="stylesheet"
href="{% static 'collector/css/bootstrap.min.css' %}" href="{% static 'collector/css/bootstrap.min.css' %}"
rel="stylesheet" rel="stylesheet"
/> >
<link <link
rel="apple-touch-icon" rel="apple-touch-icon"
sizes="180x180" sizes="180x180"
href="{% static 'collector/img/apple-touch-icon.png' %}" href="{% static 'collector/img/apple-touch-icon.png' %}"
/> >
<link <link
rel="icon" rel="icon"
type="image/png" type="image/png"
sizes="32x32" sizes="32x32"
href="{% static 'collector/img/favicon-32x32.png' %}" href="{% static 'collector/img/favicon-32x32.png' %}"
/> >
<link <link
rel="icon" rel="icon"
type="image/png" type="image/png"
sizes="16x16" sizes="16x16"
href="{% static 'collector/img/favicon-16x16.png' %}" href="{% static 'collector/img/favicon-16x16.png' %}"
/> >
<link rel="manifest" href="{% static 'collector/img/site.webmanifest' %}"> <link
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css"> rel="manifest"
href="{% static 'collector/img/site.webmanifest' %}"
>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css"
>
<title>Document</title> <title>Document</title>
</head> </head>
<body> <body>

View File

@ -81,9 +81,9 @@
<span class="visually-hidden">Toggle Dropdown</span> <span class="visually-hidden">Toggle Dropdown</span>
</button> </button>
<ul class="dropdown-menu dropdown-menu-end"> <ul class="dropdown-menu dropdown-menu-end">
<li><button class="dropdown-item" type="button">Settings</button></li> <li><button class="dropdown-item" type="button"><i class="bi bi-gear"></i> Settings</button></li>
<li><hr class="dropdown-divider" /></li> <li><hr class="dropdown-divider" /></li>
<li><button class="dropdown-item" type="button">Logout</button></li> <li><button class="dropdown-item" type="button"><i class="bi bi-door-closed"></i> Logout</button></li>
</ul> </ul>
</div> </div>
</li> </li>

View File

@ -11,12 +11,22 @@
<div class="card-body" aria-current="true"> <div class="card-body" aria-current="true">
<div class="d-flex w-100 justify-content-between mb-2"> <div class="d-flex w-100 justify-content-between mb-2">
<h4 class="card-title mb-1">Ticket: {{ ticket.number }}</h4> <h4 class="card-title mb-1">Ticket: {{ ticket.number }}</h4>
<small>{{ ticket.time_create }}</small> <small><i class="bi bi-clock-history"></i> {{ ticket.time_create }}</small>
</div>
<div class="form-check form-switch form-check-reverse d-flex w-100 justify-content-left">
<label class="form-check-label" for="ticket-state">Resolved:</label>
<input
class="form-check-input ms-2 mb-2"
type="checkbox"
role="switch"
id="ticket-state"
ticket-state-url="{% url 'ticket' ticket.platform ticket.number %}"
{% if ticket.resolved %} checked {% endif %}>
</div> </div>
<div class="col-xl-6 mb-2"> <div class="col-xl-6 mb-2">
<h6 class="card-title mb-1">Platform: {{ ticket.platform.pretty_name }}</h6> <h6 class="card-title mb-1">Platform: {{ ticket.platform.pretty_name }}</h6>
<h6 class="card-title mb-1">Owner: {{ ticket.user.username }}</h6> <h6 class="card-title mb-3">Owner: {{ ticket.user.username }}</h6>
</div> </div>
<div class="col-xl-6 mt-1 mb-2"> <div class="col-xl-6 mt-1 mb-2">
{% if ticket.note %} {% if ticket.note %}
<div class="card"> <div class="card">
@ -45,7 +55,12 @@
<b>SHA1:</b> <b>SHA1:</b>
<span style="word-wrap: break-word">{{ archive.sha1 }}</span> <span style="word-wrap: break-word">{{ archive.sha1 }}</span>
</small> </small>
<br> <small>
<br>
<b>Uploaded:</b>
<span style="word-wrap: break-word">{{ archive.time_update }}</span>
</small>
<br>
<small> <small>
<b>Size:</b> <b>Size:</b>
<span style="word-wrap: break-word">{{ archive.size }}</span> <span style="word-wrap: break-word">{{ archive.size }}</span>
@ -119,5 +134,5 @@
</main> </main>
{% endblock content %} {% endblock content %}
{% block jquery %} {% block jquery %}
<script src="{% static 'collector/js/jq.delete.archive.js' %}"></script> <script src="{% static 'collector/js/jq.ticket.detail.js' %}"></script>
{% endblock jquery %} {% endblock jquery %}

View File

@ -16,3 +16,8 @@ def get_file_size(file_path, unit='bytes'):
else: else:
size = file_size / 1024 ** exponents_map[unit] size = file_size / 1024 ** exponents_map[unit]
return round(size, 3) return round(size, 3)
def is_ajax(request):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
return True

View File

@ -1,4 +1,6 @@
import json
# from django.shortcuts import render # from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import FileResponse, JsonResponse, Http404 from django.http import FileResponse, JsonResponse, Http404
from django.views import generic from django.views import generic
@ -6,9 +8,10 @@ from rest_framework import status
# from rest_framework.response import Response # from rest_framework.response import Response
from .models import Archive, Ticket, Platform from .models import Archive, Ticket, Platform
from .utils import is_ajax
class ArchiveHandlerView(generic.View): class ArchiveHandlerView(LoginRequiredMixin, generic.View):
def get(self, request, path): def get(self, request, path):
try: try:
file = Archive.objects.get(file=path) file = Archive.objects.get(file=path)
@ -72,8 +75,21 @@ class DetailTicket(generic.DetailView):
template_name = 'collector/ticket.html' template_name = 'collector/ticket.html'
context_object_name = 'ticket' context_object_name = 'ticket'
def post(self, request, platform, ticket):
if is_ajax(request):
model = self.get_object()
if request.body:
data = json.loads(request.body)
if data.get('resolved') is True:
model.resolved = False
model.save()
if data.get('resolved') is False:
model.resolved = True
model.save()
return JsonResponse({'status': 201}, status=status.HTTP_201_CREATED)
def get_object(self, queryset=None): def get_object(self, queryset=None):
return Ticket.objects.get(number=self.kwargs.get('ticket')) return self.model.objects.get(number=self.kwargs.get('ticket'))
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)