Browse Source

Minor fixies

- Improvements in layouts texts
- Removed defaults.py
- Removed unneeded module admindocs
- Synchronization with sharix-todo
TonyKurts 1 year ago
parent
commit
5b40d1c1f9

+ 4 - 0
.gitattributes

@@ -0,0 +1,4 @@
+* text=auto
+
+*.txt text
+*.md text

+ 1 - 0
.gitignore

@@ -19,3 +19,4 @@ media/
 *.sqlite3
 *.*~
 *.*.swp
+.DS_Store

+ 2 - 2
admin.py

@@ -1,13 +1,13 @@
 from django.contrib import admin
 
-from tickets.models import *
+from tickets.models import Attachment, Comment, TicketList, Ticket
 
 
 class TicketAdmin(admin.ModelAdmin):
     list_display = ("title", "ticket_list", "ticket_type",  "status", "priority", "created_at", "due_date")
     list_filter = ("ticket_list", "ticket_type",)
     ordering = ("priority",)
-    search_fields = ("title",)
+    search_fields = ("title", "note")
 
 
 class CommentAdmin(admin.ModelAdmin):

+ 0 - 18
defaults.py

@@ -1,18 +0,0 @@
-from django.conf import settings
-
-
-hash = {
-    "TICKETS_LIMIT_FILE_ATTACHMENTS": [".jpg", ".gif", ".png", ".csv", ".pdf", ".zip", ".txt"],
-    "TICKETS_MAXIMUM_ATTACHMENT_SIZE": 5000000,
-    "TICKETS_PUBLIC_SUBMIT_REDIRECT": "/",
-}
-
-def defaults(key: str):
-    """Try to get a setting from project settings.
-    If empty or doesn't exist, fall back to a value from defaults hash."""
-
-    if hasattr(settings, key):
-        val = getattr(settings, key)
-    else:
-        val = hash.get(key)
-    return val

+ 9 - 12
forms/ticket.py

@@ -8,21 +8,14 @@ from tickets.models import Ticket, TicketList
 
 
 class TicketForm(forms.ModelForm):
-    ticket_type = forms.ChoiceField(
-        choices=Ticket.TICKET_TYPES_CHOICES,
-        widget=forms.Select(attrs={
-                'class': 'form-control'
-        }),
-    )
-
     def __init__(self, user, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
         group_ids = Group.objects.values_list("pk", flat=True)
         if not user.is_superuser:
-            group_ids = group_ids.filter(user=user) 
-        ticket_lists = TicketList.objects.select_related("group")
-        ticket_lists = ticket_lists.filter(group__in=group_ids)
+            group_ids = group_ids.filter(user=user)
+            
+        ticket_lists = TicketList.objects.select_related("group").filter(group__in=group_ids)
 
         self.fields["ticket_list"].empty_label = None
         self.fields["ticket_list"].queryset = ticket_lists
@@ -30,6 +23,10 @@ class TicketForm(forms.ModelForm):
         self.fields["assigned_to"].empty_label = "Select a user"
         self.initial["due_date"] = (timezone.now() + timedelta(days=7)).date().strftime('%Y-%m-%d')
 
+        if self.instance.pk:
+            self.initial["ticket_type"] = self.instance.ticket_type
+            self.fields["ticket_type"].disabled = True
+
     class Meta:
         model = Ticket
         exclude = ["status"]
@@ -43,7 +40,7 @@ class TicketForm(forms.ModelForm):
                 'class': 'form-control'
             }),
             'ticket_type': forms.Select(attrs={
-                'class': 'form-control',
+                'class': 'form-control'
             }),
             'due_date': forms.DateInput(attrs={
                 'class': 'form-control',
@@ -59,4 +56,4 @@ class TicketForm(forms.ModelForm):
             'priority': forms.NumberInput(attrs={
                 'class': 'form-control',
             }),
-        }
+        }

+ 2 - 8
models/attachment.py

@@ -7,16 +7,10 @@ from tickets.models.ticket import Ticket
 
 
 def get_attachment_upload_dir(instance, filename):
-    """Determine upload dir for ticket attachment files."""
-
-    return "/".join(["attachments", str(instance.ticket.id), filename])
+    return "/".join(["attachments", str(instance.ticket.pk), filename])
 
 
 class Attachment(models.Model):
-    """
-    Defines a generic file attachment for use in M2M relation with ticket.
-    """
-
     ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
     added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
     timestamp = models.DateTimeField(auto_now_add=True)
@@ -30,4 +24,4 @@ class Attachment(models.Model):
         return extension
 
     def __str__(self):
