[FIX] HORILLA VIEWS: Active view type in Horilla nav
This commit is contained in:
@@ -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,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
></ion-icon>
|
||||
</a>
|
||||
</div>
|
||||
<form autocomplete="off" id="filterForm" onsubmit="event.preventDefault()" hx-get="{{search_url}}" hx-replace-url="true" hx-target="{{search_swap_target}}" class="oh-main__titlebar oh-main__titlebar--right">
|
||||
<form autocomplete="off" id="filterForm" onsubmit="event.preventDefault()" hx-get="{{search_url}}?&referrer={{request.META.HTTP_REFERER}}&{{request.GET.urlencode}}" hx-replace-url="true" hx-target="{{search_swap_target}}" class="oh-main__titlebar oh-main__titlebar--right">
|
||||
<div class="oh-input-group oh-input__search-group" id="searchGroup">
|
||||
<ion-icon
|
||||
name="search-outline"
|
||||
@@ -73,11 +73,20 @@
|
||||
{% if view_types %}
|
||||
<ul class="oh-view-types">
|
||||
{% for type in view_types %}
|
||||
<li class="oh-view-type" onclick="$(this).closest('form').attr('hx-get','{{type.url}}');$(this).closest('form').find('#applyFilter').click();
|
||||
<li class="oh-view-type" data-url="{{type.url}}" data-type="{{type.type}}" hx-get="{% url "active-hnv-view-type" %}?view={{type.type}}&path={{request.path}}" hx-swap="none" onclick="$(this).closest('form').attr('hx-get','{{type.url}}?&referrer={{request.META.HTTP_REFERER}}&{{request.GET.urlencode}}');$(this).closest('form').find('#applyFilter').click();
|
||||
">
|
||||
<a class="oh-btn oh-btn--view" {{type.attrs|safe}}
|
||||
><ion-icon name="{{type.icon}}"></ion-icon
|
||||
></a>
|
||||
{% if active_view.type == type.type %}
|
||||
<script>
|
||||
$("form#filterForm.oh-main__titlebar oh-main__titlebar--right").attr('hx-get','{{type.url}}?&referrer={{request.META.HTTP_REFERER}}&{{request.GET.urlencode}}');
|
||||
setTimeout(() => {
|
||||
$(".oh-view-types .oh-view-type[data-type={{type.type}}]").click()
|
||||
$(".oh-view-types .oh-view-type[data-type={{type.type}}] a").addClass("oh-btn--view-active")
|
||||
}, 10);
|
||||
</script>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -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/<int:pk>/",
|
||||
views.SavedFilter.as_view(),
|
||||
name="saved-filter-update",
|
||||
),
|
||||
path(
|
||||
"delete-saved-filter/<int:pk>/",
|
||||
views.DeleteSavedFilter.as_view(),
|
||||
name="delete-saved-filter",
|
||||
),
|
||||
path(
|
||||
"active-hnv-view-type/",
|
||||
views.ActiveView.as_view(),
|
||||
name="active-hnv-view-type",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -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("")
|
||||
|
||||
Reference in New Issue
Block a user