[ADD] HORILLA VIEWS: Accessibility method dynamic mapping to the HCV and HLV

This commit is contained in:
Horilla
2024-06-15 14:07:15 +05:30
parent 20bc0a6c24
commit b55a5ca849
7 changed files with 104 additions and 30 deletions

View File

@@ -2,6 +2,7 @@
horilla/cbv_methods.py
"""
import types
import uuid
from urllib.parse import urlencode
from venv import logger
@@ -236,6 +237,14 @@ def sortby(
)
reverse = cache[request.session.session_key].reverse
none_ids = []
none_queryset = []
model = queryset.model
model_attr = getattribute(model, sort_key)
is_method = isinstance(model_attr, types.FunctionType)
if not is_method:
none_queryset = queryset.filter(**{f"{sort_key}__isnull": True})
none_ids = list(none_queryset.values_list("id", flat=True))
queryset = queryset.exclude(id__in=none_ids)
def _sortby(object):
result = getattribute(object, attr=sort_key)
@@ -258,10 +267,14 @@ def sortby(
except TypeError:
none_queryset = list(queryset.filter(id__in=none_ids))
queryset = sorted(queryset.exclude(id__in=none_ids), key=_sortby, reverse=order)
queryset = queryset + none_queryset
cache[request.session.session_key].reverse = order
order = "asc" if not order else "desc"
if order:
order = "asc"
queryset = list(queryset) + list(none_queryset)
else:
queryset = list(none_queryset) + list(queryset)
order = "desc"
setattr(request, "sort_order", order)
setattr(request, "sort_key", sort_key)
return queryset

View File

@@ -52,6 +52,23 @@ class HorillaListView(ListView):
bulk_select_option: bool = True
action_method: str = """"""
"""
eg:
def accessibility(
request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs
)->bool:
# True if accessible to the action else False
return True
actions = [
{
"action": "Edit",
"accessibility": "path_to_your.accessibility", # path to your accessibility method
"attrs": '''{instance_attributes_called_like_this}''',
},
etc..
]
"""
actions: list = []
option_method: str = ""
@@ -392,7 +409,23 @@ class HorillaCardView(ListView):
search_url: str = ""
details: dict = {}
"""
eg:
def accessibility(
request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs
)->bool:
# True if accessible to the action else False
return True
actions = [
{
"action": "Edit",
"accessibility": "path_to_your.accessibility", # path to your accessibility method
"attrs": '''{instance_attributes_called_like_this}''',
},
etc..
]
"""
actions: list = []
card_attrs: str = """"""

View File

@@ -199,13 +199,15 @@
{% if not option_method %}
<div class="oh-btn-group">
{% for option in options %}
<a
href="#"
title="{{option.option|safe}}"
{{option.attrs|format:instance|safe}}
>
<ion-icon name="{{option.icon}}"></ion-icon>
</a>
{% if option.accessibility|accessibility:instance %}
<a
href="#"
title="{{option.option|safe}}"
{{option.attrs|format:instance|safe}}
>
<ion-icon name="{{option.icon}}"></ion-icon>
</a>
{% endif %}
{% endfor %}
</div>
{% else %} {{instance|getattribute:option_method|safe}} {% endif %}
@@ -215,13 +217,15 @@
{% if not action_method %}
<div class="oh-btn-group">
{% for action in actions %}
<a
href="#"
title="{{action.action|safe}}"
{{action.attrs|format:instance|safe}}
>
<ion-icon name="{{action.icon}}"></ion-icon>
</a>
{% if action.accessibility|accessibility:instance %}
<a
href="#"
title="{{action.action|safe}}"
{{action.attrs|format:instance|safe}}
>
<ion-icon name="{{action.icon}}"></ion-icon>
</a>
{% endif %}
{% endfor %}
</div>
{% else %} {{instance|getattribute:action_method|safe}} {% endif %}

View File

@@ -48,9 +48,11 @@
>
<ul class="oh-dropdown__items">
{% for action in actions %}
{% if action.accessibility|accessibility:instance %}
<li class="oh-dropdown__item">
<a {{action.attrs|format:instance|safe}}>{{instance|getattribute:action.action|default:action.action}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>

View File

@@ -218,13 +218,15 @@
{% if not option_method %}
<div class="oh-btn-group">
{% for option in options %}
<a
href="#"
title="{{option.option|safe}}"
{{option.attrs|format:instance|safe}}
>
<ion-icon name="{{option.icon}}"></ion-icon>
</a>
{% if option.accessibility|accessibility:instance %}
<a
href="#"
title="{{option.option|safe}}"
{{option.attrs|format:instance|safe}}
>
<ion-icon name="{{option.icon}}"></ion-icon>
</a>
{% endif %}
{% endfor %}
</div>
{% else %} {{instance|getattribute:option_method|safe}} {% endif %}
@@ -234,13 +236,15 @@
{% if not action_method %}
<div class="oh-btn-group">
{% for action in actions %}
<a
href="#"
title="{{action.action|safe}}"
{{action.attrs|format:instance|safe}}
>
<ion-icon name="{{action.icon}}"></ion-icon>
</a>
{% if action.accessibility|accessibility:instance %}
<a
href="#"
title="{{action.action|safe}}"
{{action.attrs|format:instance|safe}}
>
<ion-icon name="{{action.icon}}"></ion-icon>
</a>
{% endif %}
{% endfor %}
</div>
{% else %} {{instance|getattribute:action_method|safe}} {% endif %}

View File

@@ -10,3 +10,4 @@ $("#{{dynamic_id}} [name={{field.name}}]").change(function (e) {
}
});
</script>

View File

@@ -10,8 +10,12 @@ import types
from django import template
from django.conf import settings
from django.contrib.auth.context_processors import PermWrapper
from django.template.defaultfilters import register
from base.thread_local_middleware import _thread_locals
from horilla.config import import_method
register = template.Library()
@@ -60,3 +64,16 @@ def format(string: str, instance: object):
formatted_string = string.format(**format_context)
return formatted_string
@register.filter("accessibility")
def accessibility(method: str, instance=None):
if method:
request = getattr(_thread_locals, "request")
method = import_method(method)
return method(
request,
instance,
PermWrapper(request.user),
)
return True