-        return f"{self.ticket.id} - {self.file.name}"
+        return f"{self.ticket.pk} - {self.file.name}"

+ 4 - 4
models/ticket.py

@@ -1,6 +1,6 @@
 from django.db import models
-from django.contrib.auth import get_user_model
 from django.urls import reverse
+from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 
 from tickets.models.ticket_list import TicketList
@@ -8,7 +8,7 @@ from tickets.models.ticket_list import TicketList
 
 class Ticket(models.Model):
     TICKET_TYPES = (
-        (1,"ST_REQUEST", [
+        (1, "ST_REQUEST", [
             [111, 121, 149, 159],
             [110, 121, 149, 159],
             [121, 131, 149, 159],
@@ -81,7 +81,7 @@ class Ticket(models.Model):
 
     title = models.CharField(max_length=128)
     ticket_list = models.ForeignKey(TicketList, on_delete=models.CASCADE)
-    ticket_type = models.PositiveSmallIntegerField(choices=TICKET_TYPES_CHOICES)
+    ticket_type = models.PositiveSmallIntegerField(choices=TICKET_TYPES_CHOICES, default=1)
     status = models.PositiveSmallIntegerField(null=True)
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True)
@@ -115,7 +115,7 @@ class Ticket(models.Model):
         super(Ticket, self).save(*args, **kwargs)
 
     def get_absolute_url(self):
-        return reverse("tickets:ticket_detail", kwargs={"ticket_id": self.id})
+        return reverse("tickets:ticket_detail", kwargs={"ticket_id": self.pk})
 
     class Meta:
         ordering = ["-priority", "created_at"]

+ 3 - 3
templates/tickets/ticket_detail.html

@@ -80,14 +80,14 @@
         <div class="d-flex justify-content-between">
           <button type="button" data-bs-toggle="modal" data-bs-target="#ticket-edit-modal" class="btn btn-primary">
             <i class="fa-solid fa-pen-to-square pe-1"></i>
-            Edit ticket
+            Edit Ticket
           </button>
           <button type="button" class="btn btn-outline-danger" data-bs-toggle="modal" data-bs-target="#ticket-delete-modal">
             <i class="fa-solid fa-trash-can"></i>
           </button>  
         </div>
 
-        <!--ticket edit modal-->
+        <!--Ticket edit modal-->
         <div class="modal fade" id="ticket-edit-modal" tabindex="-1">
           <div class="modal-dialog modal-dialog-centered">
             <div class="modal-content">
@@ -237,4 +237,4 @@
       $(this).next('.custom-file-label').html(fileName);
     })
   </script>
-{% endblock extra_js %}
+{% endblock extra_js %}

+ 4 - 5
templates/tickets/ticket_list_detail.html

@@ -3,11 +3,11 @@
 
 {% block content %}
   {% if my_tickets %}
-    <h1>My Tickets (in all groups)</h1>
+    <h1 class="fw-bold">My Tickets (in all groups)</h1>
   {% elif assignments %}
-    <h1>Assignments (in all groups)</h1>
+    <h1 class="fw-bold">Assignments (in all groups)</h1>
   {% else %}
-    <h1 class="mb-4">{{ ticket_list.group }} > <b>{{ ticket_list.name }}</b></h1>
+    <h1>{{ ticket_list.group }} > <b>{{ ticket_list.name }}</b></h1>
     
     <div class="d-flex justify-content-between">
       <button type="button" data-bs-toggle="modal" data-bs-target="#ticket-create-modal" class="btn btn-primary">
@@ -150,7 +150,6 @@
 {% block extra_js %}
   {% if tickets %}
     <script>
-      // State filters
       let tickets = $(".ticket");
       let filters = $(".ticket_type-filter");
       
@@ -182,4 +181,4 @@
       document.addEventListener("DOMContentLoaded", apply_filters);
     </script>
   {% endif %}
-{% endblock extra_js %}
+{% endblock extra_js %}

+ 3 - 3
templates/tickets/ticket_list_list.html

@@ -1,7 +1,7 @@
 {% extends "tickets/base.html" %}
 
 {% block content %}
-  <h1 class="fw-bold mb-4">Lists</h1>
+  <h1 class="fw-bold">Lists</h1>
 
   {% if user.is_staff or user.is_superuser %}
     <button type="button" data-bs-toggle="modal" data-bs-target="#ticket_list-create-modal" class="btn btn-primary">
@@ -52,6 +52,6 @@
       </ul>
     {% endfor %}
   {% else %}
-    <h4>There are no lists!</h4>
+    <h4>There are no Lists!</h4>
   {% endif %}
-{% endblock %}
+{% endblock %}

+ 7 - 7
urls.py

@@ -1,4 +1,4 @@
-from django.urls import path, include
+from django.urls import path
 
 from tickets.views import *
 from tickets.api import views as apiviews
@@ -23,10 +23,10 @@ urlpatterns = [
     path("attachment/remove/<int:attachment_id>/", remove_attachment, name="remove_attachment"),
 
     # API
-    path("api/v1/ticket_list/", apiviews.TicketListListAPIView.as_view()),
-    path("api/v1/ticket_list/my/", apiviews.TicketListDetailAPIView.as_view(), {"my": True}),
-    path("api/v1/ticket_list/<int:pk>", apiviews.TicketListDetailAPIView.as_view()),
-    path("api/v1/ticket/", apiviews.TicketCreateAPIView.as_view()),
-    path("api/v1/ticket/<int:pk>", apiviews.TicketDetailAPIView.as_view()),
-    path("api/v1/ticket/<int:pk>/status", apiviews.TicketStatusAPIView.as_view()),
+    path("api/ticket_list/", apiviews.TicketListListAPIView.as_view()),
+    path("api/ticket_list/my/", apiviews.TicketListDetailAPIView.as_view(), {"my": True}),
+    path("api/ticket_list/<int:pk>", apiviews.TicketListDetailAPIView.as_view()),
+    path("api/ticket/", apiviews.TicketCreateAPIView.as_view()),
+    path("api/ticket/<int:pk>", apiviews.TicketDetailAPIView.as_view()),
+    path("api/ticket/<int:pk>/status", apiviews.TicketStatusAPIView.as_view()),
 ]

+ 0 - 2
views/delete.py

@@ -1,9 +1,7 @@
 from django.views import View
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib import messages
-from django.urls import reverse_lazy
 from django.shortcuts import get_object_or_404, redirect
-from django.views import View
 
 from tickets.models import TicketList, Ticket
 from tickets.utils import SuperuserStaffRequiredMixin, UserCanReadTicketListMixin, UserCanReadTicketMixin, UserCanWriteTicketMixin

+ 1 - 0
views/search.py

@@ -5,6 +5,7 @@ from django.db.models.functions import Concat
 
 from tickets.models import Ticket
 
+
 @login_required
 def search(request):
     found_tickets = None

+ 4 - 5
views/ticket_detail.py

@@ -7,7 +7,6 @@ from django.shortcuts import redirect
 from django.db.models import F
 from django.views.generic import DetailView
 
-from tickets.defaults import defaults
 from tickets.forms import TicketForm
 from tickets.models import Attachment, Comment, Ticket
 from tickets.utils import UserCanReadTicketMixin
@@ -60,18 +59,18 @@ class TicketDetailView(LoginRequiredMixin, UserCanReadTicketMixin, DetailView):
                 ticket=ticket,
                 body=bleach.clean(request.POST.get("comment-body"), strip=True)
             )
-            messages.success(request, "Comment posted")
+            messages.success(request, "Comment posted. Notification email sent to thread participants.")
 
         if request.FILES.get("attachment_file_input"):
             uploaded_file = request.FILES.get("attachment_file_input")
             name, extension = os.path.splitext(uploaded_file.name)
 
-            if uploaded_file.size > defaults("TICKETS_MAXIMUM_ATTACHMENT_SIZE"):
+            if uploaded_file.size > 5000000:
                 messages.error(request, f"File exceeds maximum attachment size.")
-            elif extension not in defaults("TICKETS_LIMIT_FILE_ATTACHMENTS"):
+            elif extension not in [".jpg", ".gif", ".png", ".csv", ".pdf", ".zip", ".txt"]:
                 messages.error(request, f"This site does not allow upload of {extension} files.")
             else:
                 Attachment.objects.create(ticket=ticket, added_by=request.user, file=uploaded_file)
                 messages.success(request, f"File attached successfully.")
 
-        return redirect("tickets:ticket_detail", pk=ticket.pk)
+        return redirect("tickets:ticket_detail", pk=ticket.pk)

+ 2 - 2
views/ticket_list_list.py

@@ -22,11 +22,11 @@ class TicketListView(LoginRequiredMixin, ListView):
                 ticket_lists = ticket_lists.filter(group__id__in=user_groups_ids)
             else:
                 messages.warning(self.request, "You do not yet belong to any groups. Ask your administrator to add you to one.")
-                return TicketList.objects.none()
+                ticket_lists = TicketList.objects.none()
 
         return ticket_lists
     
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context["form"] = TicketListForm(self.request.user)
-        return context
+        return context