Compare commits
	
		
			4 Commits
		
	
	
		
			06648a237a
			...
			138b8f26ad
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 138b8f26ad | |||
| eb80d72153 | |||
| f8218bdfd6 | |||
| 38f1cb14ae | 
| @ -0,0 +1,27 @@ | |||||||
|  | from django import forms | ||||||
|  | from crispy_forms.helper import FormHelper | ||||||
|  | from crispy_forms.layout import Layout, Submit, Div | ||||||
|  | from crispy_bootstrap5.bootstrap5 import FloatingField | ||||||
|  | 
 | ||||||
|  | from .models import Ticket | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class CreateTicketForm(forms.ModelForm): | ||||||
|  | 
 | ||||||
|  |     class Meta: | ||||||
|  |         model = Ticket | ||||||
|  |         fields = ['number', 'platform', 'note'] | ||||||
|  |         widgets = { | ||||||
|  |             'platform': forms.RadioSelect() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         super(CreateTicketForm, self).__init__(*args, **kwargs) | ||||||
|  |         self.helper = FormHelper(self) | ||||||
|  |         # self.helper.attrs = {"novalidate": ''} | ||||||
|  | 
 | ||||||
|  |         self.helper.layout = Layout( | ||||||
|  |             Div(FloatingField('number'), 'platform', css_class='col-md-2'), | ||||||
|  |             Div('note', css_class='col-md-6'), | ||||||
|  |             Submit('submit', 'Create', css_class='btn btn-success'), | ||||||
|  |         ) | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | # Generated by Django 4.2 on 2023-08-05 11:14 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('collector', '0001_initial'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterModelOptions( | ||||||
|  |             name='ticket', | ||||||
|  |             options={'ordering': ['-time_create']}, | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='archive', | ||||||
|  |             name='size', | ||||||
|  |             field=models.CharField(blank=True, editable=False, max_length=50), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='ticket', | ||||||
|  |             name='number', | ||||||
|  |             field=models.IntegerField(db_index=True, unique=True), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
| @ -60,11 +60,11 @@ class Platform(models.Model): | |||||||
|         return reverse('collector:platform', kwargs={'platform': self.name}) |         return reverse('collector:platform', kwargs={'platform': self.name}) | ||||||
| 
 | 
 | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return self.name |         return self.pretty_name | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Ticket(models.Model): | class Ticket(models.Model): | ||||||
|     number = models.IntegerField() |     number = models.IntegerField(unique=True, db_index=True) | ||||||
|     resolved = models.BooleanField(default=False) |     resolved = models.BooleanField(default=False) | ||||||
|     note = models.TextField(blank=True) |     note = models.TextField(blank=True) | ||||||
|     time_create = models.DateTimeField(auto_now_add=True) |     time_create = models.DateTimeField(auto_now_add=True) | ||||||
|  | |||||||
| @ -52,10 +52,18 @@ | |||||||
|             </li> |             </li> | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|             <li><hr class="dropdown-divider" /></li> |             <li><hr class="dropdown-divider" /></li> | ||||||
|             <li><a class="dropdown-item" href="{% url 'collector:tickets' %}"><i class="bi bi-funnel"></i> Reset filter</a></li> |             <li> | ||||||
|  |               <a class="dropdown-item" href="{% url 'collector:tickets' %}"> | ||||||
|  |                 <i class="bi bi-funnel"></i> Reset filter | ||||||
|  |               </a> | ||||||
|  |             </li> | ||||||
|           </ul> |           </ul> | ||||||
|         </li> |         </li> | ||||||
|         <li class="nav-item"><a class="nav-link" aria-current="page" href="#"><i class="bi bi-pencil-square"></i> New</a></li> |         <li class="nav-item"> | ||||||
|  |           <a class="nav-link" aria-current="page" href="{% url 'collector:create' %}"> | ||||||
|  |             <i class="bi bi-pencil-square"></i> New | ||||||
|  |           </a> | ||||||
|  |         </li> | ||||||
|       </ul> |       </ul> | ||||||
|       <!-- Search --> |       <!-- Search --> | ||||||
|       <ul class="navbar-nav flex-row flex-wrap me-md-auto"> |       <ul class="navbar-nav flex-row flex-wrap me-md-auto"> | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
|     type="checkbox" |     type="checkbox" | ||||||
|     role="switch" |     role="switch" | ||||||
|     name="ticket-state" |     name="ticket-state" | ||||||
|     ticket-state-url="{% url 'collector:ajax_update_state_ticket' ticket.platform ticket.number %}" |     ticket-state-url="{% url 'collector:ajax_update_state_ticket' ticket.platform.name ticket.number %}" | ||||||
|     {% if ticket.resolved %} ticket-state-switch="1" {% endif %} |     {% if ticket.resolved %} ticket-state-switch="1" {% endif %} | ||||||
|     {% if ticket.resolved %} checked {% endif %}> |     {% if ticket.resolved %} checked {% endif %}> | ||||||
| </div> | </div> | ||||||
|  | |||||||
| @ -0,0 +1,16 @@ | |||||||
|  | {% extends 'collector/base.html' %} | ||||||
|  | {% load static %} | ||||||
|  | {% load crispy_forms_tags %} | ||||||
|  | {% block title %}<title>Collector - create</title>{% endblock title %} | ||||||
|  | {% block main %} | ||||||
|  | <div class="container mt-3"> | ||||||
|  |     <div class="card"> | ||||||
|  |       <div class="card-header"> | ||||||
|  |         <h4>New ticket:</h4> | ||||||
|  |       </div> | ||||||
|  |       <div class="card-body"> | ||||||
|  |         {% crispy form %} | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | {% endblock main %} | ||||||
| @ -4,7 +4,7 @@ | |||||||
| {% include 'collector/includes/navbar.html' %} | {% include 'collector/includes/navbar.html' %} | ||||||
| <div class="container mt-5"> | <div class="container mt-5"> | ||||||
|   <div class="row"> |   <div class="row"> | ||||||
|     <form method="post" action="{% url 'delete' ticket.number %}"> |     <form method="post" action="{% url 'collector:delete' ticket.number %}"> | ||||||
|       {% csrf_token %} |       {% csrf_token %} | ||||||
|       <button |       <button | ||||||
|         type="button" |         type="button" | ||||||
| @ -12,7 +12,7 @@ | |||||||
|         data-bs-dismiss="modal" |         data-bs-dismiss="modal" | ||||||
|       >Cancel</button> |       >Cancel</button> | ||||||
|       <button |       <button | ||||||
|         type="button" |         type="submit" | ||||||
|         class="btn btn-danger btn-archive-eraser" |         class="btn btn-danger btn-archive-eraser" | ||||||
|         data-bs-dismiss="modal" |         data-bs-dismiss="modal" | ||||||
|       >Delete</button> |       >Delete</button> | ||||||
| @ -9,6 +9,13 @@ urlpatterns = [ | |||||||
|     # ▀▄▀▄▀ ██▄ █▄█ |     # ▀▄▀▄▀ ██▄ █▄█ | ||||||
|     # -- -- -- -- -- |     # -- -- -- -- -- | ||||||
| 
 | 
 | ||||||
|  |     # CREATE: | ||||||
|  |     path( | ||||||
|  |         'tickets/create/', | ||||||
|  |         views.CreateTicket.as_view(), | ||||||
|  |         name='create' | ||||||
|  |     ), | ||||||
|  | 
 | ||||||
|     # READ: |     # READ: | ||||||
|     path( |     path( | ||||||
|         '', |         '', | ||||||
|  | |||||||
| @ -8,7 +8,8 @@ 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 | ||||||
| 
 | 
 | ||||||
| from .models import Archive, Ticket, Platform | from .models import Archive, Ticket | ||||||
|  | from .forms import CreateTicketForm | ||||||
| from .utils import is_ajax | from .utils import is_ajax | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -28,17 +29,22 @@ class ArchiveHandlerView(LoginRequiredMixin, SingleObjectMixin, generic.View): | |||||||
|             return JsonResponse({'file': path}, status=status.HTTP_200_OK) |             return JsonResponse({'file': path}, status=status.HTTP_200_OK) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class CreateTicket(LoginRequiredMixin, generic.CreateView): | ||||||
|  |     model = Ticket | ||||||
|  |     form_class = CreateTicketForm | ||||||
|  |     template_name = 'collector/ticket_create.html' | ||||||
|  | 
 | ||||||
|  |     def form_valid(self, form): | ||||||
|  |         form.instance.user = self.request.user | ||||||
|  |         return super().form_valid(form) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class ListAllTickets(generic.ListView): | class ListAllTickets(generic.ListView): | ||||||
|     model = Ticket |     model = Ticket | ||||||
|     template_name = 'collector/tickets.html' |     template_name = 'collector/tickets.html' | ||||||
|     context_object_name = 'tickets' |     context_object_name = 'tickets' | ||||||
|     paginate_by = 5 |     paginate_by = 5 | ||||||
| 
 | 
 | ||||||
|     # def get_context_data(self, **kwargs): |  | ||||||
|     #     context = super().get_context_data(**kwargs) |  | ||||||
|     #     context['platforms'] = Platform.objects.all() |  | ||||||
|     #     return context |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class ListPlatformTickets(generic.ListView): | class ListPlatformTickets(generic.ListView): | ||||||
|     model = Ticket |     model = Ticket | ||||||
| @ -52,11 +58,6 @@ class ListPlatformTickets(generic.ListView): | |||||||
|             platform__name=self.kwargs.get('platform') |             platform__name=self.kwargs.get('platform') | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|     def get_context_data(self, **kwargs): |  | ||||||
|         context = super().get_context_data(**kwargs) |  | ||||||
|         context['platforms'] = Platform.objects.all() |  | ||||||
|         return context |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class DetailTicket(generic.DetailView): | class DetailTicket(generic.DetailView): | ||||||
|     model = Ticket |     model = Ticket | ||||||
| @ -65,15 +66,10 @@ class DetailTicket(generic.DetailView): | |||||||
|     slug_field = 'number' |     slug_field = 'number' | ||||||
|     slug_url_kwarg = 'ticket' |     slug_url_kwarg = 'ticket' | ||||||
| 
 | 
 | ||||||
|     def get_context_data(self, **kwargs): |  | ||||||
|         context = super().get_context_data(**kwargs) |  | ||||||
|         context['platforms'] = Platform.objects.all() |  | ||||||
|         return context |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class DeleteTicket(generic.DeleteView): | class DeleteTicket(generic.DeleteView): | ||||||
|     model = Ticket |     model = Ticket | ||||||
|     template_name = 'collector/delete_ticket.html' |     template_name = 'collector/ticket_delete.html' | ||||||
|     context_object_name = 'ticket' |     context_object_name = 'ticket' | ||||||
|     slug_field = 'number' |     slug_field = 'number' | ||||||
|     slug_url_kwarg = 'ticket' |     slug_url_kwarg = 'ticket' | ||||||
|  | |||||||
| @ -35,6 +35,8 @@ INSTALLED_APPS = [ | |||||||
|     'django.contrib.staticfiles', |     'django.contrib.staticfiles', | ||||||
|     'collector.apps.CollectorConfig',  # main app |     'collector.apps.CollectorConfig',  # main app | ||||||
|     'rest_framework', |     'rest_framework', | ||||||
|  |     "crispy_forms", | ||||||
|  |     "crispy_bootstrap5", | ||||||
|     'django_cleanup.apps.CleanupConfig',  # required bottom |     'django_cleanup.apps.CleanupConfig',  # required bottom | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| @ -126,3 +128,10 @@ MEDIA_URL = 'media/' | |||||||
| 
 | 
 | ||||||
| MEDIA_ROOT_FOR_SENSITIVE_FILES = BASE_DIR / 'archives' | MEDIA_ROOT_FOR_SENSITIVE_FILES = BASE_DIR / 'archives' | ||||||
| MEDIA_URL_FOR_SENSITIVE_FILES = '/archives/' | MEDIA_URL_FOR_SENSITIVE_FILES = '/archives/' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # django-crispy-forms and crispy-bootstrap5 | ||||||
|  | # https://django-crispy-forms.readthedocs.io/en/latest/ | ||||||
|  | CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" | ||||||
|  | 
 | ||||||
|  | CRISPY_TEMPLATE_PACK = "bootstrap5" | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										34
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							| @ -17,6 +17,24 @@ typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} | |||||||
| [package.extras] | [package.extras] | ||||||
| tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] | tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "crispy-bootstrap5" | ||||||
|  | version = "0.7" | ||||||
|  | description = "Bootstrap5 template pack for django-crispy-forms" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.7" | ||||||
|  | files = [ | ||||||
|  |     {file = "crispy-bootstrap5-0.7.tar.gz", hash = "sha256:0745a67199619149b7feca87dab7a45664876ed50fb582b38fd2aeb3f8a8d869"}, | ||||||
|  |     {file = "crispy_bootstrap5-0.7-py3-none-any.whl", hash = "sha256:f3ff1ef5cb379fe80b1b02e245008f276444098a4bdb8d855bed84c623798a85"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [package.dependencies] | ||||||
|  | django = ">=3.2" | ||||||
|  | django-crispy-forms = ">=1.13.0" | ||||||
|  | 
 | ||||||
|  | [package.extras] | ||||||
|  | test = ["pytest", "pytest-django"] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "django" | name = "django" | ||||||
| version = "4.2" | version = "4.2" | ||||||
| @ -48,6 +66,20 @@ files = [ | |||||||
|     {file = "django_cleanup-8.0.0-py2.py3-none-any.whl", hash = "sha256:8cd8872d67fe1501b19a843d006cdb5673cfbb74ac3d6d8f2c60e8e7723a7f5b"}, |     {file = "django_cleanup-8.0.0-py2.py3-none-any.whl", hash = "sha256:8cd8872d67fe1501b19a843d006cdb5673cfbb74ac3d6d8f2c60e8e7723a7f5b"}, | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "django-crispy-forms" | ||||||
|  | version = "2.0" | ||||||
|  | description = "Best way to have Django DRY forms" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.7" | ||||||
|  | files = [ | ||||||
|  |     {file = "django-crispy-forms-2.0.tar.gz", hash = "sha256:90193b068bf948d9c68449bc8260afed1a8e2afe11ee0bac8c4ebfaeb175b322"}, | ||||||
|  |     {file = "django_crispy_forms-2.0-py3-none-any.whl", hash = "sha256:d1d4e585929058a9ab3b797666ea5b69320b9ba7937f9d146d32173246a6fd13"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [package.dependencies] | ||||||
|  | django = ">=3.2" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "django-environ" | name = "django-environ" | ||||||
| version = "0.10.0" | version = "0.10.0" | ||||||
| @ -221,4 +253,4 @@ files = [ | |||||||
| [metadata] | [metadata] | ||||||
| lock-version = "2.0" | lock-version = "2.0" | ||||||
| python-versions = "^3.10" | python-versions = "^3.10" | ||||||
| content-hash = "82580779974f9b9a09d2b46c9d92491e870b66363e634d34252a31338da1aeff" | content-hash = "23169e9f6f71a2b23a984051083562a0b5cc0eb95a224bcd6dbef2b3dffe7b7b" | ||||||
|  | |||||||
| @ -13,6 +13,8 @@ djangorestframework = "^3.14.0" | |||||||
| djangorestframework-simplejwt = "^5.2.2" | djangorestframework-simplejwt = "^5.2.2" | ||||||
| django-environ = "^0.10.0" | django-environ = "^0.10.0" | ||||||
| django-cleanup = "^8.0.0" | django-cleanup = "^8.0.0" | ||||||
|  | django-crispy-forms = "^2.0" | ||||||
|  | crispy-bootstrap5 = "^0.7" | ||||||
| 
 | 
 | ||||||
| [tool.poetry.group.dev.dependencies] | [tool.poetry.group.dev.dependencies] | ||||||
| flake8 = "^6.0.0" | flake8 = "^6.0.0" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user