admin: cleanup templates, cleanup templatetags
This commit is contained in:
parent
6104b7c9ba
commit
5ba55356a9
|
@ -24,7 +24,7 @@
|
||||||
<ul class="pf-c-nav__list">
|
<ul class="pf-c-nav__list">
|
||||||
<li class="pf-c-nav__item">
|
<li class="pf-c-nav__item">
|
||||||
<a href="{% url 'passbook_admin:overview' %}"
|
<a href="{% url 'passbook_admin:overview' %}"
|
||||||
class="pf-c-nav__link {% is_active_url 'passbook_admin:overview' %}">
|
class="pf-c-nav__link {% is_active 'passbook_admin:overview' %}">
|
||||||
{% trans 'System Status' %}
|
{% trans 'System Status' %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
{% trans 'Property Mappings' %}
|
{% trans 'Property Mappings' %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="pf-c-nav__item pf-m-expandable pf-m-expanded pf-m-current">
|
<li class="pf-c-nav__item pf-m-expandable pf-m-current">
|
||||||
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Flows' %}
|
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Flows' %}
|
||||||
<span class="pf-c-nav__toggle">
|
<span class="pf-c-nav__toggle">
|
||||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
</li>
|
</li>
|
||||||
<li class="pf-c-nav__item pf-m-expandable pf-m-expanded pf-m-current">
|
<li class="pf-c-nav__item pf-m-expandable pf-m-current">
|
||||||
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Policies and Bindings' %}
|
<a href="#" class="pf-c-nav__link" aria-expanded="true">{% trans 'Policies and Bindings' %}
|
||||||
<span class="pf-c-nav__toggle">
|
<span class="pf-c-nav__toggle">
|
||||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||||
|
|
|
@ -26,31 +26,24 @@
|
||||||
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
|
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
|
||||||
<thead>
|
<thead>
|
||||||
<tr role="row">
|
<tr role="row">
|
||||||
<th role="columnheader" scope="col">{% trans 'Name' %}</th>
|
<th role="columnheader" scope="col">{% trans 'Enabled' %}</th>
|
||||||
<th role="columnheader" scope="col">{% trans 'Type' %}</th>
|
<th role="columnheader" scope="col">{% trans 'Policy' %}</th>
|
||||||
|
<th role="columnheader" scope="col">{% trans 'Target' %}</th>
|
||||||
<th role="cell"></th>
|
<th role="cell"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody role="rowgroup">
|
<tbody role="rowgroup" class="pf-m-expanded">
|
||||||
{% for binding in object_list %}
|
{% for binding in object_list %}
|
||||||
<tr role="row">
|
<tr role="row pf-c-table__expandable-row pf-m-expanded">
|
||||||
<th role="columnheader">
|
<th role="cell">
|
||||||
<div>
|
<div>{{ binding.enabled }}</div>
|
||||||
<div>{{ binding.name }}</div>
|
</th>
|
||||||
{% if not binding.bindings.exists %}
|
<th role="cell">
|
||||||
<i class="pf-icon pf-icon-warning-triangle"></i>
|
<div>{{ binding.policy }}</div>
|
||||||
<small>{% trans 'Warning: Policy is not assigned.' %}</small>
|
</th>
|
||||||
{% else %}
|
<th role="cell">
|
||||||
<i class="pf-icon pf-icon-ok"></i>
|
<div>{{ binding.target|verbose_name }}</div>
|
||||||
<small>{% blocktrans with object_count=binding.bindings.all|length %}Assigned to {{ object_count }} objects.{% endblocktrans %}</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</th>
|
</th>
|
||||||
<td role="cell">
|
|
||||||
<span>
|
|
||||||
{{ binding|verbose_name }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:policy-binding-update' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
<a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:policy-binding-update' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
||||||
<a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:policy-binding-delete' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
|
<a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:policy-binding-delete' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
|
||||||
|
|
|
@ -33,33 +33,49 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody role="rowgroup">
|
<tbody role="rowgroup">
|
||||||
{% for binding in object_list %}
|
{% regroup object_list by flow as grouped_bindings %}
|
||||||
<tr role="row">
|
{% for flow in grouped_bindings %}
|
||||||
<td role="cell">
|
<tr role="role">
|
||||||
<span>
|
<td>
|
||||||
{{ binding.order }}
|
{% blocktrans with name=flow.grouper.name %}
|
||||||
</span>
|
Flow {{ name }}
|
||||||
</td>
|
{% endblocktrans %}
|
||||||
<th role="columnheader">
|
</td>
|
||||||
<div>
|
<td></td>
|
||||||
<div>{{ binding.stage.name }}</div>
|
<td></td>
|
||||||
<small>
|
<td></td>
|
||||||
{% blocktrans with flow=binding.flow %}
|
</tr>
|
||||||
Bound to {{ flow }}.
|
{% for binding in flow.list %}
|
||||||
{% endblocktrans %}
|
<tr class="pf-c-table__expandable-row pf-m-expanded" role="row">
|
||||||
</small>
|
<td role="cell">
|
||||||
</div>
|
<span>
|
||||||
</th>
|
{{ binding.order }}
|
||||||
<td role="cell">
|
</span>
|
||||||
<span>
|
</td>
|
||||||
{{ binding.stage }}
|
<th role="columnheader">
|
||||||
</span>
|
<div>
|
||||||
</td>
|
<div>{{ binding.flow.name }}</div>
|
||||||
<td>
|
<small>
|
||||||
<a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:stage-binding-update' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
{{ binding.flow }}
|
||||||
<a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:stage-binding-delete' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
|
</small>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</th>
|
||||||
|
<td role="cell">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
{{ binding.stage.name }}
|
||||||
|
</div>
|
||||||
|
<small>
|
||||||
|
{{ binding.stage }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:stage-binding-update' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
||||||
|
<a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:stage-binding-delete' pk=binding.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
|
@ -10,7 +10,6 @@ from django.utils.translation import ugettext as _
|
||||||
from django.views.generic import DeleteView, ListView, UpdateView
|
from django.views.generic import DeleteView, ListView, UpdateView
|
||||||
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
|
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
|
||||||
|
|
||||||
from passbook.lib.utils.reflection import path_to_class
|
|
||||||
from passbook.lib.views import CreateAssignPermView
|
from passbook.lib.views import CreateAssignPermView
|
||||||
from passbook.policies.forms import PolicyBindingForm
|
from passbook.policies.forms import PolicyBindingForm
|
||||||
from passbook.policies.models import PolicyBinding
|
from passbook.policies.models import PolicyBinding
|
||||||
|
@ -22,7 +21,7 @@ class PolicyBindingListView(LoginRequiredMixin, PermissionListMixin, ListView):
|
||||||
model = PolicyBinding
|
model = PolicyBinding
|
||||||
permission_required = "passbook_policies.view_policybinding"
|
permission_required = "passbook_policies.view_policybinding"
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
ordering = "order"
|
ordering = ["order", "target"]
|
||||||
template_name = "administration/policybinding/list.html"
|
template_name = "administration/policybinding/list.html"
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,13 +41,6 @@ class PolicyBindingCreateView(
|
||||||
success_url = reverse_lazy("passbook_admin:policies")
|
success_url = reverse_lazy("passbook_admin:policies")
|
||||||
success_message = _("Successfully created PolicyBinding")
|
success_message = _("Successfully created PolicyBinding")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
kwargs = super().get_context_data(**kwargs)
|
|
||||||
form_cls = self.get_form_class()
|
|
||||||
if hasattr(form_cls, "template_name"):
|
|
||||||
kwargs["base_template"] = form_cls.template_name
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingUpdateView(
|
class PolicyBindingUpdateView(
|
||||||
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, UpdateView
|
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, UpdateView
|
||||||
|
@ -70,18 +62,6 @@ class PolicyBindingUpdateView(
|
||||||
kwargs["base_template"] = form_cls.template_name
|
kwargs["base_template"] = form_cls.template_name
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_form_class(self):
|
|
||||||
form_class_path = self.get_object().form
|
|
||||||
form_class = path_to_class(form_class_path)
|
|
||||||
return form_class
|
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
|
||||||
return (
|
|
||||||
PolicyBinding.objects.filter(pk=self.kwargs.get("pk"))
|
|
||||||
.select_subclasses()
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingDeleteView(
|
class PolicyBindingDeleteView(
|
||||||
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, DeleteView
|
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, DeleteView
|
||||||
|
|
|
@ -21,8 +21,8 @@ class StageBindingListView(LoginRequiredMixin, PermissionListMixin, ListView):
|
||||||
model = FlowStageBinding
|
model = FlowStageBinding
|
||||||
permission_required = "passbook_flows.view_flowstagebinding"
|
permission_required = "passbook_flows.view_flowstagebinding"
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
ordering = "order"
|
ordering = ["order", "flow"]
|
||||||
template_name = "administration/flowstagebinding/list.html"
|
template_name = "administration/stage_binding/list.html"
|
||||||
|
|
||||||
|
|
||||||
class StageBindingCreateView(
|
class StageBindingCreateView(
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_core:overview' %}"
|
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_core:overview' %}"
|
||||||
href="{% url 'passbook_core:overview' %}">{% trans 'Access' %}</a></li>
|
href="{% url 'passbook_core:overview' %}">{% trans 'Access' %}</a></li>
|
||||||
{% if user.is_superuser %}
|
{% if user.is_superuser %}
|
||||||
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_admin:overview' %}"
|
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_app 'passbook_admin' %}"
|
||||||
href="{% url 'passbook_admin:overview' %}">{% trans 'Administrate' %}</a></li>
|
href="{% url 'passbook_admin:overview' %}">{% trans 'Administrate' %}</a></li>
|
||||||
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_admin:audit-log' %}"
|
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_admin:audit-log' %}"
|
||||||
href="{% url 'passbook_admin:audit-log' %}">{% trans 'Monitor' %}</a></li>
|
href="{% url 'passbook_admin:audit-log' %}">{% trans 'Monitor' %}</a></li>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""passbook lib navbar Templatetag"""
|
"""passbook lib navbar Templatetag"""
|
||||||
from django import template
|
from django import template
|
||||||
|
from django.http import HttpRequest
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
@ -9,47 +10,43 @@ ACTIVE_STRING = "pf-m-current"
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
def is_active(context, *args, **kwargs):
|
def is_active(context, *args: str, **_) -> str:
|
||||||
"""Return whether a navbar link is active or not."""
|
"""Return whether a navbar link is active or not."""
|
||||||
request = context.get("request")
|
request: HttpRequest = context.get("request")
|
||||||
app_name = kwargs.get("app_name", None)
|
|
||||||
if not request.resolver_match:
|
if not request.resolver_match:
|
||||||
return ""
|
return ""
|
||||||
|
match = request.resolver_match
|
||||||
for url in args:
|
for url in args:
|
||||||
short_url = url.split(":")[1] if ":" in url else url
|
if ":" in url:
|
||||||
# Check if resolver_match matches
|
app_name, url = url.split(":")
|
||||||
if request.resolver_match.url_name.startswith(
|
if match.app_name == app_name and match.url_name == url:
|
||||||
url
|
|
||||||
) or request.resolver_match.url_name.startswith(short_url):
|
|
||||||
# Monkeypatch app_name: urls from core have app_name == ''
|
|
||||||
# since the root urlpatterns have no namespace
|
|
||||||
if app_name and request.resolver_match.app_name == app_name:
|
|
||||||
return ACTIVE_STRING
|
return ACTIVE_STRING
|
||||||
if app_name is None:
|
else:
|
||||||
|
if match.url_name == url:
|
||||||
return ACTIVE_STRING
|
return ACTIVE_STRING
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
def is_active_url(context, view):
|
def is_active_url(context, view: str) -> str:
|
||||||
"""Return whether a navbar link is active or not."""
|
"""Return whether a navbar link is active or not."""
|
||||||
request = context.get("request")
|
request: HttpRequest = context.get("request")
|
||||||
current_full_url = (
|
|
||||||
f"{request.resolver_match.app_name}:{request.resolver_match.url_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not request.resolver_match:
|
if not request.resolver_match:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
match = request.resolver_match
|
||||||
|
current_full_url = f"{match.app_name}:{match.url_name}"
|
||||||
|
|
||||||
if current_full_url == view:
|
if current_full_url == view:
|
||||||
return ACTIVE_STRING
|
return ACTIVE_STRING
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
def is_active_app(context, *args):
|
def is_active_app(context, *args: str) -> str:
|
||||||
"""Return True if current link is from app"""
|
"""Return True if current link is from app"""
|
||||||
|
|
||||||
request = context.get("request")
|
request: HttpRequest = context.get("request")
|
||||||
if not request.resolver_match:
|
if not request.resolver_match:
|
||||||
return ""
|
return ""
|
||||||
for app_name in args:
|
for app_name in args:
|
||||||
|
|
|
@ -6,11 +6,13 @@ from django import template
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
from django.template import Context
|
from django.template import Context
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.lib.config import CONFIG
|
from passbook.lib.config import CONFIG
|
||||||
from passbook.lib.utils.urls import is_url_absolute
|
from passbook.lib.utils.urls import is_url_absolute
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
|
@ -78,7 +80,7 @@ def gravatar(email, size=None, rating=None):
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def verbose_name(obj):
|
def verbose_name(obj) -> str:
|
||||||
"""Return Object's Verbose Name"""
|
"""Return Object's Verbose Name"""
|
||||||
if not obj:
|
if not obj:
|
||||||
return ""
|
return ""
|
||||||
|
@ -86,8 +88,15 @@ def verbose_name(obj):
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def form_verbose_name(obj):
|
def form_verbose_name(obj) -> str:
|
||||||
"""Return ModelForm's Object's Verbose Name"""
|
"""Return ModelForm's Object's Verbose Name"""
|
||||||
if not obj:
|
if not obj:
|
||||||
return ""
|
return ""
|
||||||
return obj._meta.model._meta.verbose_name
|
return obj._meta.model._meta.verbose_name
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def debug(obj) -> str:
|
||||||
|
"""Output object to logger"""
|
||||||
|
LOGGER.debug(obj)
|
||||||
|
return ""
|
||||||
|
|
Reference in New Issue