sideabar fixed in dhjanog

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-14 23:43:10 +00:00
parent 78f71558ed
commit aa48a55504
21 changed files with 703 additions and 71 deletions

View File

@@ -1,7 +1,7 @@
"""
Admin module for IGNY8
"""
from .base import AccountAdminMixin, SiteSectorAdminMixin
# Note: Igny8ModelAdmin is imported by individual admin modules as needed to avoid circular imports
__all__ = ['AccountAdminMixin', 'SiteSectorAdminMixin']
__all__ = []

View File

@@ -107,3 +107,77 @@ class SiteSectorAdminMixin:
return obj.site in accessible_sites
return super().has_delete_permission(request, obj)
# ============================================================================
# Custom ModelAdmin for Sidebar Fix
# ============================================================================
from unfold.admin import ModelAdmin as UnfoldModelAdmin
class Igny8ModelAdmin(UnfoldModelAdmin):
"""
Custom ModelAdmin that ensures sidebar_navigation is set correctly on ALL pages
Django's ModelAdmin views don't call AdminSite.each_context(),
so we override them to inject our custom sidebar.
"""
def _inject_sidebar_context(self, request, extra_context=None):
"""Helper to inject custom sidebar into context"""
if extra_context is None:
extra_context = {}
# Get our custom sidebar from the admin site
from igny8_core.admin.site import admin_site
# CRITICAL: Get the full Unfold context (includes all branding, form classes, etc.)
# This is what makes the logo/title appear properly
unfold_context = admin_site.each_context(request)
# Get the current path to detect active group
current_path = request.path
sidebar_navigation = admin_site.get_sidebar_list(request)
# Detect active group and expand it by setting collapsible=False
for group in sidebar_navigation:
group_is_active = False
for item in group.get('items', []):
item_link = item.get('link', '')
# Check if current path matches this item's link
if item_link and current_path.startswith(item_link):
item['active'] = True
group_is_active = True
# If any item in this group is active, expand the group
if group_is_active:
group['collapsible'] = False # Expanded state
else:
group['collapsible'] = True # Collapsed state
# Merge Unfold context with our custom sidebar
unfold_context['sidebar_navigation'] = sidebar_navigation
unfold_context['available_apps'] = admin_site.get_app_list(request, app_label=None)
unfold_context['app_list'] = unfold_context['available_apps']
# Merge with any existing extra_context
unfold_context.update(extra_context)
return unfold_context
def changelist_view(self, request, extra_context=None):
"""Override to inject custom sidebar"""
extra_context = self._inject_sidebar_context(request, extra_context)
return super().changelist_view(request, extra_context)
def change_view(self, request, object_id, form_url='', extra_context=None):
"""Override to inject custom sidebar"""
extra_context = self._inject_sidebar_context(request, extra_context)
return super().change_view(request, object_id, form_url, extra_context)
def add_view(self, request, form_url='', extra_context=None):
"""Override to inject custom sidebar"""
extra_context = self._inject_sidebar_context(request, extra_context)
return super().add_view(request, form_url, extra_context)

View File

@@ -31,6 +31,41 @@ class Igny8AdminSite(UnfoldAdminSite):
]
return custom_urls + urls
def get_sidebar_list(self, request):
"""
Override Unfold's get_sidebar_list to return our custom app groups
Convert Django app_list format to Unfold sidebar navigation format
"""
# Get our custom Django app list
django_apps = self.get_app_list(request, app_label=None)
# Convert to Unfold navigation format: {title, items: [{title, link, icon}]}
sidebar_groups = []
for app in django_apps:
group = {
'title': app['name'],
'collapsible': True,
'items': []
}
# Convert each model to navigation item
for model in app.get('models', []):
if model.get('perms', {}).get('view', False) or model.get('perms', {}).get('change', False):
item = {
'title': model['name'],
'link': model['admin_url'],
'icon': None, # Unfold will use default
'has_permission': True, # CRITICAL: Template checks this
}
group['items'].append(item)
# Only add groups that have items
if group['items']:
sidebar_groups.append(group)
return sidebar_groups
def each_context(self, request):
"""
Override context to ensure our custom app_list is always used
@@ -38,11 +73,31 @@ class Igny8AdminSite(UnfoldAdminSite):
CRITICAL FIX: Force custom sidebar on ALL pages including model detail/list views
"""
# CRITICAL: Must call parent to get sidebar_navigation set
context = super().each_context(request)
# Force our custom app list to be used everywhere - IGNORE app_label parameter
# DEBUGGING: Print to console what parent returned
print(f"\n=== DEBUG each_context for {request.path} ===")
print(f"sidebar_navigation length from parent: {len(context.get('sidebar_navigation', []))}")
if context.get('sidebar_navigation'):
print(f"First sidebar group: {context['sidebar_navigation'][0].get('title', 'NO TITLE')}")
# Force our custom app list to be used everywhere - IGNORE app_label parameter
custom_apps = self.get_app_list(request, app_label=None)
context['available_apps'] = custom_apps
context['app_list'] = custom_apps # Also set app_list for compatibility
# CRITICAL FIX: Ensure sidebar_navigation is using our custom sidebar
# Parent's each_context already called get_sidebar_list(), which returns our custom sidebar
# So sidebar_navigation should already be correct, but let's verify
if not context.get('sidebar_navigation') or len(context.get('sidebar_navigation', [])) == 0:
# If sidebar_navigation is empty, force it
print("WARNING: sidebar_navigation was empty, forcing it!")
context['sidebar_navigation'] = self.get_sidebar_list(request)
print(f"Final sidebar_navigation length: {len(context['sidebar_navigation'])}")
print("=== END DEBUG ===\n")
return context
def get_app_list(self, request, app_label=None):