Skip to content

Commit

Permalink
feat: tabs with filters (#876)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasvinclav authored Nov 25, 2024
1 parent b342733 commit cce7d2e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
29 changes: 24 additions & 5 deletions src/unfold/sites.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any, Callable, Dict, List, Optional, Union
from urllib.parse import parse_qs, urlparse

from django.contrib.admin import AdminSite
from django.contrib.auth import REDIRECT_FIELD_NAME
Expand Down Expand Up @@ -235,6 +236,7 @@ def password_change(

def get_sidebar_list(self, request: HttpRequest) -> List[Dict[str, Any]]:
navigation = get_config(self.settings_name)["SIDEBAR"].get("navigation", [])
tabs = get_config(self.settings_name)["TABS"]
results = []

for group in navigation:
Expand All @@ -246,7 +248,8 @@ def get_sidebar_list(self, request: HttpRequest) -> List[Dict[str, Any]]:
request, item.get("link_callback") or item["link"]
)

for tab in get_config(self.settings_name)["TABS"]:
# Checks if any tab item is active and then marks the sidebar link as active
for tab in tabs:
has_primary_link = False
has_tab_link_active = False

Expand Down Expand Up @@ -303,7 +306,7 @@ def get_tabs_list(self, request: HttpRequest) -> List[Dict[str, Any]]:
item["link_callback"] = lazy(item["link"])(request)

item["active"] = self._get_is_active(
request, item.get("link_callback") or item["link"]
request, item.get("link_callback") or item["link"], True
)
allowed_items.append(item)

Expand Down Expand Up @@ -392,13 +395,29 @@ def _process_colors(

return colors

def _get_is_active(self, request: HttpRequest, link: str) -> bool:
def _get_is_active(
self, request: HttpRequest, link: str, is_tab: bool = False
) -> bool:
if not isinstance(link, str):
link = str(link)

if link in request.path and link != reverse_lazy(f"{self.name}:index"):
index_path = reverse_lazy(f"{self.name}:index")
link_path = urlparse(link).path

# Dashboard
if link_path == request.path == index_path:
return True
elif link == request.path == reverse_lazy(f"{self.name}:index"):

if link_path in request.path and link_path != index_path:
query_params = parse_qs(urlparse(link).query)
request_params = parse_qs(request.GET.urlencode())

# In case of tabs, we need to check if the query params are the same
if is_tab and not all(
request_params.get(k) == v for k, v in query_params.items()
):
return False

return True

return False
6 changes: 3 additions & 3 deletions src/unfold/templates/unfold/helpers/tab_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{% for item in tabs_list %}
{% if item.has_permission %}
<li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-gray-800">
<a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}" class="block px-3 py-2 md:py-4 md:px-0 dark:border-gray-800 {% if item.active %} border-b font-semibold -mb-px text-primary-600 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-500 md:border-primary-500 dark:md:!border-primary-600{% else %}font-medium hover:text-gray-700 dark:hover:text-gray-200{% endif %}">
<a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}" class="block px-3 py-2 md:py-4 md:px-0 dark:border-gray-800 {% if item.active %} border-b font-semibold -mb-px text-primary-600 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-500 md:border-primary-500 dark:md:!border-primary-600{% else %}font-medium hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
{{ item.title }}
</a>
</li>
Expand All @@ -20,7 +20,7 @@
<a class="block cursor-pointer font-medium px-3 py-2 md:py-4 md:px-0"
href="#general"
x-on:click="activeTab = 'general'"
x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == 'general', 'hover:text-gray-700 dark:hover:text-gray-200 dark:border-gray-800': activeTab != 'general'}">
x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == 'general', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-gray-800': activeTab != 'general'}">
{% trans "General" %}
</a>
</li>
Expand All @@ -30,7 +30,7 @@
<a class="block cursor-pointer font-medium px-3 py-2 md:py-4 md:px-0"
href="#{{ inline.opts.verbose_name|slugify }}"
x-on:click="activeTab = '{{ inline.opts.verbose_name|slugify }}'"
x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ inline.opts.verbose_name|slugify }}', 'hover:text-gray-700 dark:hover:text-gray-200 dark:border-gray-800': activeTab != '{{ inline.opts.verbose_name|slugify }}'}">
x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ inline.opts.verbose_name|slugify }}', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-gray-800': activeTab != '{{ inline.opts.verbose_name|slugify }}'}">
{% if inline.formset.max_num == 1 %}
{{ inline.opts.verbose_name|capfirst }}
{% else %}
Expand Down

0 comments on commit cce7d2e

Please sign in to comment.