This commit is contained in:
IGNY8 VPS (Salman)
2025-12-14 18:39:39 +00:00
parent 94b1ce8d8f
commit a518997467
2 changed files with 256 additions and 71 deletions

View File

@@ -1,5 +1,6 @@
""" """
Custom AdminSite for IGNY8 to organize models into proper groups using Unfold Custom AdminSite for IGNY8 to organize models into proper groups using Unfold
NO EMOJIS - Unfold handles all icons via Material Design
""" """
from django.contrib import admin from django.contrib import admin
from django.contrib.admin.apps import AdminConfig from django.contrib.admin.apps import AdminConfig
@@ -26,19 +27,31 @@ class Igny8AdminSite(UnfoldAdminSite):
def get_app_list(self, request): def get_app_list(self, request):
""" """
Customize the app list to organize models into logical groups Customize the app list to organize models into logical groups
NO EMOJIS - Unfold handles all icons via Material Design
""" """
# Get the default app list # Get the default app list
app_dict = self._build_app_dict(request) app_dict = self._build_app_dict(request)
# Define our custom groups with their models (using object_name) # Define our custom groups with their models (using object_name)
# Organized by business function with emoji icons for visual recognition # Organized by business function - Material icons configured in Unfold
custom_groups = { custom_groups = {
'💰 Billing & Accounts': { 'Igny8_Core_Auth': {
'models': [ 'models': [
('igny8_core_auth', 'Plan'),
('billing', 'PlanLimitUsage'),
('igny8_core_auth', 'Account'), ('igny8_core_auth', 'Account'),
('igny8_core_auth', 'User'),
('igny8_core_auth', 'Site'),
('igny8_core_auth', 'Sector'),
('igny8_core_auth', 'SiteUserAccess'),
('igny8_core_auth', 'Plan'),
('igny8_core_auth', 'Subscription'), ('igny8_core_auth', 'Subscription'),
('igny8_core_auth', 'PasswordResetToken'),
('igny8_core_auth', 'Industry'),
('igny8_core_auth', 'IndustrySector'),
('igny8_core_auth', 'SeedKeyword'),
],
},
'Billing & Tenancy': {
'models': [
('billing', 'Invoice'), ('billing', 'Invoice'),
('billing', 'Payment'), ('billing', 'Payment'),
('billing', 'CreditTransaction'), ('billing', 'CreditTransaction'),
@@ -47,18 +60,10 @@ class Igny8AdminSite(UnfoldAdminSite):
('billing', 'PaymentMethodConfig'), ('billing', 'PaymentMethodConfig'),
('billing', 'AccountPaymentMethod'), ('billing', 'AccountPaymentMethod'),
('billing', 'CreditCostConfig'), ('billing', 'CreditCostConfig'),
('billing', 'PlanLimitUsage'),
], ],
}, },
'👥 Sites & Users': { 'Writer Module': {
'models': [
('igny8_core_auth', 'Site'),
('igny8_core_auth', 'Sector'),
('igny8_core_auth', 'User'),
('igny8_core_auth', 'SiteUserAccess'),
('igny8_core_auth', 'PasswordResetToken'),
],
},
'📚 Content Management': {
'models': [ 'models': [
('writer', 'Content'), ('writer', 'Content'),
('writer', 'Tasks'), ('writer', 'Tasks'),
@@ -69,111 +74,112 @@ class Igny8AdminSite(UnfoldAdminSite):
('writer', 'ContentClusterMap'), ('writer', 'ContentClusterMap'),
], ],
}, },
'🎯 Planning & Strategy': { 'Planner': {
'models': [ 'models': [
('planner', 'Clusters'), ('planner', 'Clusters'),
('planner', 'Keywords'), ('planner', 'Keywords'),
('planner', 'ContentIdeas'), ('planner', 'ContentIdeas'),
('system', 'Strategy'),
], ],
}, },
'🔗 Integrations & Publishing': { 'Publishing': {
'models': [ 'models': [
('integration', 'SiteIntegration'),
('integration', 'SyncEvent'),
('publishing', 'PublishingRecord'), ('publishing', 'PublishingRecord'),
('publishing', 'DeploymentRecord'), ('publishing', 'DeploymentRecord'),
], ],
}, },
'🤖 AI & Automation': { 'Optimization': {
'models': [ 'models': [
('ai', 'AITaskLog'),
('system', 'AIPrompt'),
('automation', 'AutomationConfig'),
('automation', 'AutomationRun'),
('optimization', 'OptimizationTask'), ('optimization', 'OptimizationTask'),
], ],
}, },
'🌍 Global Reference Data': { 'Automation': {
'models': [ 'models': [
('igny8_core_auth', 'Industry'), ('automation', 'AutomationConfig'),
('igny8_core_auth', 'IndustrySector'), ('automation', 'AutomationRun'),
('igny8_core_auth', 'SeedKeyword'),
], ],
}, },
'⚙️ System Configuration': { 'Integration': {
'models': [ 'models': [
('system', 'IntegrationSettings'), ('integration', 'SiteIntegration'),
('integration', 'SyncEvent'),
],
},
'AI Framework': {
'models': [
('ai', 'AITaskLog'),
],
},
'System Configuration': {
'models': [
('system', 'AIPrompt'),
('system', 'Strategy'),
('system', 'AuthorProfile'), ('system', 'AuthorProfile'),
('system', 'SystemSettings'), ('system', 'ContentTemplate'),
('system', 'AccountSettings'), ('system', 'TaxonomyConfig'),
('system', 'UserSettings'), ('system', 'SystemSetting'),
('system', 'ModuleSettings'), ('system', 'ContentTypeConfig'),
('system', 'AISettings'), ('system', 'PublishingChannel'),
('system', 'ModuleEnableSettings'), ('system', 'APIKey'),
('system', 'SystemLog'), ('system', 'WebhookConfig'),
('system', 'SystemStatus'), ('system', 'NotificationConfig'),
('system', 'AuditLog'),
], ],
}, },
'<EFBFBD> Monitoring & Tasks': { 'Celery Results': {
'models': [ 'models': [
('django_celery_results', 'TaskResult'), ('django_celery_results', 'TaskResult'),
('django_celery_results', 'GroupResult'), ('django_celery_results', 'GroupResult'),
], ],
}, },
'<EFBFBD>🔧 Django System': { 'Content Types': {
'models': [
('contenttypes', 'ContentType'),
],
},
'Administration': {
'models': [ 'models': [
('admin', 'LogEntry'), ('admin', 'LogEntry'),
],
},
'Authentication and Authorization': {
'models': [
('auth', 'Group'), ('auth', 'Group'),
('auth', 'Permission'), ('auth', 'Permission'),
('contenttypes', 'ContentType'), ],
},
'Sessions': {
'models': [
('sessions', 'Session'), ('sessions', 'Session'),
], ],
}, },
} }
# Build the custom app list # Build the organized app list
app_list = [] organized_apps = []
for group_name, group_config in custom_groups.items(): for group_name, group_config in custom_groups.items():
group_models = [] group_models = []
for app_label, model_name in group_config['models']: for app_label, model_name in group_config['models']:
# Find the model in app_dict # Find the model in app_dict
if app_label in app_dict: for app in app_dict.values():
app_data = app_dict[app_label] if app['app_label'] == app_label:
# Look for the model in the app's models for model in app.get('models', []):
for model in app_data.get('models', []):
if model['object_name'] == model_name: if model['object_name'] == model_name:
group_models.append(model) group_models.append(model)
break break
# Only add the group if it has models
if group_models: if group_models:
app_list.append({ organized_apps.append({
'name': group_name, 'name': group_name,
'app_label': group_name.lower().replace(' ', '_').replace('&', '').replace('emoji', ''), 'app_label': group_name.lower().replace(' ', '_').replace('&', 'and'),
'app_url': None, 'app_url': '#',
'has_module_perms': True, 'has_module_perms': True,
'models': group_models, 'models': group_models,
}) })
# Sort the app list by our custom order return organized_apps
order = [
'💰 Billing & Accounts',
'👥 Sites & Users',
'📚 Content Management',
'🎯 Planning & Strategy',
'🔗 Integrations & Publishing',
'🤖 AI & Automation',
'🌍 Global Reference Data',
'⚙️ System Configuration',
'🔧 Django System',
]
app_list.sort(key=lambda x: order.index(x['name']) if x['name'] in order else 999)
return app_list
# Create admin site instance
admin_site = Igny8AdminSite(name='admin')

