From b1024ab3be8b8ffe0a1810a9dcf6398f213871bb Mon Sep 17 00:00:00 2001 From: Dan <47875749+leethobbit@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:01:15 -0400 Subject: [PATCH] Add medical and people views --- config/urls.py | 2 + dragonroost_ng/animals/tables.py | 7 +- dragonroost_ng/animals/urls.py | 4 +- dragonroost_ng/animals/views.py | 26 ++-- .../migrations/0002_meeting_meeting_url.py | 18 +++ .../business/migrations/0003_feedback.py | 23 ++++ .../migrations/0004_alter_feedback_name.py | 18 +++ .../0005_alter_meeting_meeting_url.py | 18 +++ .../migrations/0006_alter_meeting_minutes.py | 18 +++ .../migrations/0007_alter_meeting_minutes.py | 18 +++ dragonroost_ng/business/models.py | 42 ++++++- dragonroost_ng/business/tables.py | 14 ++- dragonroost_ng/business/urls.py | 18 +-- dragonroost_ng/business/views.py | 32 +++-- dragonroost_ng/medical/urls.py | 3 + dragonroost_ng/people/filters.py | 48 ++++++++ dragonroost_ng/people/tables.py | 17 +++ dragonroost_ng/people/urls.py | 19 +++ dragonroost_ng/people/views.py | 115 ++++++++++++++++++ .../templates/animals/_animal_cards.html | 2 +- .../templates/animals/animal_detail.html | 6 +- .../templates/animals/animal_table_htmx.html | 2 +- .../animals/animal_table_htmx_reload.html | 2 +- .../templates/animals/species_detail.html | 2 +- ...cies_list.html => species_table_htmx.html} | 0 .../animals/species_table_htmx_reload.html | 13 ++ dragonroost_ng/templates/base.html | 114 +++++++++++------ .../templates/business/_location_table.html | 2 +- .../business/location_confirm_delete.html | 2 +- .../templates/business/location_detail.html | 4 +- ...t.html => location_table_htmx_reload.html} | 2 +- ...st.html => meeting_table_htmx_reload.html} | 2 +- .../partials/location_table_htmx.html | 9 ++ .../business/partials/meeting_table_htmx.html | 9 ++ 34 files changed, 539 insertions(+), 92 deletions(-) create mode 100644 dragonroost_ng/business/migrations/0002_meeting_meeting_url.py create mode 100644 dragonroost_ng/business/migrations/0003_feedback.py create mode 100644 dragonroost_ng/business/migrations/0004_alter_feedback_name.py create mode 100644 dragonroost_ng/business/migrations/0005_alter_meeting_meeting_url.py create mode 100644 dragonroost_ng/business/migrations/0006_alter_meeting_minutes.py create mode 100644 dragonroost_ng/business/migrations/0007_alter_meeting_minutes.py create mode 100644 dragonroost_ng/medical/urls.py create mode 100644 dragonroost_ng/people/filters.py create mode 100644 dragonroost_ng/people/tables.py create mode 100644 dragonroost_ng/people/urls.py rename dragonroost_ng/templates/animals/{species_list.html => species_table_htmx.html} (100%) create mode 100644 dragonroost_ng/templates/animals/species_table_htmx_reload.html rename dragonroost_ng/templates/business/{location_list.html => location_table_htmx_reload.html} (80%) rename dragonroost_ng/templates/business/{meeting_list.html => meeting_table_htmx_reload.html} (80%) create mode 100644 dragonroost_ng/templates/business/partials/location_table_htmx.html create mode 100644 dragonroost_ng/templates/business/partials/meeting_table_htmx.html diff --git a/config/urls.py b/config/urls.py index d9c43ad..32f0c2d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -22,6 +22,8 @@ # Your stuff: custom urls includes go here path("animals/", include("dragonroost_ng.animals.urls", namespace="animals")), path("business/", include("dragonroost_ng.business.urls", namespace="business")), + path("medical", include("dragonroost_ng.medical.urls", namespace="medical")), + path("people/", include("dragonroost_ng.people.urls", namespace="people")), # Media files *static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT), ] diff --git a/dragonroost_ng/animals/tables.py b/dragonroost_ng/animals/tables.py index 80cf5f5..d2fb9fd 100644 --- a/dragonroost_ng/animals/tables.py +++ b/dragonroost_ng/animals/tables.py @@ -40,7 +40,7 @@ def render(self, value): ) -class AnimalHTMxTable(tables.Table): +class AnimalTable(tables.Table): animal_photo = AnimalImageColumn("Photo") id = tables.TemplateColumn( @@ -58,7 +58,7 @@ class AnimalHTMxTable(tables.Table): """, ) location = tables.TemplateColumn( - """ + """ {{record.location.name}} """, @@ -86,7 +86,7 @@ class Meta: template_name = "tables/bootstrap_htmx.html" -class SpeciesListTable(tables.Table): +class SpeciesTable(tables.Table): name = tables.TemplateColumn( """ {{record.name}} @@ -96,3 +96,4 @@ class SpeciesListTable(tables.Table): class Meta: model = Species fields = ("name", "diet", "class_name", "description") + template_name = "tables/bootstrap_htmx.html" diff --git a/dragonroost_ng/animals/urls.py b/dragonroost_ng/animals/urls.py index 39d495b..27e306f 100644 --- a/dragonroost_ng/animals/urls.py +++ b/dragonroost_ng/animals/urls.py @@ -3,7 +3,6 @@ from dragonroost_ng.animals.views import AnimalCreateView from dragonroost_ng.animals.views import AnimalDeleteView from dragonroost_ng.animals.views import AnimalDetailView -from dragonroost_ng.animals.views import AnimalListView from dragonroost_ng.animals.views import AnimalOutcomeView from dragonroost_ng.animals.views import AnimalUpdateView from dragonroost_ng.animals.views import HTMxAnimalTableDisplayView @@ -19,14 +18,13 @@ app_name = "animals" # This is for namespacing the URLs later urlpatterns = [ - path("", AnimalListView.as_view(), name="animal-list"), path("new/", AnimalCreateView.as_view(), name="animal-create"), path("/detail/", AnimalDetailView.as_view(), name="animal-detail"), path("/edit/", AnimalUpdateView.as_view(), name="animal-update"), path("/outcome/", AnimalOutcomeView.as_view(), name="animal-outcome"), path("/delete/", AnimalDeleteView.as_view(), name="animal-delete"), path("table/", HTMxAnimalTableDisplayView.as_view(), name="animal-table"), - path("table/search/", HTMxAnimalTableSearchView.as_view(), name="get_animal_list"), + path("table/search/", HTMxAnimalTableSearchView.as_view(), name="get-animal-list"), path("species/", SpeciesListView.as_view(), name="species-table"), path("species/new/", SpeciesCreateView.as_view(), name="species-create"), path( diff --git a/dragonroost_ng/animals/views.py b/dragonroost_ng/animals/views.py index f37ee92..f9ae312 100644 --- a/dragonroost_ng/animals/views.py +++ b/dragonroost_ng/animals/views.py @@ -18,8 +18,8 @@ from dragonroost_ng.animals.models import Animal from dragonroost_ng.animals.models import MedicalRecord from dragonroost_ng.animals.models import Species -from dragonroost_ng.animals.tables import AnimalHTMxTable -from dragonroost_ng.animals.tables import SpeciesListTable +from dragonroost_ng.animals.tables import AnimalTable +from dragonroost_ng.animals.tables import SpeciesTable from dragonroost_ng.mixins import PageTitleViewMixin @@ -34,7 +34,7 @@ class HTMxAnimalTableDisplayView( or via reload. """ - table_class = AnimalHTMxTable + table_class = AnimalTable queryset = Animal.objects.all().order_by("name") filterset_class = AnimalFilter paginate_by = 15 @@ -54,7 +54,7 @@ class HTMxAnimalTableSearchView(LoginRequiredMixin, SingleTableMixin, FilterView This view only handles the small partial for reloading the table data specifically. """ - table_class = AnimalHTMxTable + table_class = AnimalTable queryset = Animal.objects.all().order_by("name") filterset_class = AnimalFilter paginate_by = 15 @@ -62,13 +62,6 @@ class HTMxAnimalTableSearchView(LoginRequiredMixin, SingleTableMixin, FilterView # Old views to update / remove / etc -class AnimalListView(LoginRequiredMixin, PageTitleViewMixin, ListView): - model = Animal - template_name = "animals/animal_list.html" - title = "Recent Intakes" - context_object_name = "animals" - - class AnimalDetailView(LoginRequiredMixin, PageTitleViewMixin, DetailView): model = Animal template_name = "animals/animal_detail.html" @@ -179,13 +172,20 @@ class SpeciesListView( ListView, ): model = Species - table_class = SpeciesListTable + table_class = SpeciesTable queryset = Species.objects.all().order_by("name") filterset_class = SpeciesFilter - template_name = "animals/species_list.html" title = "Species List" context_object_name = "species" + def get_template_names(self): + if self.request.htmx: + template_name = "animals/species_table_htmx.html" + else: + template_name = "animals/species_table_htmx_reload.html" + + return template_name + class SpeciesDetailView(LoginRequiredMixin, PageTitleViewMixin, DetailView): model = Species diff --git a/dragonroost_ng/business/migrations/0002_meeting_meeting_url.py b/dragonroost_ng/business/migrations/0002_meeting_meeting_url.py new file mode 100644 index 0000000..0f9b5d1 --- /dev/null +++ b/dragonroost_ng/business/migrations/0002_meeting_meeting_url.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='meeting', + name='meeting_url', + field=models.URLField(default='example.com'), + ), + ] diff --git a/dragonroost_ng/business/migrations/0003_feedback.py b/dragonroost_ng/business/migrations/0003_feedback.py new file mode 100644 index 0000000..3d30c46 --- /dev/null +++ b/dragonroost_ng/business/migrations/0003_feedback.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0002_meeting_meeting_url'), + ] + + operations = [ + migrations.CreateModel( + name='Feedback', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=80, unique=True)), + ('email_address', models.EmailField(blank=True, max_length=254)), + ('feedback_type', models.CharField(choices=[('SUGGESTION', 'Suggestion'), ('COMPLIMENT', 'Compliment'), ('COMPLAINT', 'Complaint')], default='SUGGESTION', max_length=80)), + ('feedback', models.TextField(blank=True, default='')), + ], + ), + ] diff --git a/dragonroost_ng/business/migrations/0004_alter_feedback_name.py b/dragonroost_ng/business/migrations/0004_alter_feedback_name.py new file mode 100644 index 0000000..5dabfb0 --- /dev/null +++ b/dragonroost_ng/business/migrations/0004_alter_feedback_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0003_feedback'), + ] + + operations = [ + migrations.AlterField( + model_name='feedback', + name='name', + field=models.CharField(blank=True, default='', max_length=80), + ), + ] diff --git a/dragonroost_ng/business/migrations/0005_alter_meeting_meeting_url.py b/dragonroost_ng/business/migrations/0005_alter_meeting_meeting_url.py new file mode 100644 index 0000000..e12e17d --- /dev/null +++ b/dragonroost_ng/business/migrations/0005_alter_meeting_meeting_url.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0004_alter_feedback_name'), + ] + + operations = [ + migrations.AlterField( + model_name='meeting', + name='meeting_url', + field=models.URLField(default='example.com', verbose_name='Meeting URL'), + ), + ] diff --git a/dragonroost_ng/business/migrations/0006_alter_meeting_minutes.py b/dragonroost_ng/business/migrations/0006_alter_meeting_minutes.py new file mode 100644 index 0000000..91e2cfd --- /dev/null +++ b/dragonroost_ng/business/migrations/0006_alter_meeting_minutes.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0005_alter_meeting_meeting_url'), + ] + + operations = [ + migrations.AlterField( + model_name='meeting', + name='minutes', + field=models.FileField(null=True, upload_to='meetings/%Y'), + ), + ] diff --git a/dragonroost_ng/business/migrations/0007_alter_meeting_minutes.py b/dragonroost_ng/business/migrations/0007_alter_meeting_minutes.py new file mode 100644 index 0000000..d388e21 --- /dev/null +++ b/dragonroost_ng/business/migrations/0007_alter_meeting_minutes.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.9 on 2024-10-28 20:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('business', '0006_alter_meeting_minutes'), + ] + + operations = [ + migrations.AlterField( + model_name='meeting', + name='minutes', + field=models.FileField(blank=True, upload_to='meetings/%Y'), + ), + ] diff --git a/dragonroost_ng/business/models.py b/dragonroost_ng/business/models.py index 4be6212..6dc402d 100644 --- a/dragonroost_ng/business/models.py +++ b/dragonroost_ng/business/models.py @@ -4,6 +4,32 @@ # Create your models here. +class Feedback(models.Model): + FEEDBACK_CHOICES = [ + ("SUGGESTION", "Suggestion"), + ("COMPLIMENT", "Compliment"), + ("COMPLAINT", "Complaint"), + ] + + name = models.CharField(max_length=80, null=False, blank=True, default="") + email_address = models.EmailField(blank=True) + feedback_type = models.CharField( + max_length=80, + choices=FEEDBACK_CHOICES, + default="SUGGESTION", + ) + feedback = models.TextField(blank=True, null=False, default="") + + def __str__(self): + """ + Required method to see the name field when a form is created with this model + """ + return self.name + + def get_absolute_url(self): + return f"/business/feedback/{self}/" + + class Location(models.Model): name = models.CharField(max_length=80, unique=True) description = models.TextField(blank=True, null=False, default="") @@ -14,6 +40,9 @@ def __str__(self): """ return self.name + def get_absolute_url(self): + return f"/business/locations/{self.id}/" + # class Meeting class Meeting(models.Model): @@ -23,16 +52,25 @@ class Meeting(models.Model): title = models.CharField(max_length=120, unique=True) date = models.DateField(auto_now_add=True) - minutes = models.FileField(upload_to="meetings/%Y") + meeting_url = models.URLField( + max_length=200, + default="example.com", + verbose_name="Meeting URL", + ) + minutes = models.FileField(upload_to="meetings/%Y", blank=True) def __str__(self) -> str: return self.title + def get_absolute_url(self): + return f"/business/meetings/{self.id}/" + # class Donation class Donation(models.Model): """ - Possible model for donations - not in use currently + Possible model for donations - not in use currently. + TODO: Change this to a more generic Transaction model. """ amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) diff --git a/dragonroost_ng/business/tables.py b/dragonroost_ng/business/tables.py index 9fbebf7..fdcc849 100644 --- a/dragonroost_ng/business/tables.py +++ b/dragonroost_ng/business/tables.py @@ -7,7 +7,7 @@ class LocationListTable(tables.Table): name = tables.TemplateColumn( """ - + {{record.name}} """, ) @@ -15,16 +15,24 @@ class LocationListTable(tables.Table): class Meta: model = Location fields = ("name", "description") + template_name = "tables/bootstrap_htmx.html" class MeetingListTable(tables.Table): title = tables.TemplateColumn( """ - + {{record.title}} """, ) + meeting_url = tables.TemplateColumn( + """ + {{record.meeting_url}} + """, + ) + class Meta: model = Meeting - fields = ("title", "date", "minutes") + fields = ("title", "date", "meeting_url", "minutes") + template_name = "tables/bootstrap_htmx.html" diff --git a/dragonroost_ng/business/urls.py b/dragonroost_ng/business/urls.py index 89365a3..ffd0176 100644 --- a/dragonroost_ng/business/urls.py +++ b/dragonroost_ng/business/urls.py @@ -13,29 +13,29 @@ app_name = "business" # This is for namespacing the URLs later urlpatterns = [ - path("locations/", LocationListView.as_view(), name="location_list"), - path("locations/new/", LocationCreateView.as_view(), name="location_create"), + path("locations/", LocationListView.as_view(), name="location-table"), + path("locations/new/", LocationCreateView.as_view(), name="location-create"), path( "locations//detail/", LocationDetailView.as_view(), - name="location_detail", + name="location-detail", ), path( "locations//edit/", LocationUpdateView.as_view(), - name="location_update", + name="location-update", ), path( "locations//delete/", LocationDeleteView.as_view(), - name="location_delete", + name="location-delete", ), - path("meetings/", MeetingListView.as_view(), name="meeting_list"), - path("meetings/new/", MeetingCreateView.as_view(), name="meeting_create"), - path("meetings//edit/", MeetingUpdateView.as_view(), name="meeting_update"), + path("meetings/", MeetingListView.as_view(), name="meeting-table"), + path("meetings/new/", MeetingCreateView.as_view(), name="meeting-create"), + path("meetings//edit/", MeetingUpdateView.as_view(), name="meeting-update"), path( "meetings//delete/", MeetingDeleteView.as_view(), - name="meeting_delete", + name="meeting-delete", ), ] diff --git a/dragonroost_ng/business/views.py b/dragonroost_ng/business/views.py index ee78ea8..008adc4 100644 --- a/dragonroost_ng/business/views.py +++ b/dragonroost_ng/business/views.py @@ -25,10 +25,16 @@ class LocationListView( model = Location table_class = LocationListTable queryset = Location.objects.all().order_by("name") - template_name = "business/location_list.html" title = "Location List" context_object_name = "locations" + def get_template_names(self): + if self.request.htmx: + template_name = "business/partials/location_table_htmx.html" + else: + template_name = "business/location_table_htmx_reload.html" + return template_name + class LocationDetailView(LoginRequiredMixin, PageTitleViewMixin, DetailView): model = Location @@ -44,7 +50,7 @@ class LocationCreateView(LoginRequiredMixin, PageTitleViewMixin, CreateView): fields = ("name", "description") def get_success_url(self): - return reverse_lazy("business:location_detail", kwargs={"pk": self.object.id}) + return reverse_lazy("business:location-detail", kwargs={"pk": self.object.id}) class LocationUpdateView(LoginRequiredMixin, PageTitleViewMixin, UpdateView): @@ -54,14 +60,14 @@ class LocationUpdateView(LoginRequiredMixin, PageTitleViewMixin, UpdateView): fields = ("name", "description") def get_success_url(self): - return reverse_lazy("business:location_detail", kwargs={"pk": self.object.id}) + return reverse_lazy("business:location-detail", kwargs={"pk": self.object.id}) class LocationDeleteView(LoginRequiredMixin, PageTitleViewMixin, DeleteView): model = Location title = "Delete Location" template_name = "business/location_confirm_delete.html" - success_url = reverse_lazy("business:location_list") + success_url = reverse_lazy("business:location-list") class MeetingListView( @@ -73,33 +79,39 @@ class MeetingListView( model = Meeting table_class = MeetingListTable queryset = Meeting.objects.all().order_by("-date") - template_name = "business/meeting_list.html" title = "Meeting List" context_object_name = "meetings" + def get_template_names(self): + if self.request.htmx: + template_name = "business/partials/meeting_table_htmx.html" + else: + template_name = "business/meeting_table_htmx_reload.html" + return template_name + class MeetingCreateView(LoginRequiredMixin, PageTitleViewMixin, CreateView): model = Meeting title = "Create Meeting" template_name = "business/business_form.html" - fields = ("title", "minutes") + fields = ("title", "meeting_url", "minutes") def get_success_url(self): - return reverse_lazy("business:meeting_list") + return reverse_lazy("business:meeting-table") class MeetingUpdateView(LoginRequiredMixin, PageTitleViewMixin, UpdateView): model = Meeting template_name = "business/business_form.html" title = "Edit Meeting" - fields = ("title", "minutes") + fields = ("title", "meeting_url", "minutes") def get_success_url(self): - return reverse_lazy("business:meeting_list") + return reverse_lazy("business:meeting-table") class MeetingDeleteView(LoginRequiredMixin, PageTitleViewMixin, DeleteView): model = Meeting title = "Delete Meeting" template_name = "business/meeting_confirm_delete.html" - success_url = reverse_lazy("business:meeting_list") + success_url = reverse_lazy("business:meeting-table") diff --git a/dragonroost_ng/medical/urls.py b/dragonroost_ng/medical/urls.py new file mode 100644 index 0000000..6c378a9 --- /dev/null +++ b/dragonroost_ng/medical/urls.py @@ -0,0 +1,3 @@ +app_name = "medical" + +urlpatterns = [] diff --git a/dragonroost_ng/people/filters.py b/dragonroost_ng/people/filters.py new file mode 100644 index 0000000..bddfe2d --- /dev/null +++ b/dragonroost_ng/people/filters.py @@ -0,0 +1,48 @@ +import django_filters +from crispy_forms.helper import FormHelper +from django.db.models import Q +from django.forms import TextInput + +from dragonroost_ng.people.models import Person + + +class PeopleSearchInput(TextInput): + input_type = "search" + + +class PersonFilter(django_filters.FilterSet): + query = django_filters.CharFilter( + method="universal_search", + label="", + widget=PeopleSearchInput(attrs={"placeholder": "Search..."}), + ) + + class Meta: + model = Person + fields = ["query"] + + def universal_search(self, queryset, name, value): + return Person.objects.filter( + Q(first_name__icontains=value) + | Q(last_name__icontains=value) + # | Q(email__icontains=value) + # | Q(phone_number__icontains=value) + | Q(roles__name__icontains=value), + # | Q(address__icontains=value) + # | Q(zip_code__icontains=value) + # | Q(notes__icontains=value) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form.helper = PersonFilterFormHelper() + self.form.helper.form_tag = False + + +class PersonFilterFormHelper(FormHelper): + """ + Subclassing the FormHelper simply to force GET method + and enable usage of form_tag = False in the AnimalFilter class. + """ + + form_method = "GET" diff --git a/dragonroost_ng/people/tables.py b/dragonroost_ng/people/tables.py new file mode 100644 index 0000000..f489aa3 --- /dev/null +++ b/dragonroost_ng/people/tables.py @@ -0,0 +1,17 @@ +import django_tables2 as tables + +from dragonroost_ng.people.models import Person + + +class PersonHTMxTable(tables.Table): + first_name = tables.TemplateColumn( + """ + + {{record.first_name}} + """, + ) + + class Meta: + model = Person + template_name = "tables/bootstrap_htmx.html" + fields = ("first_name", "last_name", "roles", "phone_number") diff --git a/dragonroost_ng/people/urls.py b/dragonroost_ng/people/urls.py new file mode 100644 index 0000000..3faeca1 --- /dev/null +++ b/dragonroost_ng/people/urls.py @@ -0,0 +1,19 @@ +from django.urls import path + +from dragonroost_ng.people.views import PersonCreateView +from dragonroost_ng.people.views import PersonDeleteView +from dragonroost_ng.people.views import PersonDetailView +from dragonroost_ng.people.views import PersonHTMxView +from dragonroost_ng.people.views import PersonListView +from dragonroost_ng.people.views import PersonUpdateView + +app_name = "people" # This is for namespacing the URLs later + +urlpatterns = [ + path("", PersonListView.as_view(), name="person-list"), + path("new/", PersonCreateView.as_view(), name="person-create"), + path("/detail/", PersonDetailView.as_view(), name="person-detail"), + path("/edit/", PersonUpdateView.as_view(), name="person-update"), + path("/delete/", PersonDeleteView.as_view(), name="person-delete"), + path("search/", PersonHTMxView.as_view(), name="person-table"), +] diff --git a/dragonroost_ng/people/views.py b/dragonroost_ng/people/views.py index 60f00ef..238de8b 100644 --- a/dragonroost_ng/people/views.py +++ b/dragonroost_ng/people/views.py @@ -1 +1,116 @@ # Create your views here. +from django.contrib.auth.mixins import LoginRequiredMixin +from django.urls import reverse_lazy +from django.views.generic import DetailView +from django.views.generic import ListView +from django.views.generic.edit import CreateView +from django.views.generic.edit import DeleteView +from django.views.generic.edit import UpdateView +from django_filters.views import FilterView +from django_tables2 import SingleTableMixin + +from dragonroost_ng.mixins import PageTitleViewMixin + +from .filters import PersonFilter +from .models import Person +from .tables import PersonHTMxTable + + +# Create your views here. +class PersonListView( + SingleTableMixin, + LoginRequiredMixin, + PageTitleViewMixin, + ListView, +): + model = Person + table_class = PersonHTMxTable + queryset = Person.objects.all().order_by("first_name") + template_name = "people/person-list.html" + title = "People List" + context_object_name = "people" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["volunteers"] = Person.objects.filter(roles__name="VOLUNTEER").order_by( + "first_name", + ) + context["adopters"] = Person.objects.filter(roles__name="ADOPTER").order_by( + "first_name", + ) + context["donors"] = Person.objects.filter(roles__name="DONOR").order_by( + "first_name", + ) + context["fosters"] = Person.objects.filter(roles__name="FOSTER").order_by( + "first_name", + ) + + return context + + +class PersonDetailView(LoginRequiredMixin, PageTitleViewMixin, DetailView): + model = Person + template_name = "people/person_detail.html" + title = "Person Details" + context_object_name = "person" + + +class PersonCreateView(LoginRequiredMixin, PageTitleViewMixin, CreateView): + model = Person + template_name = "people/person_form.html" + title = "Add Person" + fields = ( + "first_name", + "last_name", + "email", + "phone_number", + "roles", + "address", + "zip_code", + "notes", + ) + + def get_success_url(self): + return reverse_lazy("people:person-detail", kwargs={"pk": self.object.id}) + + +class PersonUpdateView(LoginRequiredMixin, PageTitleViewMixin, UpdateView): + model = Person + template_name = "people/person_form.html" + title = "Edit Person" + fields = ( + "first_name", + "last_name", + "email", + "phone_number", + "roles", + "address", + "zip_code", + "notes", + ) + + def get_success_url(self): + return reverse_lazy("people:person-detail", kwargs={"pk": self.object.id}) + + +class PersonDeleteView(LoginRequiredMixin, PageTitleViewMixin, DeleteView): + model = Person + template_name = "people/person_confirm_delete.html" + title = "Delete Person" + success_url = reverse_lazy("people:person-list") + + +class PersonHTMxView(SingleTableMixin, PageTitleViewMixin, FilterView): + table_class = PersonHTMxTable + queryset = Person.objects.all() + filterset_class = PersonFilter + paginate_by = 15 + title = "People Search" + + def get_template_names(self) -> list[str]: + if self.request.htmx: + template_name = "people/person_table_partial.html" + else: + template_name = "people/person_table_htmx.html" + + return template_name diff --git a/dragonroost_ng/templates/animals/_animal_cards.html b/dragonroost_ng/templates/animals/_animal_cards.html index b09a89d..db75a99 100644 --- a/dragonroost_ng/templates/animals/_animal_cards.html +++ b/dragonroost_ng/templates/animals/_animal_cards.html @@ -29,7 +29,7 @@
{{ animal.species.name }}

