1
0
Эх сурвалжийг харах

Minor fixies

- Improvements in layouts texts
- Removed defaults.py
- Removed unneeded module admindocs
- Synchronization with sharix-todo
TonyKurts 1 жил өмнө
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
 *.sqlite3
 *.*~
 *.*~
 *.*.swp
 *.*.swp
+.DS_Store

+ 2 - 2
admin.py

@@ -1,13 +1,13 @@
 from django.contrib import admin
 from django.contrib import admin
 
 
-from tickets.models import *
+from tickets.models import Attachment, Comment, TicketList, Ticket
 
 
 
 
 class TicketAdmin(admin.ModelAdmin):
 class TicketAdmin(admin.ModelAdmin):
     list_display = ("title", "ticket_list", "ticket_type",  "status", "priority", "created_at", "due_date")
     list_display = ("title", "ticket_list", "ticket_type",  "status", "priority", "created_at", "due_date")
     list_filter = ("ticket_list", "ticket_type",)
     list_filter = ("ticket_list", "ticket_type",)
     ordering = ("priority",)
     ordering = ("priority",)
-    search_fields = ("title",)
+    search_fields = ("title", "note")
 
 
 
 
 class CommentAdmin(admin.ModelAdmin):
 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):
 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):
     def __init__(self, user, *args, **kwargs):
         super().__init__(*args, **kwargs)
         super().__init__(*args, **kwargs)
 
 
         group_ids = Group.objects.values_list("pk", flat=True)
         group_ids = Group.objects.values_list("pk", flat=True)
         if not user.is_superuser:
         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"].empty_label = None
         self.fields["ticket_list"].queryset = ticket_lists
         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.fields["assigned_to"].empty_label = "Select a user"
         self.initial["due_date"] = (timezone.now() + timedelta(days=7)).date().strftime('%Y-%m-%d')
         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:
     class Meta:
         model = Ticket
         model = Ticket
         exclude = ["status"]
         exclude = ["status"]
