From 2581d2732bebfbfe46a275ca6bae6cfcd48074ea Mon Sep 17 00:00:00 2001 From: Horilla Date: Mon, 29 Jul 2024 16:50:00 +0530 Subject: [PATCH] [FIX] HORILLA VIEWS: Active view type in Horilla nav --- horilla_views/admin.py | 12 ++- horilla_views/forms.py | 41 +++++++++ horilla_views/models.py | 35 +++++++ .../templates/generic/horilla_nav.html | 13 ++- horilla_views/urls.py | 16 ++++ horilla_views/views.py | 91 +++++++++++++++++-- 6 files changed, 197 insertions(+), 11 deletions(-) diff --git a/horilla_views/admin.py b/horilla_views/admin.py index 03cb2a23a..ce350e7bb 100644 --- a/horilla_views/admin.py +++ b/horilla_views/admin.py @@ -1,5 +1,13 @@ from django.contrib import admin -from horilla_views.models import ActiveGroup, ActiveTab, ToggleColumn +from horilla_views import models -admin.site.register([ToggleColumn, ActiveTab, ActiveGroup]) +admin.site.register( + [ + models.ToggleColumn, + models.ActiveTab, + models.ActiveGroup, + models.SavedFilter, + models.ActiveView, + ] +) diff --git a/horilla_views/forms.py b/horilla_views/forms.py index a0b44cfdc..291f30235 100644 --- a/horilla_views/forms.py +++ b/horilla_views/forms.py @@ -7,6 +7,7 @@ from django.template.loader import render_to_string from django.utils.safestring import SafeText from horilla.horilla_middlewares import _thread_locals +from horilla_views import models class ToggleColumnForm(forms.Form): @@ -34,3 +35,43 @@ class ToggleColumnForm(forms.Form): context = {"form": self, "request": self.request} table_html = render_to_string("generic/as_list.html", context) return table_html + + +class SavedFilterForm(forms.ModelForm): + """ + SavedFilterForm + """ + + color = forms.CharField( + widget=forms.TextInput( + attrs={ + "class": "oh-input w-100", + "type": "color", + "placeholder": "Choose a color", + } + ) + ) + + class Meta: + model = models.SavedFilter + fields = ["title", "is_default", "color"] + + def structured(self): + """ + Render the form fields as HTML table rows with Bootstrap styling. + """ + request = getattr(_thread_locals, "request", None) + context = { + "form": self, + "request": request, + } + table_html = render_to_string("common_form.html", context) + return table_html + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + attrs = self.fields["title"].widget.attrs + attrs["class"] = "oh-input w-100" + attrs["placeholder"] = "Saved filter title" + if self.instance.pk: + self.verbose_name = self.instance.title diff --git a/horilla_views/models.py b/horilla_views/models.py index 683c93835..e6f2df5d8 100644 --- a/horilla_views/models.py +++ b/horilla_views/models.py @@ -50,3 +50,38 @@ class ActiveGroup(HorillaModel): path = models.CharField(max_length=256) group_target = models.CharField(max_length=256) group_by_field = models.CharField(max_length=256) + + +class SavedFilter(HorillaModel): + """ + SavedFilter + """ + + title = models.CharField(max_length=20, null=True) + color = models.CharField(max_length=10, default="") + is_default = models.BooleanField(default=False) + filter = models.TextField() + urlencode = models.TextField(default="") + path = models.CharField(max_length=256) + referrer = models.CharField(max_length=256, default="") + + def save(self, *args, **kwargs): + SavedFilter.objects.filter( + is_default=True, path=self.path, created_by=self.created_by + ).exclude(id=self.pk).update(is_default=False) + return super().save(*args, **kwargs) + + def __str__(self) -> str: + return str(self.title) + + +class ActiveView(HorillaModel): + """ + This model to store the active view type for HNV + """ + + path = models.CharField(max_length=256) + type = models.CharField(max_length=50) + + def save(self, *args, **kwargs): + return super().save(*args, **kwargs) diff --git a/horilla_views/templates/generic/horilla_nav.html b/horilla_views/templates/generic/horilla_nav.html index 3a6decda8..434438d6b 100644 --- a/horilla_views/templates/generic/horilla_nav.html +++ b/horilla_views/templates/generic/horilla_nav.html @@ -14,7 +14,7 @@ > -
+
{% for type in view_types %} -
  • + {% if active_view.type == type.type %} + + {% endif %}
  • {% endfor %} diff --git a/horilla_views/urls.py b/horilla_views/urls.py index f429f68e0..f7256066f 100644 --- a/horilla_views/urls.py +++ b/horilla_views/urls.py @@ -13,4 +13,20 @@ urlpatterns = [ path("active-group", views.ActiveGroup.as_view(), name="cbv-active-group"), path("reload-field", views.ReloadField.as_view(), name="reload-field"), path("reload-messages", ReloadMessages.as_view(), name="reload-messages"), + path("saved-filter/", views.SavedFilter.as_view(), name="saved-filter"), + path( + "saved-filter//", + views.SavedFilter.as_view(), + name="saved-filter-update", + ), + path( + "delete-saved-filter//", + views.DeleteSavedFilter.as_view(), + name="delete-saved-filter", + ), + path( + "active-hnv-view-type/", + views.ActiveView.as_view(), + name="active-hnv-view-type", + ), ] diff --git a/horilla_views/views.py b/horilla_views/views.py index 9e21fbb86..b0cfbd51d 100644 --- a/horilla_views/views.py +++ b/horilla_views/views.py @@ -1,17 +1,22 @@ import importlib from django import forms +from django.contrib import messages +from django.core.cache import cache as CACHE from django.http import HttpResponse, JsonResponse from django.shortcuts import render +from django.utils.decorators import method_decorator from django.views import View from horilla_views import models -from horilla_views.cbv_methods import get_short_uuid -from horilla_views.generic.cbv.views import dynamic_create_cache +from horilla_views.cbv_methods import get_short_uuid, login_required +from horilla_views.forms import SavedFilterForm +from horilla_views.generic.cbv.views import HorillaFormView # Create your views here. +@method_decorator(login_required, name="dispatch") class ToggleColumn(View): """ ToggleColumn @@ -42,6 +47,7 @@ class ToggleColumn(View): return HttpResponse("success") +@method_decorator(login_required, name="dispatch") class ReloadField(View): """ ReloadField @@ -58,17 +64,15 @@ class ReloadField(View): module = importlib.import_module(module_name) parent_form = getattr(module, class_name)() - dynamic_cache = dynamic_create_cache.get( - request.session.session_key + reload_field - ) - form: forms.ModelForm = dynamic_cache["form"] + dynamic_cache = CACHE.get(request.session.session_key + "cbv" + reload_field) + model: models.HorillaModel = dynamic_cache["model"] cache_field = dynamic_cache["dynamic_field"] if cache_field != reload_field: cache_field = reload_field field = parent_form.fields[cache_field] - queryset = form._meta.model.objects.all() + queryset = model.objects.all() queryset = field.queryset choices = [(instance.id, instance) for instance in queryset] choices.insert(0, ("", "Select option")) @@ -91,6 +95,7 @@ class ReloadField(View): ) +@method_decorator(login_required, name="dispatch") class ActiveTab(View): def get(self, *args, **kwargs): """ @@ -112,6 +117,7 @@ class ActiveTab(View): return JsonResponse({"message": "Success"}) +@method_decorator(login_required, name="dispatch") class ActiveGroup(View): def get(self, *args, **kwargs): """ @@ -135,3 +141,74 @@ class ActiveGroup(View): instance.group_target = target instance.save() return JsonResponse({"message": "Success"}) + + +@method_decorator(login_required, name="dispatch") +class SavedFilter(HorillaFormView): + """ + SavedFilter + """ + + model = models.SavedFilter + form_class = SavedFilterForm + new_display_title = "Save Applied Filter" + template_name = "generic/saved_filter_form.html" + form_disaply_attr = "Blah" + + def form_valid(self, form: SavedFilterForm) -> HttpResponse: + referrer = self.request.POST.get("referrer", "") + path = self.request.POST.get("path", "/") + result_dict = {key: value[0] for key, value in self.request.GET.lists()} + if form.is_valid(): + instance: models.SavedFilter = form.save(commit=False) + if not instance.pk: + instance.path = path + instance.referrer = referrer + instance.filter = result_dict + instance.urlencode = self.request.GET.urlencode() + instance.save() + messages.success(self.request, "Filter Saved") + return self.HttpResponse() + return super().form_valid(form) + + def get_context_data(self, **kwargs) -> dict: + context = super().get_context_data(**kwargs) + referrer = self.request.GET.get("referrer", "") + if referrer: + # Remove the protocol and domain part + referrer = "/" + "/".join(referrer.split("/")[3:]) + context["path"] = self.request.GET.get("path", "") + context["referrer"] = referrer + return context + + +@method_decorator(login_required, name="dispatch") +class DeleteSavedFilter(View): + """ + Delete saved filter + """ + + def get(self, *args, **kwargs): + pk = kwargs["pk"] + models.SavedFilter.objects.filter(created_by=self.request.user, pk=pk).delete() + return HttpResponse("") + + +@method_decorator(login_required, name="dispatch") +class ActiveView(View): + """ + ActiveView CBV + """ + + def get(self, *args, **kwargs): + path = self.request.GET["path"] + view_type = self.request.GET["view"] + active_view = models.ActiveView.objects.filter( + path=path, created_by=self.request.user + ).first() + + active_view = active_view if active_view else models.ActiveView() + active_view.path = path + active_view.type = view_type + active_view.save() + return HttpResponse("")