django-cfg 1.1.82__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. django_cfg/__init__.py +20 -448
  2. django_cfg/apps/accounts/README.md +3 -3
  3. django_cfg/apps/accounts/admin/__init__.py +0 -2
  4. django_cfg/apps/accounts/admin/activity.py +2 -9
  5. django_cfg/apps/accounts/admin/filters.py +0 -42
  6. django_cfg/apps/accounts/admin/inlines.py +8 -8
  7. django_cfg/apps/accounts/admin/otp.py +5 -5
  8. django_cfg/apps/accounts/admin/registration_source.py +1 -8
  9. django_cfg/apps/accounts/admin/user.py +12 -20
  10. django_cfg/apps/accounts/managers/user_manager.py +2 -129
  11. django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
  12. django_cfg/apps/accounts/models.py +3 -123
  13. django_cfg/apps/accounts/serializers/otp.py +40 -44
  14. django_cfg/apps/accounts/serializers/profile.py +0 -2
  15. django_cfg/apps/accounts/services/otp_service.py +98 -186
  16. django_cfg/apps/accounts/signals.py +25 -15
  17. django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
  18. django_cfg/apps/accounts/views/otp.py +35 -36
  19. django_cfg/apps/agents/README.md +129 -0
  20. django_cfg/apps/agents/__init__.py +68 -0
  21. django_cfg/apps/agents/admin/__init__.py +17 -0
  22. django_cfg/apps/agents/admin/execution_admin.py +460 -0
  23. django_cfg/apps/agents/admin/registry_admin.py +360 -0
  24. django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
  25. django_cfg/apps/agents/apps.py +29 -0
  26. django_cfg/apps/agents/core/__init__.py +20 -0
  27. django_cfg/apps/agents/core/agent.py +281 -0
  28. django_cfg/apps/agents/core/dependencies.py +154 -0
  29. django_cfg/apps/agents/core/exceptions.py +66 -0
  30. django_cfg/apps/agents/core/models.py +106 -0
  31. django_cfg/apps/agents/core/orchestrator.py +391 -0
  32. django_cfg/apps/agents/examples/__init__.py +3 -0
  33. django_cfg/apps/agents/examples/simple_example.py +161 -0
  34. django_cfg/apps/agents/integration/__init__.py +14 -0
  35. django_cfg/apps/agents/integration/middleware.py +80 -0
  36. django_cfg/apps/agents/integration/registry.py +345 -0
  37. django_cfg/apps/agents/integration/signals.py +50 -0
  38. django_cfg/apps/agents/management/__init__.py +3 -0
  39. django_cfg/apps/agents/management/commands/__init__.py +3 -0
  40. django_cfg/apps/agents/management/commands/create_agent.py +365 -0
  41. django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
  42. django_cfg/apps/agents/managers/__init__.py +23 -0
  43. django_cfg/apps/agents/managers/execution.py +236 -0
  44. django_cfg/apps/agents/managers/registry.py +254 -0
  45. django_cfg/apps/agents/managers/toolsets.py +496 -0
  46. django_cfg/apps/agents/migrations/0001_initial.py +286 -0
  47. django_cfg/apps/agents/migrations/__init__.py +5 -0
  48. django_cfg/apps/agents/models/__init__.py +15 -0
  49. django_cfg/apps/agents/models/execution.py +215 -0
  50. django_cfg/apps/agents/models/registry.py +220 -0
  51. django_cfg/apps/agents/models/toolsets.py +305 -0
  52. django_cfg/apps/agents/patterns/__init__.py +24 -0
  53. django_cfg/apps/agents/patterns/content_agents.py +234 -0
  54. django_cfg/apps/agents/toolsets/__init__.py +15 -0
  55. django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
  56. django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
  57. django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
  58. django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
  59. django_cfg/apps/agents/urls.py +46 -0
  60. django_cfg/apps/knowbase/README.md +150 -0
  61. django_cfg/apps/knowbase/__init__.py +27 -0
  62. django_cfg/apps/knowbase/admin/__init__.py +23 -0
  63. django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
  64. django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
  65. django_cfg/apps/knowbase/admin/document_admin.py +650 -0
  66. django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
  67. django_cfg/apps/knowbase/apps.py +81 -0
  68. django_cfg/apps/knowbase/config/README.md +176 -0
  69. django_cfg/apps/knowbase/config/__init__.py +51 -0
  70. django_cfg/apps/knowbase/config/constance_fields.py +186 -0
  71. django_cfg/apps/knowbase/config/constance_settings.py +200 -0
  72. django_cfg/apps/knowbase/config/settings.py +444 -0
  73. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  74. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  75. django_cfg/apps/knowbase/management/__init__.py +0 -0
  76. django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
  77. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
  78. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
  79. django_cfg/apps/knowbase/managers/__init__.py +22 -0
  80. django_cfg/apps/knowbase/managers/archive.py +426 -0
  81. django_cfg/apps/knowbase/managers/base.py +32 -0
  82. django_cfg/apps/knowbase/managers/chat.py +141 -0
  83. django_cfg/apps/knowbase/managers/document.py +203 -0
  84. django_cfg/apps/knowbase/managers/external_data.py +471 -0
  85. django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
  86. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
  87. django_cfg/apps/knowbase/migrations/__init__.py +5 -0
  88. django_cfg/apps/knowbase/mixins/__init__.py +15 -0
  89. django_cfg/apps/knowbase/mixins/config.py +108 -0
  90. django_cfg/apps/knowbase/mixins/creator.py +81 -0
  91. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  92. django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
  93. django_cfg/apps/knowbase/mixins/service.py +362 -0
  94. django_cfg/apps/knowbase/models/__init__.py +41 -0
  95. django_cfg/apps/knowbase/models/archive.py +599 -0
  96. django_cfg/apps/knowbase/models/base.py +58 -0
  97. django_cfg/apps/knowbase/models/chat.py +157 -0
  98. django_cfg/apps/knowbase/models/document.py +267 -0
  99. django_cfg/apps/knowbase/models/external_data.py +376 -0
  100. django_cfg/apps/knowbase/serializers/__init__.py +68 -0
  101. django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
  102. django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
  103. django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
  104. django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
  105. django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
  106. django_cfg/apps/knowbase/services/__init__.py +40 -0
  107. django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
  108. django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
  109. django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
  110. django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
  111. django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
  112. django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
  113. django_cfg/apps/knowbase/services/base.py +53 -0
  114. django_cfg/apps/knowbase/services/chat_service.py +239 -0
  115. django_cfg/apps/knowbase/services/document_service.py +144 -0
  116. django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
  117. django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
  118. django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
  119. django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
  120. django_cfg/apps/knowbase/services/embedding/models.py +229 -0
  121. django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
  122. django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
  123. django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
  124. django_cfg/apps/knowbase/services/search_service.py +293 -0
  125. django_cfg/apps/knowbase/signals/__init__.py +21 -0
  126. django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
  127. django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
  128. django_cfg/apps/knowbase/signals/document_signals.py +143 -0
  129. django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
  130. django_cfg/apps/knowbase/tasks/__init__.py +39 -0
  131. django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
  132. django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
  133. django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
  134. django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
  135. django_cfg/apps/knowbase/urls.py +43 -0
  136. django_cfg/apps/knowbase/utils/__init__.py +12 -0
  137. django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
  138. django_cfg/apps/knowbase/utils/text_processing.py +375 -0
  139. django_cfg/apps/knowbase/utils/validation.py +99 -0
  140. django_cfg/apps/knowbase/views/__init__.py +28 -0
  141. django_cfg/apps/knowbase/views/archive_views.py +469 -0
  142. django_cfg/apps/knowbase/views/base.py +49 -0
  143. django_cfg/apps/knowbase/views/chat_views.py +181 -0
  144. django_cfg/apps/knowbase/views/document_views.py +183 -0
  145. django_cfg/apps/knowbase/views/public_views.py +129 -0
  146. django_cfg/apps/leads/admin.py +70 -0
  147. django_cfg/apps/newsletter/admin.py +234 -0
  148. django_cfg/apps/newsletter/admin_filters.py +124 -0
  149. django_cfg/apps/support/admin.py +196 -0
  150. django_cfg/apps/support/admin_filters.py +71 -0
  151. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  152. django_cfg/apps/urls.py +5 -4
  153. django_cfg/cli/README.md +1 -1
  154. django_cfg/cli/commands/create_project.py +2 -2
  155. django_cfg/cli/commands/info.py +1 -1
  156. django_cfg/config.py +44 -0
  157. django_cfg/core/config.py +29 -82
  158. django_cfg/core/environment.py +1 -1
  159. django_cfg/core/generation.py +19 -107
  160. django_cfg/{integration.py → core/integration.py} +18 -16
  161. django_cfg/core/validation.py +1 -1
  162. django_cfg/management/__init__.py +1 -1
  163. django_cfg/management/commands/__init__.py +1 -1
  164. django_cfg/management/commands/auto_generate.py +482 -0
  165. django_cfg/management/commands/migrator.py +19 -101
  166. django_cfg/management/commands/test_email.py +1 -1
  167. django_cfg/middleware/README.md +0 -158
  168. django_cfg/middleware/__init__.py +0 -2
  169. django_cfg/middleware/user_activity.py +3 -3
  170. django_cfg/models/api.py +145 -0
  171. django_cfg/models/base.py +287 -0
  172. django_cfg/models/cache.py +4 -4
  173. django_cfg/models/constance.py +25 -88
  174. django_cfg/models/database.py +9 -9
  175. django_cfg/models/drf.py +3 -36
  176. django_cfg/models/email.py +163 -0
  177. django_cfg/models/environment.py +276 -0
  178. django_cfg/models/limits.py +1 -1
  179. django_cfg/models/logging.py +366 -0
  180. django_cfg/models/revolution.py +41 -2
  181. django_cfg/models/security.py +125 -0
  182. django_cfg/models/services.py +1 -1
  183. django_cfg/modules/__init__.py +2 -56
  184. django_cfg/modules/base.py +78 -52
  185. django_cfg/modules/django_currency/service.py +2 -2
  186. django_cfg/modules/django_email.py +2 -2
  187. django_cfg/modules/django_health.py +267 -0
  188. django_cfg/modules/django_llm/llm/client.py +79 -17
  189. django_cfg/modules/django_llm/translator/translator.py +2 -2
  190. django_cfg/modules/django_logger.py +2 -2
  191. django_cfg/modules/django_ngrok.py +2 -2
  192. django_cfg/modules/django_tasks.py +68 -3
  193. django_cfg/modules/django_telegram.py +3 -3
  194. django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
  195. django_cfg/modules/django_twilio/service.py +2 -2
  196. django_cfg/modules/django_twilio/simple_service.py +2 -2
  197. django_cfg/modules/django_twilio/twilio_service.py +2 -2
  198. django_cfg/modules/django_unfold/__init__.py +69 -0
  199. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  200. django_cfg/modules/django_unfold/dashboard.py +278 -0
  201. django_cfg/modules/django_unfold/icons/README.md +145 -0
  202. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  203. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  204. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  205. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  206. django_cfg/modules/django_unfold/models/config.py +601 -0
  207. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  208. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  209. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  210. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  211. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  212. django_cfg/modules/django_unfold/utils.py +140 -0
  213. django_cfg/registry/__init__.py +23 -0
  214. django_cfg/registry/core.py +61 -0
  215. django_cfg/registry/exceptions.py +11 -0
  216. django_cfg/registry/modules.py +12 -0
  217. django_cfg/registry/services.py +26 -0
  218. django_cfg/registry/third_party.py +52 -0
  219. django_cfg/routing/__init__.py +19 -0
  220. django_cfg/routing/callbacks.py +198 -0
  221. django_cfg/routing/routers.py +48 -0
  222. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  223. django_cfg/templatetags/__init__.py +0 -0
  224. django_cfg/templatetags/django_cfg.py +33 -0
  225. django_cfg/urls.py +33 -0
  226. django_cfg/utils/path_resolution.py +1 -1
  227. django_cfg/utils/smart_defaults.py +7 -61
  228. django_cfg/utils/toolkit.py +663 -0
  229. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
  230. django_cfg-1.2.0.dist-info/RECORD +441 -0
  231. django_cfg/archive/django_sample.zip +0 -0
  232. django_cfg/models/unfold.py +0 -271
  233. django_cfg/modules/unfold/__init__.py +0 -29
  234. django_cfg/modules/unfold/dashboard.py +0 -318
  235. django_cfg/pyproject.toml +0 -370
  236. django_cfg/routers.py +0 -83
  237. django_cfg-1.1.82.dist-info/RECORD +0 -278
  238. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  239. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  240. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  241. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  242. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
  243. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
  244. {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,271 +0,0 @@
1
- """
2
- Unfold Configuration Models for django_cfg.
3
-
4
- Provides type-safe configuration for Django Unfold admin interface.
5
- """
6
-
7
- from typing import List, Optional, Dict, Any
8
- from pydantic import BaseModel, Field
9
- from django.urls import reverse_lazy, NoReverseMatch
10
- import base64
11
-
12
- from django_cfg.modules.unfold.tailwind import get_unfold_colors, get_css_variables
13
-
14
- class UnfoldColors(BaseModel):
15
- """Unfold color theme configuration."""
16
-
17
- primary: Optional[str] = Field(None, description="Primary color")
18
- success: Optional[str] = Field(None, description="Success color")
19
- warning: Optional[str] = Field(None, description="Warning color")
20
- danger: Optional[str] = Field(None, description="Danger color")
21
- info: Optional[str] = Field(None, description="Info color")
22
-
23
-
24
- class UnfoldSidebar(BaseModel):
25
- """Unfold sidebar configuration."""
26
-
27
- show_search: bool = Field(True, description="Show search in sidebar")
28
- show_all_applications: bool = Field(True, description="Show all applications")
29
- navigation: List[Dict[str, Any]] = Field(default_factory=list, description="Custom navigation")
30
-
31
-
32
- class NavigationItem(BaseModel):
33
- """Single navigation item configuration."""
34
-
35
- title: str = Field(..., description="Navigation item title")
36
- icon: Optional[str] = Field(None, description="Material icon name")
37
- link: Optional[str] = Field(None, description="Navigation link")
38
- badge: Optional[str] = Field(None, description="Badge text")
39
-
40
- class NavigationGroup(BaseModel):
41
- """Navigation group configuration."""
42
-
43
- title: str = Field(..., description="Group title")
44
- separator: bool = Field(True, description="Add separator before group")
45
- collapsible: bool = Field(True, description="Group is collapsible")
46
- items: List[NavigationItem] = Field(default_factory=list, description="Group items")
47
-
48
-
49
- class DropdownItem(BaseModel):
50
- """Dropdown menu item configuration."""
51
-
52
- title: str = Field(..., description="Item title")
53
- icon: str = Field(..., description="Material icon name")
54
- link: str = Field(..., description="Item URL")
55
-
56
-
57
- class QuickAction(BaseModel):
58
- """Quick action configuration for dashboard."""
59
-
60
- title: str = Field(..., description="Action title")
61
- icon: str = Field(..., description="Material icon name")
62
- url: str = Field(..., description="Action URL")
63
- description: Optional[str] = Field(None, description="Action description")
64
- color: Optional[str] = Field(None, description="Action color")
65
-
66
-
67
- def get_reverse_lazy(link: str) -> str:
68
- try:
69
- return reverse_lazy(link)
70
- except NoReverseMatch:
71
- return link
72
-
73
-
74
- class DashboardWidget(BaseModel):
75
- """Dashboard widget configuration."""
76
-
77
- title: str = Field(..., description="Widget title")
78
- template: Optional[str] = Field(None, description="Custom template path")
79
- callback: Optional[str] = Field(None, description="Callback function path")
80
- width: int = Field(12, description="Widget width (1-12)")
81
- order: int = Field(0, description="Widget order")
82
-
83
-
84
- class UnfoldTheme(BaseModel):
85
- """Complete Unfold theme configuration."""
86
-
87
- # Basic theme settings
88
- site_title: str = Field("Django Admin", description="Site title")
89
- site_header: str = Field("Django Administration", description="Site header")
90
- site_url: str = Field("/", description="Site URL")
91
- site_symbol: str = Field("rocket_launch", description="Material icon for site")
92
-
93
- # UI settings
94
- show_history: bool = Field(True, description="Show history in admin")
95
- show_view_on_site: bool = Field(True, description="Show view on site links")
96
- show_back_button: bool = Field(False, description="Show back button")
97
-
98
- # Theme and appearance
99
- theme: Optional[str] = Field(None, description="Theme: light, dark, or None for switcher")
100
- colors: UnfoldColors = Field(default_factory=UnfoldColors, description="Color theme")
101
- sidebar: UnfoldSidebar = Field(default_factory=UnfoldSidebar, description="Sidebar config")
102
-
103
- # Dashboard
104
- dashboard_callback: Optional[str] = Field(None, description="Dashboard callback function")
105
- environment_callback: Optional[str] = Field(None, description="Environment callback function")
106
-
107
- # Navigation
108
- navigation: List[NavigationGroup] = Field(default_factory=list, description="Custom navigation")
109
-
110
- # Site dropdown menu
111
- site_dropdown: List[DropdownItem] = Field(default_factory=list, description="Site dropdown menu items")
112
-
113
- # Quick actions and widgets
114
- quick_actions: List[QuickAction] = Field(default_factory=list, description="Dashboard quick actions")
115
- widgets: List[DashboardWidget] = Field(default_factory=list, description="Dashboard widgets")
116
-
117
- def to_django_settings(self) -> Dict[str, Any]:
118
- """Convert to Django UNFOLD settings."""
119
- # Try to import colors, fallback to base colors if not available
120
- colors = get_unfold_colors()
121
-
122
- settings = {
123
- "SITE_TITLE": self.site_title,
124
- "SITE_HEADER": self.site_header,
125
- "SITE_URL": self.site_url,
126
- "SITE_SYMBOL": self.site_symbol,
127
- "SHOW_HISTORY": self.show_history,
128
- "SHOW_VIEW_ON_SITE": self.show_view_on_site,
129
- "SHOW_BACK_BUTTON": self.show_back_button,
130
- "COLORS": colors,
131
- "BORDER_RADIUS": "8px",
132
- }
133
-
134
- # Theme settings
135
- if self.theme:
136
- settings["THEME"] = self.theme
137
-
138
- # Sidebar configuration - KEY PART!
139
- sidebar_config = {
140
- "show_search": self.sidebar.show_search,
141
- "command_search": True,
142
- "show_all_applications": self.sidebar.show_all_applications,
143
- }
144
-
145
- # Get default navigation from dashboard manager
146
- from django_cfg.modules.unfold.dashboard import DashboardManager
147
- dashboard = DashboardManager()
148
- nav_items = dashboard.get_navigation_config()
149
-
150
- # 1. Add custom navigation from project (if defined)
151
- if self.navigation:
152
- # Project has custom navigation - add it first
153
- for group in self.navigation:
154
- group_dict = {
155
- "title": group.title,
156
- "separator": group.separator,
157
- "collapsible": group.collapsible,
158
- "items": [
159
- {
160
- "title": item.title,
161
- "icon": item.icon,
162
- "link": get_reverse_lazy(item.link),
163
- }
164
- for item in group.items
165
- ],
166
- }
167
- nav_items.append(group_dict)
168
-
169
- sidebar_config["navigation"] = nav_items
170
-
171
- settings["SIDEBAR"] = sidebar_config
172
-
173
- # Command interface
174
- settings["COMMAND"] = {
175
- "search_models": True,
176
- "show_history": True,
177
- }
178
-
179
- # Multi-language support - DISABLED
180
- settings["SHOW_LANGUAGES"] = False
181
-
182
- # Site dropdown menu
183
- if self.site_dropdown:
184
- settings["SITE_DROPDOWN"] = [
185
- {
186
- "icon": item.icon,
187
- "title": item.title,
188
- "link": item.link,
189
- }
190
- for item in self.site_dropdown
191
- ]
192
-
193
- # Dashboard callback
194
- if self.dashboard_callback:
195
- settings["DASHBOARD_CALLBACK"] = self.dashboard_callback
196
-
197
- # Environment callback
198
- if self.environment_callback:
199
- settings["ENVIRONMENT_CALLBACK"] = self.environment_callback
200
-
201
- return settings
202
-
203
-
204
-
205
- class UnfoldConfig(BaseModel):
206
- """
207
- Main Unfold configuration for django_cfg.
208
-
209
- Usage:
210
- unfold = UnfoldConfig(
211
- theme=UnfoldTheme(
212
- site_title="My Admin",
213
- site_header="My Project Admin",
214
- )
215
- )
216
- """
217
-
218
- enabled: bool = Field(True, description="Enable Unfold admin interface")
219
- theme: UnfoldTheme = Field(default_factory=UnfoldTheme, description="Unfold theme configuration")
220
-
221
- # Additional settings that can be overridden
222
- additional_settings: Dict[str, Any] = Field(default_factory=dict, description="Additional Django UNFOLD settings")
223
-
224
- def to_django_settings(self) -> Dict[str, Any]:
225
- """Generate Django settings for Unfold."""
226
- if not self.enabled:
227
- return {}
228
-
229
- # Get base settings from theme
230
- unfold_settings = self.theme.to_django_settings()
231
-
232
- # Inject universal CSS variables (includes object-tools flex)
233
- if "STYLES" not in unfold_settings:
234
- unfold_settings["STYLES"] = []
235
-
236
- # Add our CSS as inline data URI
237
- css_content = get_css_variables()
238
- css_b64 = base64.b64encode(css_content.encode('utf-8')).decode('utf-8')
239
- data_uri = f"data:text/css;base64,{css_b64}"
240
-
241
- unfold_settings["STYLES"].append(lambda request: data_uri)
242
-
243
- # Add Tailwind CSS CDN
244
- if "SCRIPTS" not in unfold_settings:
245
- unfold_settings["SCRIPTS"] = []
246
-
247
- # unfold_settings["SCRIPTS"].append(
248
- # lambda request: "https://cdn.tailwindcss.com/4.1.11"
249
- # )
250
-
251
- # Merge additional settings
252
- unfold_settings.update(self.additional_settings)
253
-
254
- return {"UNFOLD": unfold_settings}
255
-
256
- def get_installed_apps(self) -> List[str]:
257
- """Get required installed apps for Unfold."""
258
- if not self.enabled:
259
- return []
260
-
261
- return [
262
- "unfold", # Must be before django.contrib.admin
263
- "unfold.contrib.filters", # Optional filters
264
- "unfold.contrib.forms", # Optional form elements
265
- "unfold.contrib.inlines", # Inline forms
266
- "unfold.contrib.import_export", # Import/export functionality
267
- "unfold.contrib.guardian", # Guardian permissions
268
- "unfold.contrib.simple_history", # Simple history
269
- "unfold.contrib.location_field", # Location fields
270
- "unfold.contrib.constance", # Constance integration
271
- ]
@@ -1,29 +0,0 @@
1
- """
2
- Django CFG Unfold Module
3
-
4
- Complete Unfold admin interface integration with system monitoring,
5
- dashboard callbacks, and auto-configuration.
6
- """
7
-
8
- from .system_monitor import SystemMonitor
9
- from .dashboard import DashboardManager
10
- from .callbacks import UnfoldCallbacks
11
- from .models import DashboardData, StatCard, SystemHealthItem, QuickAction
12
-
13
- # Export instances for easy import
14
- system_monitor = SystemMonitor()
15
- dashboard_manager = DashboardManager()
16
- unfold_callbacks = UnfoldCallbacks()
17
-
18
- __all__ = [
19
- "SystemMonitor",
20
- "DashboardManager",
21
- "UnfoldCallbacks",
22
- "DashboardData",
23
- "StatCard",
24
- "SystemHealthItem",
25
- "QuickAction",
26
- "system_monitor",
27
- "dashboard_manager",
28
- "unfold_callbacks",
29
- ]
@@ -1,318 +0,0 @@
1
- """
2
- Dashboard Manager for Django CFG Unfold
3
-
4
- Manages dashboard configuration, widgets, and navigation
5
- based on the working configuration from the old version.
6
- """
7
-
8
- from typing import List, Dict, Any, Optional
9
- from django.templatetags.static import static
10
- from django.urls import reverse_lazy
11
- from ..base import BaseModule
12
-
13
-
14
- class DashboardManager(BaseModule):
15
- """
16
- Dashboard configuration manager for Unfold.
17
-
18
- Based on the working configuration from @old/api__old/api/dashboard/unfold_config.py
19
- """
20
-
21
- def __init__(self):
22
- """Initialize dashboard manager."""
23
- super().__init__()
24
- self.config = self.get_config()
25
-
26
- def get_navigation_config(self) -> List[Dict[str, Any]]:
27
- """Get complete default navigation configuration for Unfold sidebar."""
28
- navigation = [
29
- {
30
- "title": "Dashboard",
31
- "separator": True,
32
- "collapsible": True,
33
- "items": [
34
- {
35
- "title": "Overview",
36
- "icon": "dashboard",
37
- "link": "/admin/",
38
- },
39
- {
40
- "title": "Settings",
41
- "icon": "settings",
42
- "link": '/admin/constance/config/',
43
- },
44
- {
45
- "title": "Health Check",
46
- "icon": "health_and_safety",
47
- "link": "/cfg/health/",
48
- },
49
- ],
50
- },
51
- ]
52
-
53
- # Add Accounts section if enabled
54
- if self.is_accounts_enabled():
55
- navigation.append({
56
- "title": "Users & Access",
57
- "separator": True,
58
- "collapsible": True,
59
- "items": [
60
- {
61
- "title": "Users",
62
- "icon": "people",
63
- "link": "/admin/django_cfg_accounts/customuser/",
64
- },
65
-
66
- {
67
- "title": "User Groups",
68
- "icon": "group",
69
- "link": "/admin/auth/group/",
70
- },
71
- {
72
- "title": "Registration Sources",
73
- "icon": "link",
74
- "link": "/admin/django_cfg_accounts/registrationsource/",
75
- },
76
- {
77
- "title": "User Registration Sources",
78
- "icon": "person",
79
- "link": "/admin/django_cfg_accounts/userregistrationsource/",
80
- },
81
- ]
82
- })
83
-
84
- # Add Support section if enabled
85
- if self.is_support_enabled():
86
- navigation.append({
87
- "title": "Support",
88
- "separator": True,
89
- "collapsible": True,
90
- "items": [
91
- {
92
- "title": "Tickets",
93
- "icon": "support_agent",
94
- "link": "/admin/django_cfg_support/ticket/",
95
- },
96
- {
97
- "title": "Messages",
98
- "icon": "chat",
99
- "link": "/admin/django_cfg_support/message/",
100
- },
101
- ]
102
- })
103
-
104
- # Add Newsletter section if enabled
105
- if self.is_newsletter_enabled():
106
- navigation.append({
107
- "title": "Newsletter",
108
- "separator": True,
109
- "collapsible": True,
110
- "items": [
111
- {
112
- "title": "Newsletters",
113
- "icon": "email",
114
- "link": "/admin/django_cfg_newsletter/newsletter/",
115
- },
116
- {
117
- "title": "Subscriptions",
118
- "icon": "person_add",
119
- "link": "/admin/django_cfg_newsletter/newslettersubscription/",
120
- },
121
- {
122
- "title": "Campaigns",
123
- "icon": "campaign",
124
- "link": "/admin/django_cfg_newsletter/newslettercampaign/",
125
- },
126
- {
127
- "title": "Email Logs",
128
- "icon": "mail_outline",
129
- "link": "/admin/django_cfg_newsletter/emaillog/",
130
- },
131
- ]
132
- })
133
-
134
- # Add Leads section if enabled
135
- if self.is_leads_enabled():
136
- navigation.append({
137
- "title": "Leads",
138
- "separator": True,
139
- "collapsible": True,
140
- "items": [
141
- {
142
- "title": "Leads",
143
- "icon": "contact_page",
144
- "link": "/admin/django_cfg_leads/lead/",
145
- },
146
- ]
147
- })
148
-
149
- # Add Dramatiq section if enabled
150
- if self.is_tasks_enabled():
151
- navigation.append({
152
- "title": "Background Tasks",
153
- "separator": True,
154
- "collapsible": True,
155
- "items": [
156
- {
157
- "title": "Queue Dashboard",
158
- "icon": "dashboard",
159
- "link": "/cfg/tasks/dashboard/",
160
- "description": "Interactive queue management and monitoring",
161
- },
162
- {
163
- "title": "Task History",
164
- "icon": "history",
165
- "link": "/admin/django_dramatiq/task/",
166
- "description": "View task execution history and details",
167
- },
168
- ]
169
- })
170
-
171
- return navigation
172
-
173
- def _get_reverse_lazy(self, link: str) -> str:
174
- """Safe reverse with fallback."""
175
- try:
176
- from django.urls import reverse
177
- return reverse(link)
178
- except Exception:
179
- return link
180
-
181
-
182
- def _get_user_admin_url(self) -> str:
183
- """Get admin changelist URL for the current AUTH_USER_MODEL."""
184
- try:
185
- from django.contrib.auth import get_user_model
186
- User = get_user_model()
187
- app_label = User._meta.app_label
188
- model_name = User._meta.model_name
189
- # Return string URL, not reverse_lazy object
190
- return f'/admin/{app_label}/{model_name}/'
191
- except Exception:
192
- # Universal fallback - return admin index instead of hardcoded model
193
- return '/admin/'
194
-
195
- def get_unfold_config(self) -> Dict[str, Any]:
196
- """Get complete Unfold configuration based on working old version."""
197
- return {
198
- # Site branding and appearance
199
- "SITE_TITLE": "Admin",
200
- "SITE_HEADER": "Admin",
201
- "SITE_SUBHEADER": "",
202
- "SITE_URL": "/",
203
- "SITE_SYMBOL": "dashboard",
204
-
205
- # UI visibility controls
206
- "SHOW_HISTORY": True,
207
- "SHOW_VIEW_ON_SITE": True,
208
- "SHOW_BACK_BUTTON": False,
209
-
210
- # Dashboard callback
211
- "DASHBOARD_CALLBACK": "api.dashboard.callbacks.main_dashboard_callback",
212
-
213
- # Theme configuration
214
- "THEME": None, # Auto-detect or force "dark"/"light"
215
-
216
- # Login page customization
217
- "LOGIN": {
218
- "redirect_after": lambda request: "/admin/",
219
- },
220
-
221
- # Design system
222
- "BORDER_RADIUS": "8px",
223
- "COLORS": {
224
- "base": {
225
- "50": "249, 250, 251",
226
- "100": "243, 244, 246",
227
- "200": "229, 231, 235",
228
- "300": "209, 213, 219",
229
- "400": "156, 163, 175",
230
- "500": "107, 114, 128",
231
- "600": "75, 85, 99",
232
- "700": "55, 65, 81",
233
- "800": "31, 41, 55",
234
- "900": "17, 24, 39",
235
- "950": "3, 7, 18",
236
- },
237
- "primary": {
238
- "50": "239, 246, 255",
239
- "100": "219, 234, 254",
240
- "200": "191, 219, 254",
241
- "300": "147, 197, 253",
242
- "400": "96, 165, 250",
243
- "500": "59, 130, 246",
244
- "600": "37, 99, 235",
245
- "700": "29, 78, 216",
246
- "800": "30, 64, 175",
247
- "900": "30, 58, 138",
248
- "950": "23, 37, 84",
249
- },
250
- "font": {
251
- "subtle-light": "var(--color-base-500)",
252
- "subtle-dark": "var(--color-base-400)",
253
- "default-light": "var(--color-base-600)",
254
- "default-dark": "var(--color-base-300)",
255
- "important-light": "var(--color-base-900)",
256
- "important-dark": "var(--color-base-100)",
257
- },
258
- },
259
-
260
- # Sidebar navigation - KEY STRUCTURE!
261
- "SIDEBAR": {
262
- "show_search": True,
263
- "command_search": True,
264
- "show_all_applications": True,
265
- "navigation": self.get_navigation_config(),
266
- },
267
-
268
- # Site dropdown menu - moved to top level
269
- "SITE_DROPDOWN": [
270
- # {
271
- # "icon": "language",
272
- # "title": "Documentation",
273
- # "link": "https://docs.carapis.com",
274
- # },
275
- ],
276
-
277
- # Command interface
278
- "COMMAND": {
279
- "search_models": True,
280
- "show_history": True,
281
- },
282
-
283
- # Multi-language support - DISABLED
284
- "SHOW_LANGUAGES": False,
285
- }
286
-
287
- def get_widgets_config(self) -> List[Dict[str, Any]]:
288
- """Get dashboard widgets configuration."""
289
- return [
290
- {
291
- "type": "stats_cards",
292
- "title": "System Overview",
293
- "cards": [
294
- {
295
- "title": "CPU Usage",
296
- "value_template": "{{ cpu_percent }}%",
297
- "icon": "memory",
298
- "color": "blue",
299
- },
300
- {
301
- "title": "Memory Usage",
302
- "value_template": "{{ memory_percent }}%",
303
- "icon": "storage",
304
- "color": "green",
305
- },
306
- {
307
- "title": "Disk Usage",
308
- "value_template": "{{ disk_percent }}%",
309
- "icon": "folder",
310
- "color": "orange",
311
- },
312
- ]
313
- },
314
- ]
315
-
316
-
317
- # Create global instance for easy import
318
- dashboard_manager = DashboardManager()