@@ -43,7 +40,7 @@ class TicketForm(forms.ModelForm):
                 'class': 'form-control'
                 'class': 'form-control'
             }),
             }),
             'ticket_type': forms.Select(attrs={
             'ticket_type': forms.Select(attrs={
-                'class': 'form-control',
+                'class': 'form-control'
             }),
             }),
             'due_date': forms.DateInput(attrs={
             'due_date': forms.DateInput(attrs={
                 'class': 'form-control',
                 'class': 'form-control',
@@ -59,4 +56,4 @@ class TicketForm(forms.ModelForm):
             'priority': forms.NumberInput(attrs={
             'priority': forms.NumberInput(attrs={
                 'class': 'form-control',
                 '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):
 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):
 class Attachment(models.Model):
-    """
-    Defines a generic file attachment for use in M2M relation with ticket.
-    """
-
     ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
     ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
     added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
     added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
     timestamp = models.DateTimeField(auto_now_add=True)
     timestamp = models.DateTimeField(auto_now_add=True)
@@ -30,4 +24,4 @@ class Attachment(models.Model):
         return extension
         return extension
 
 
     def __str__(self):
     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.db import models
-from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
+from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 
 
 from tickets.models.ticket_list import TicketList
 from tickets.models.ticket_list import TicketList
@@ -8,7 +8,7 @@ from tickets.models.ticket_list import TicketList
 
 
 class Ticket(models.Model):
 class Ticket(models.Model):
     TICKET_TYPES = (
     TICKET_TYPES = (
-        (1,"ST_REQUEST", [
+        (1, "ST_REQUEST", [
             [111, 121, 149, 159],
             [111, 121, 149, 159],
             [110, 121, 149, 159],
             [110, 121, 149, 159],
             [121, 131, 149, 159],
             [121, 131, 149, 159],
@@ -81,7 +81,7 @@ class Ticket(models.Model):
 
 
     title = models.CharField(max_length=128)
     title = models.CharField(max_length=128)
     ticket_list = models.ForeignKey(TicketList, on_delete=models.CASCADE)
     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)
     status = models.PositiveSmallIntegerField(null=True)
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True)
     updated_at = models.DateTimeField(auto_now=True)
@@ -115,7 +115,7 @@ class Ticket(models.Model):
         super(Ticket, self).save(*args, **kwargs)
         super(Ticket, self).save(*args, **kwargs)
 
 
     def get_absolute_url(self):
     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:
     class Meta:
         ordering = ["-priority", "created_at"]
         ordering = ["-priority", "created_at"]

+ 3 - 3
templates/tickets/ticket_detail.html

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

+ 4 - 5
templates/tickets/ticket_list_detail.html

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

+ 3 - 3
templates/tickets/ticket_list_list.html

@@ -1,7 +1,7 @@
 {% extends "tickets/base.html" %}
 {% extends "tickets/base.html" %}
 
 
 {% block content %}
 {% block content %}
-  <h1 class="fw-bold mb-4">Lists</h1>
+  <h1 class="fw-bold">Lists</h1>
 
 
   {% if user.is_staff or user.is_superuser %}
   {% 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">
     <button type="button" data-bs-toggle="modal" data-bs-target="#ticket_list-create-modal" class="btn btn-primary">
@@ -52,6 +52,6 @@
       </ul>
       </ul>
     {% endfor %}
     {% endfor %}
   {% else %}
   {% else %}
-    <h4>There are no lists!</h4>
+    <h4>There are no Lists!</h4>
   {% endif %}
   {% 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.views import *
 from tickets.api import views as apiviews
 from tickets.api import views as apiviews
@@ -23,10 +23,10 @@ urlpatterns = [
     path("attachment/remove/<int:attachment_id>/", remove_attachment, name="remove_attachment"),
     path("attachment/remove/<int:attachment_id>/", remove_attachment, name="remove_attachment"),
 
 
     # API
     # 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.views import View
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib import messages
 from django.contrib import messages
-from django.urls import reverse_lazy
 from django.shortcuts import get_object_or_404, redirect
 from django.shortcuts import get_object_or_404, redirect
-from django.views import View
 
 
 from tickets.models import TicketList, Ticket
 from tickets.models import TicketList, Ticket
 from tickets.utils import SuperuserStaffRequiredMixin, UserCanReadTicketListMixin, UserCanReadTicketMixin, UserCanWriteTicketMixin
 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
 from tickets.models import Ticket
 
 
+
 @login_required
 @login_required
 def search(request):
 def search(request):
     found_tickets = None
     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.db.models import F
 from django.views.generic import DetailView
 from django.views.generic import DetailView
 
 
-from tickets.defaults import defaults
 from tickets.forms import TicketForm
 from tickets.forms import TicketForm
 from tickets.models import Attachment, Comment, Ticket
 from tickets.models import Attachment, Comment, Ticket
 from tickets.utils import UserCanReadTicketMixin
 from tickets.utils import UserCanReadTicketMixin
@@ -60,18 +59,18 @@ class TicketDetailView(LoginRequiredMixin, UserCanReadTicketMixin, DetailView):
                 ticket=ticket,
                 ticket=ticket,
                 body=bleach.clean(request.POST.get("comment-body"), strip=True)
                 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"):
         if request.FILES.get("attachment_file_input"):
             uploaded_file = request.FILES.get("attachment_file_input")
             uploaded_file = request.FILES.get("attachment_file_input")
             name, extension = os.path.splitext(uploaded_file.name)
             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.")
                 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.")
                 messages.error(request, f"This site does not allow upload of {extension} files.")
             else:
             else:
                 Attachment.objects.create(ticket=ticket, added_by=request.user, file=uploaded_file)
                 Attachment.objects.create(ticket=ticket, added_by=request.user, file=uploaded_file)
                 messages.success(request, f"File attached successfully.")
                 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)
                 ticket_lists = ticket_lists.filter(group__id__in=user_groups_ids)
             else:
             else:
                 messages.warning(self.request, "You do not yet belong to any groups. Ask your administrator to add you to one.")
                 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
         return ticket_lists
     
     
     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["form"] = TicketListForm(self.request.user)
         context["form"] = TicketListForm(self.request.user)
-        return context
+        return context