View File

@@ -0,0 +1,179 @@
"""
Custom AdminSite for IGNY8 to organize models into proper groups using Unfold
"""
from django.contrib import admin
from django.contrib.admin.apps import AdminConfig
from django.apps import apps
from django.urls import path, reverse_lazy
from django.shortcuts import redirect
from unfold.admin import ModelAdmin as UnfoldModelAdmin
from unfold.sites import UnfoldAdminSite
class Igny8AdminSite(UnfoldAdminSite):
"""
Custom AdminSite based on Unfold that organizes models into the planned groups
"""
site_header = 'IGNY8 Administration'
site_title = 'IGNY8 Admin'
index_title = 'IGNY8 Administration'
def get_urls(self):
"""Get admin URLs without custom dashboard"""
urls = super().get_urls()
return urls
def get_app_list(self, request):
"""
Customize the app list to organize models into logical groups
"""
# Get the default app list
app_dict = self._build_app_dict(request)
# Define our custom groups with their models (using object_name)
# Organized by business function with emoji icons for visual recognition
custom_groups = {
'💰 Billing & Accounts': {
'models': [
('igny8_core_auth', 'Plan'),
('billing', 'PlanLimitUsage'),
('igny8_core_auth', 'Account'),
('igny8_core_auth', 'Subscription'),
('billing', 'Invoice'),
('billing', 'Payment'),
('billing', 'CreditTransaction'),
('billing', 'CreditUsageLog'),
('billing', 'CreditPackage'),
('billing', 'PaymentMethodConfig'),
('billing', 'AccountPaymentMethod'),
('billing', 'CreditCostConfig'),
],
},
'👥 Sites & Users': {
'models': [
('igny8_core_auth', 'Site'),
('igny8_core_auth', 'Sector'),
('igny8_core_auth', 'User'),
('igny8_core_auth', 'SiteUserAccess'),
('igny8_core_auth', 'PasswordResetToken'),
],
},
'📚 Content Management': {
'models': [
('writer', 'Content'),
('writer', 'Tasks'),
('writer', 'Images'),
('writer', 'ContentTaxonomy'),
('writer', 'ContentAttribute'),
('writer', 'ContentTaxonomyRelation'),
('writer', 'ContentClusterMap'),
],
},
'🎯 Planning & Strategy': {
'models': [
('planner', 'Clusters'),
('planner', 'Keywords'),
('planner', 'ContentIdeas'),
('system', 'Strategy'),
],
},
'🔗 Integrations & Publishing': {
'models': [
('integration', 'SiteIntegration'),
('integration', 'SyncEvent'),
('publishing', 'PublishingRecord'),
('publishing', 'DeploymentRecord'),
],
},
'🤖 AI & Automation': {
'models': [
('ai', 'AITaskLog'),
('system', 'AIPrompt'),
('automation', 'AutomationConfig'),
('automation', 'AutomationRun'),
('optimization', 'OptimizationTask'),
],
},
'🌍 Global Reference Data': {
'models': [
('igny8_core_auth', 'Industry'),
('igny8_core_auth', 'IndustrySector'),
('igny8_core_auth', 'SeedKeyword'),
],
},
'⚙️ System Configuration': {
'models': [
('system', 'IntegrationSettings'),
('system', 'AuthorProfile'),
('system', 'SystemSettings'),
('system', 'AccountSettings'),
('system', 'UserSettings'),
('system', 'ModuleSettings'),
('system', 'AISettings'),
('system', 'ModuleEnableSettings'),
('system', 'SystemLog'),
('system', 'SystemStatus'),
],
},
'<EFBFBD> Monitoring & Tasks': {
'models': [
('django_celery_results', 'TaskResult'),
('django_celery_results', 'GroupResult'),
],
},
'<EFBFBD>🔧 Django System': {
'models': [
('admin', 'LogEntry'),
('auth', 'Group'),
('auth', 'Permission'),
('contenttypes', 'ContentType'),
('sessions', 'Session'),
],
},
}
# Build the custom app list
app_list = []
for group_name, group_config in custom_groups.items():
group_models = []
for app_label, model_name in group_config['models']:
# Find the model in app_dict
if app_label in app_dict:
app_data = app_dict[app_label]
# Look for the model in the app's models
for model in app_data.get('models', []):
if model['object_name'] == model_name:
group_models.append(model)
break
# Only add the group if it has models
if group_models:
app_list.append({
'name': group_name,
'app_label': group_name.lower().replace(' ', '_').replace('&', '').replace('emoji', ''),
'app_url': None,
'has_module_perms': True,
'models': group_models,
})
# Sort the app list by our custom order
order = [
'💰 Billing & Accounts',
'👥 Sites & Users',
'📚 Content Management',
'🎯 Planning & Strategy',
'🔗 Integrations & Publishing',
'🤖 AI & Automation',
'🌍 Global Reference Data',
'⚙️ System Configuration',
'🔧 Django System',
]
app_list.sort(key=lambda x: order.index(x['name']) if x['name'] in order else 999)
return app_list