{{ animal.get_status_display }}

- {{ animal.location.name }} diff --git a/dragonroost_ng/templates/animals/animal_detail.html b/dragonroost_ng/templates/animals/animal_detail.html index a164bbb..9cfc0ee 100644 --- a/dragonroost_ng/templates/animals/animal_detail.html +++ b/dragonroost_ng/templates/animals/animal_detail.html @@ -9,7 +9,11 @@

diff --git a/dragonroost_ng/templates/animals/animal_table_htmx.html b/dragonroost_ng/templates/animals/animal_table_htmx.html index 42d662f..441ab66 100644 --- a/dragonroost_ng/templates/animals/animal_table_htmx.html +++ b/dragonroost_ng/templates/animals/animal_table_htmx.html @@ -10,7 +10,7 @@

{# Search form #} -

{# Search form #} -

- Species - {{ species.name }} + Species - {{ species.name }}

{{ species.description }}

Edit diff --git a/dragonroost_ng/templates/animals/species_list.html b/dragonroost_ng/templates/animals/species_table_htmx.html similarity index 100% rename from dragonroost_ng/templates/animals/species_list.html rename to dragonroost_ng/templates/animals/species_table_htmx.html diff --git a/dragonroost_ng/templates/animals/species_table_htmx_reload.html b/dragonroost_ng/templates/animals/species_table_htmx_reload.html new file mode 100644 index 0000000..55be3aa --- /dev/null +++ b/dragonroost_ng/templates/animals/species_table_htmx_reload.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% load django_tables2 %} + +{% block content %} +
+
+Add New Species +
+
+{% render_table table %} +{% endblock content %} diff --git a/dragonroost_ng/templates/base.html b/dragonroost_ng/templates/base.html index 7277aa8..c96bbf7 100644 --- a/dragonroost_ng/templates/base.html +++ b/dragonroost_ng/templates/base.html @@ -109,12 +109,12 @@ -
+
-
+
-

+

Actions


@@ -122,7 +122,7 @@

Animals

  • Manage Species
  • - -
    -
    -
    -
    - {% if messages %} - {% for message in messages %} -
    - {{ message }} - -
    - {% endfor %} - {% endif %} - {% block main %} -
    - {% block content %} - Click a link on the left sidebar to get started. - {% endblock content %} -
    - {% endblock main %} -
    +
    +

    Business

    +
  • + Manage Locations +
  • +
  • + Manage Meetings +
  • +
    +

    People

    +
  • + Manage People +
  • +
    +

    Medical

    +
  • + TODO Manage Medical Updates +
  • +
    - {% endblock body %} - - {% block modal %} - {% endblock modal %} - {% block inline_javascript %} - {% comment %} +
    +
    + {% if messages %} + {% for message in messages %} +
    + {{ message }} + +
    + {% endfor %} + {% endif %} + {% block main %} +
    + {% block content %} + Click a link on the left sidebar to get started. + {% endblock content %} +
    + {% endblock main %} +
    +
    + +{% endblock body %} + +{% block modal %} +{% endblock modal %} +{% block inline_javascript %} + {% comment %} Script tags with only code, no src (defer by default). To run with a "defer" so that you run inline code: - {% endcomment %} - {% endblock inline_javascript %} - + {% endcomment %} +{% endblock inline_javascript %} + diff --git a/dragonroost_ng/templates/business/_location_table.html b/dragonroost_ng/templates/business/_location_table.html index 29008ef..e481627 100644 --- a/dragonroost_ng/templates/business/_location_table.html +++ b/dragonroost_ng/templates/business/_location_table.html @@ -9,7 +9,7 @@ {% for location in locations %} - {{ location.name }} + {{ location.name }} {{ location.description }} diff --git a/dragonroost_ng/templates/business/location_confirm_delete.html b/dragonroost_ng/templates/business/location_confirm_delete.html index ef0d2d4..b0a4a89 100644 --- a/dragonroost_ng/templates/business/location_confirm_delete.html +++ b/dragonroost_ng/templates/business/location_confirm_delete.html @@ -10,6 +10,6 @@

    Delete Location

    {% csrf_token %}
    - No, take me + No, take me back {% endblock content %} diff --git a/dragonroost_ng/templates/business/location_detail.html b/dragonroost_ng/templates/business/location_detail.html index fb7d118..671a309 100644 --- a/dragonroost_ng/templates/business/location_detail.html +++ b/dragonroost_ng/templates/business/location_detail.html @@ -3,6 +3,6 @@ {% block content %}

    {{ location.name }} - Detail

    {{ location.description }}

    - Edit - Delete + Edit + Delete {% endblock content %} diff --git a/dragonroost_ng/templates/business/location_list.html b/dragonroost_ng/templates/business/location_table_htmx_reload.html similarity index 80% rename from dragonroost_ng/templates/business/location_list.html rename to dragonroost_ng/templates/business/location_table_htmx_reload.html index 31f7679..6bc8ff5 100644 --- a/dragonroost_ng/templates/business/location_list.html +++ b/dragonroost_ng/templates/business/location_table_htmx_reload.html @@ -3,7 +3,7 @@ {% load django_tables2 %} {% block content %} - Add New Location

    diff --git a/dragonroost_ng/templates/business/meeting_list.html b/dragonroost_ng/templates/business/meeting_table_htmx_reload.html similarity index 80% rename from dragonroost_ng/templates/business/meeting_list.html rename to dragonroost_ng/templates/business/meeting_table_htmx_reload.html index ff0735e..2ffde63 100644 --- a/dragonroost_ng/templates/business/meeting_list.html +++ b/dragonroost_ng/templates/business/meeting_table_htmx_reload.html @@ -3,7 +3,7 @@ {% load django_tables2 %} {% block content %} - Add New Meeting

    diff --git a/dragonroost_ng/templates/business/partials/location_table_htmx.html b/dragonroost_ng/templates/business/partials/location_table_htmx.html new file mode 100644 index 0000000..c410724 --- /dev/null +++ b/dragonroost_ng/templates/business/partials/location_table_htmx.html @@ -0,0 +1,9 @@ +{% load django_tables2 %} + +{% block content %} + Add New Location +
    +
    +{% render_table table %} +{% endblock content %} diff --git a/dragonroost_ng/templates/business/partials/meeting_table_htmx.html b/dragonroost_ng/templates/business/partials/meeting_table_htmx.html new file mode 100644 index 0000000..0b17b8d --- /dev/null +++ b/dragonroost_ng/templates/business/partials/meeting_table_htmx.html @@ -0,0 +1,9 @@ +{% load django_tables2 %} + +{% block content %} + Add New Meeting +
    +
    +{% render_table table %} +{% endblock content %}