django-cfg 1.4.88__py3-none-any.whl → 1.4.89__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.

Potentially problematic release.


This version of django-cfg might be problematic. Click here for more details.

Files changed (146) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/centrifugo/views/__init__.py +0 -2
  3. django_cfg/apps/dashboard/services/__init__.py +2 -0
  4. django_cfg/apps/dashboard/services/overview_service.py +205 -0
  5. django_cfg/apps/frontend/test_routing.py +134 -0
  6. django_cfg/apps/frontend/views.py +69 -28
  7. django_cfg/apps/urls.py +0 -1
  8. django_cfg/core/builders/apps_builder.py +0 -58
  9. django_cfg/modules/django_unfold/__init__.py +5 -24
  10. django_cfg/modules/django_unfold/models/__init__.py +0 -23
  11. django_cfg/modules/django_unfold/models/config.py +11 -65
  12. django_cfg/modules/django_unfold/{dashboard.py → navigation.py} +21 -152
  13. django_cfg/modules/django_unfold/tailwind.py +2 -4
  14. django_cfg/pyproject.toml +1 -1
  15. django_cfg/registry/third_party.py +0 -9
  16. django_cfg/routing/callbacks.py +1 -43
  17. django_cfg/static/frontend/admin/404/index.html +1 -1
  18. django_cfg/static/frontend/admin/404.html +1 -1
  19. django_cfg/static/frontend/admin/500/index.html +1 -1
  20. django_cfg/static/frontend/admin/_next/static/{D_d9HRw5Yn7BRHAX5q89_ → 0sN9ktsgXH48ygtGSrhfu}/_buildManifest.js +1 -1
  21. django_cfg/static/frontend/admin/_next/static/chunks/50314-9443faa6df24aebf.js +1 -0
  22. django_cfg/static/frontend/admin/_next/static/chunks/pages/{_app-1c0fff0f59a6d683.js → _app-c7dcd3aa616fab68.js} +1 -1
  23. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/{centrifugo-44a8313fa040e9ad.js → centrifugo-f9ecbc3ae0052a03.js} +1 -1
  24. django_cfg/static/frontend/admin/auth/index.html +1 -1
  25. django_cfg/static/frontend/admin/index.html +1 -1
  26. django_cfg/static/frontend/admin/legal/cookies/index.html +1 -1
  27. django_cfg/static/frontend/admin/legal/privacy/index.html +1 -1
  28. django_cfg/static/frontend/admin/legal/security/index.html +1 -1
  29. django_cfg/static/frontend/admin/legal/terms/index.html +1 -1
  30. django_cfg/static/frontend/admin/private/centrifugo/index.html +1 -1
  31. django_cfg/static/frontend/admin/private/index.html +1 -1
  32. django_cfg/static/frontend/admin/private/profile/index.html +1 -1
  33. django_cfg/static/frontend/admin/private/ui/index.html +2 -2
  34. {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/METADATA +1 -1
  35. {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/RECORD +39 -143
  36. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/css/dashboard.css +0 -260
  37. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_channels.mjs +0 -313
  38. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_testing.mjs +0 -803
  39. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/main.mjs +0 -341
  40. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/overview.mjs +0 -432
  41. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/testing.mjs +0 -33
  42. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/websocket.mjs +0 -210
  43. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/channels_content.html +0 -46
  44. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/live_channels_content.html +0 -123
  45. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/overview_content.html +0 -45
  46. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/publishes_content.html +0 -84
  47. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/stat_cards.html +0 -53
  48. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/system_status.html +0 -91
  49. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/tab_navigation.html +0 -29
  50. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/testing_tools.html +0 -415
  51. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/layout/base.html +0 -61
  52. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/pages/dashboard.html +0 -58
  53. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/tags/connection_script.html +0 -48
  54. django_cfg/apps/centrifugo/templatetags/__init__.py +0 -1
  55. django_cfg/apps/centrifugo/templatetags/centrifugo_tags.py +0 -81
  56. django_cfg/apps/centrifugo/urls_admin.py +0 -20
  57. django_cfg/apps/centrifugo/views/dashboard.py +0 -28
  58. django_cfg/modules/django_dashboard/__init__.py +0 -23
  59. django_cfg/modules/django_dashboard/components.py +0 -312
  60. django_cfg/modules/django_dashboard/debug.py +0 -174
  61. django_cfg/modules/django_dashboard/management/__init__.py +0 -0
  62. django_cfg/modules/django_dashboard/management/commands/__init__.py +0 -0
  63. django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +0 -109
  64. django_cfg/modules/django_dashboard/sections/__init__.py +0 -1
  65. django_cfg/modules/django_dashboard/sections/base.py +0 -129
  66. django_cfg/modules/django_dashboard/sections/commands.py +0 -33
  67. django_cfg/modules/django_dashboard/sections/documentation.py +0 -393
  68. django_cfg/modules/django_dashboard/sections/overview.py +0 -398
  69. django_cfg/modules/django_dashboard/sections/stats.py +0 -48
  70. django_cfg/modules/django_dashboard/sections/system.py +0 -74
  71. django_cfg/modules/django_dashboard/sections/widgets.py +0 -222
  72. django_cfg/modules/django_unfold/callbacks/__init__.py +0 -9
  73. django_cfg/modules/django_unfold/callbacks/actions.py +0 -51
  74. django_cfg/modules/django_unfold/callbacks/apizones.py +0 -122
  75. django_cfg/modules/django_unfold/callbacks/base.py +0 -290
  76. django_cfg/modules/django_unfold/callbacks/charts.py +0 -223
  77. django_cfg/modules/django_unfold/callbacks/commands.py +0 -40
  78. django_cfg/modules/django_unfold/callbacks/main.py +0 -322
  79. django_cfg/modules/django_unfold/callbacks/statistics.py +0 -240
  80. django_cfg/modules/django_unfold/callbacks/system.py +0 -180
  81. django_cfg/modules/django_unfold/callbacks/users.py +0 -65
  82. django_cfg/modules/django_unfold/models/dashboard.py +0 -207
  83. django_cfg/modules/django_unfold/models/tabs.py +0 -26
  84. django_cfg/modules/django_unfold/models.py +0 -98
  85. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +0 -102
  86. django_cfg/static/frontend/admin/_next/static/chunks/50314-5ec79b293c2283dd.js +0 -1
  87. django_cfg/templates/admin/sections/commands_section.html +0 -5
  88. django_cfg/templates/admin/sections/documentation_section.html +0 -5
  89. django_cfg/templates/admin/sections/overview_section.html +0 -5
  90. django_cfg/templates/admin/sections/stats_section.html +0 -5
  91. django_cfg/templates/admin/sections/system_section.html +0 -5
  92. django_cfg/templates/admin/sections/widgets_section.html +0 -11
  93. django_cfg/templates/admin_old/components/action_grid.html +0 -49
  94. django_cfg/templates/admin_old/components/card.html +0 -50
  95. django_cfg/templates/admin_old/components/data_table.html +0 -67
  96. django_cfg/templates/admin_old/components/metric_card.html +0 -39
  97. django_cfg/templates/admin_old/components/modal.html +0 -58
  98. django_cfg/templates/admin_old/components/progress_bar.html +0 -20
  99. django_cfg/templates/admin_old/components/section_header.html +0 -26
  100. django_cfg/templates/admin_old/components/stat_item.html +0 -32
  101. django_cfg/templates/admin_old/components/stats_grid.html +0 -72
  102. django_cfg/templates/admin_old/components/status_badge.html +0 -28
  103. django_cfg/templates/admin_old/components/user_avatar.html +0 -27
  104. django_cfg/templates/admin_old/constance/change_list.html +0 -74
  105. django_cfg/templates/admin_old/constance/includes/default_value.html +0 -24
  106. django_cfg/templates/admin_old/constance/includes/fieldset_header.html +0 -15
  107. django_cfg/templates/admin_old/constance/includes/results_list.html +0 -16
  108. django_cfg/templates/admin_old/constance/includes/setting_row.html +0 -50
  109. django_cfg/templates/admin_old/constance/includes/table_headers.html +0 -10
  110. django_cfg/templates/admin_old/examples/component_class_example.html +0 -156
  111. django_cfg/templates/admin_old/import_export/change_list_export.html +0 -24
  112. django_cfg/templates/admin_old/import_export/change_list_import.html +0 -24
  113. django_cfg/templates/admin_old/import_export/change_list_import_export.html +0 -34
  114. django_cfg/templates/admin_old/index.html +0 -80
  115. django_cfg/templates/admin_old/index_new.html +0 -119
  116. django_cfg/templates/admin_old/layouts/base_dashboard.html +0 -62
  117. django_cfg/templates/admin_old/layouts/dashboard_with_tabs.html +0 -176
  118. django_cfg/templates/admin_old/sections/commands_section.html +0 -549
  119. django_cfg/templates/admin_old/sections/documentation_section.html +0 -152
  120. django_cfg/templates/admin_old/sections/overview_section.html +0 -112
  121. django_cfg/templates/admin_old/sections/stats_section.html +0 -35
  122. django_cfg/templates/admin_old/sections/system_section.html +0 -99
  123. django_cfg/templates/admin_old/sections/widgets_section.html +0 -129
  124. django_cfg/templates/admin_old/snippets/components/activity_tracker.html +0 -70
  125. django_cfg/templates/admin_old/snippets/components/charts_section.html +0 -113
  126. django_cfg/templates/admin_old/snippets/components/django_commands.html +0 -270
  127. django_cfg/templates/admin_old/snippets/components/quick_actions.html +0 -66
  128. django_cfg/templates/admin_old/snippets/components/recent_activity_improved.html +0 -25
  129. django_cfg/templates/admin_old/snippets/components/recent_users_table.html +0 -102
  130. django_cfg/templates/admin_old/snippets/components/stats_cards.html +0 -4
  131. django_cfg/templates/admin_old/snippets/components/stats_tiles.html +0 -92
  132. django_cfg/templates/admin_old/snippets/components/system_health.html +0 -22
  133. django_cfg/templates/admin_old/snippets/components/system_metrics.html +0 -199
  134. django_cfg/templates/admin_old/snippets/components/user_permissions.html +0 -57
  135. django_cfg/templates/admin_old/snippets/tabs/app_stats_tab.html +0 -201
  136. django_cfg/templates/admin_old/snippets/tabs/commands_tab.html +0 -114
  137. django_cfg/templates/admin_old/snippets/tabs/documentation_tab.html +0 -42
  138. django_cfg/templates/admin_old/snippets/tabs/overview_tab.html +0 -116
  139. django_cfg/templates/admin_old/snippets/tabs/stats_tab.html +0 -89
  140. django_cfg/templates/admin_old/snippets/tabs/users_tab.html +0 -51
  141. django_cfg/templates/admin_old/snippets/tabs/widgets_tab.html +0 -38
  142. django_cfg/templates/admin_old/snippets/zones/zones_table.html +0 -176
  143. /django_cfg/static/frontend/admin/_next/static/{D_d9HRw5Yn7BRHAX5q89_ → 0sN9ktsgXH48ygtGSrhfu}/_ssgManifest.js +0 -0
  144. {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/WHEEL +0 -0
  145. {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/entry_points.txt +0 -0
  146. {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/licenses/LICENSE +0 -0
@@ -1,398 +0,0 @@
1
- """Overview section for dashboard."""
2
-
3
- from typing import Any, Dict, List
4
-
5
- from .base import DataSection
6
-
7
-
8
- class OverviewSection(DataSection):
9
- """
10
- Overview section showing key metrics and system status.
11
- """
12
-
13
- template_name = "admin/sections/overview_section.html"
14
- title = "System Overview"
15
- icon = "dashboard"
16
-
17
- def get_data(self) -> Dict[str, Any]:
18
- """Get overview data."""
19
- from django_cfg.core.config import get_current_config
20
-
21
- config = get_current_config()
22
-
23
- return {
24
- 'stats': self.get_key_stats(),
25
- 'system_health': self.get_system_health(),
26
- 'recent_activity': self.get_recent_activity(),
27
- }
28
-
29
- def get_context_data(self, **kwargs) -> Dict[str, Any]:
30
- """Add additional context for includes."""
31
- import json
32
-
33
- from django.utils.safestring import mark_safe
34
-
35
- context = super().get_context_data(**kwargs)
36
-
37
- # Get time range from kwargs (default: 7 days)
38
- time_range = kwargs.get('time_range', 7)
39
-
40
- # Add data needed by included components
41
- context['system_metrics'] = self.get_system_metrics()
42
- context['recent_users'] = self.get_recent_users()
43
- context['recent_users_table'] = self.get_recent_users_table()
44
-
45
- # Convert activity tracker to JSON for JavaScript
46
- activity_data = self.get_activity_tracker()
47
- context['activity_tracker'] = mark_safe(json.dumps(activity_data))
48
-
49
- context['charts'] = self.get_charts_data(days=time_range)
50
-
51
- # Quick actions come from kwargs (passed from callbacks)
52
- if 'quick_actions' in kwargs:
53
- context['quick_actions'] = kwargs['quick_actions']
54
-
55
- # Navigation for time range filter
56
- if 'navigation' in kwargs:
57
- context['navigation'] = kwargs['navigation']
58
-
59
- return context
60
-
61
- def get_key_stats(self) -> Dict[str, Any]:
62
- """Get key statistics."""
63
- from django.contrib.auth import get_user_model
64
- from django.db import connection
65
-
66
- User = get_user_model()
67
-
68
- # Get database count
69
- db_count = len(connection.settings_dict.get('DATABASES', {})) if hasattr(connection, 'settings_dict') else 1
70
-
71
- # Get app count
72
- from django.apps import apps
73
- app_count = len(apps.get_app_configs())
74
-
75
- return {
76
- 'users': User.objects.count(),
77
- 'databases': db_count,
78
- 'apps': app_count,
79
- }
80
-
81
- def get_system_health(self) -> Dict[str, Any]:
82
- """Get system health metrics."""
83
- import sys
84
-
85
- import psutil
86
-
87
- return {
88
- 'python_version': f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
89
- 'cpu_percent': psutil.cpu_percent(interval=0.1),
90
- 'memory_percent': psutil.virtual_memory().percent,
91
- 'disk_percent': psutil.disk_usage('/').percent,
92
- }
93
-
94
- def get_recent_activity(self) -> list:
95
- """Get recent activity items."""
96
- # TODO: Implement activity tracking
97
- return []
98
-
99
- def get_system_metrics(self) -> Dict[str, Any]:
100
- """Get system metrics for progress bars."""
101
- from django.core.cache import cache
102
- from django.db import connection
103
-
104
- metrics = {}
105
-
106
- # Database metrics
107
- try:
108
- with connection.cursor() as cursor:
109
- cursor.execute("SELECT 1")
110
- metrics["database"] = {
111
- "status": "healthy",
112
- "type": connection.settings_dict.get('ENGINE', 'Unknown').split('.')[-1],
113
- "health_percentage": 95,
114
- "description": "Connection successful",
115
- }
116
- except Exception as e:
117
- metrics["database"] = {
118
- "status": "error",
119
- "type": "Database",
120
- "health_percentage": 0,
121
- "description": f"Connection failed: {str(e)[:50]}",
122
- }
123
-
124
- # Cache metrics
125
- try:
126
- cache.set("health_check", "ok", 10)
127
- cache_result = cache.get("health_check")
128
- if cache_result == "ok":
129
- metrics["cache"] = {
130
- "status": "healthy",
131
- "type": "Memory Cache",
132
- "health_percentage": 90,
133
- "description": "Cache working properly",
134
- }
135
- else:
136
- metrics["cache"] = {
137
- "status": "warning",
138
- "type": "Memory Cache",
139
- "health_percentage": 50,
140
- "description": "Cache response delayed",
141
- }
142
- except Exception as e:
143
- metrics["cache"] = {
144
- "status": "error",
145
- "type": "Memory Cache",
146
- "health_percentage": 0,
147
- "description": f"Cache error: {str(e)[:50]}",
148
- }
149
-
150
- # Storage metrics
151
- try:
152
- import shutil
153
- total, used, free = shutil.disk_usage("/")
154
- usage_percentage = (used / total) * 100
155
- free_percentage = 100 - usage_percentage
156
-
157
- # Status based on free space
158
- if free_percentage > 20:
159
- status = "healthy"
160
- elif free_percentage > 10:
161
- status = "warning"
162
- else:
163
- status = "error"
164
-
165
- metrics["storage"] = {
166
- "status": status,
167
- "type": "Disk Space",
168
- "health_percentage": int(free_percentage), # Show free space percentage
169
- "description": f"{free_percentage:.1f}% free ({usage_percentage:.1f}% used)",
170
- }
171
- except Exception as e:
172
- metrics["storage"] = {
173
- "status": "error",
174
- "type": "Disk Space",
175
- "health_percentage": 0,
176
- "description": f"Check failed: {str(e)[:50]}",
177
- }
178
-
179
- # API metrics
180
- try:
181
- from django.urls import get_resolver
182
- resolver = get_resolver()
183
- url_patterns = list(resolver.url_patterns)
184
-
185
- metrics["api"] = {
186
- "status": "healthy",
187
- "type": "REST API",
188
- "health_percentage": 100,
189
- "description": f"{len(url_patterns)} URL patterns",
190
- }
191
- except Exception:
192
- metrics["api"] = {
193
- "status": "warning",
194
- "type": "REST API",
195
- "health_percentage": 50,
196
- "description": "Unable to count URLs",
197
- }
198
-
199
- return metrics
200
-
201
- def get_recent_users(self) -> List[Dict[str, Any]]:
202
- """Get recent users for activity section."""
203
- from django.contrib.auth import get_user_model
204
-
205
- User = get_user_model()
206
-
207
- try:
208
- recent_users = User.objects.order_by('-date_joined')[:5]
209
- return list(recent_users.values(
210
- 'id', 'username', 'email', 'is_active', 'date_joined'
211
- ))
212
- except Exception:
213
- return []
214
-
215
- def get_recent_users_table(self) -> Dict[str, Any]:
216
- """Get recent users in table format for Unfold table component."""
217
- from django.contrib.auth import get_user_model
218
-
219
- User = get_user_model()
220
-
221
- try:
222
- recent_users = User.objects.order_by('-date_joined')[:10]
223
-
224
- return {
225
- "headers": ["Username", "Email", "Status", "Staff", "Joined"],
226
- "rows": [
227
- [
228
- user.username,
229
- user.email,
230
- "✅ Active" if user.is_active else "❌ Inactive",
231
- "🛡️ Yes" if user.is_staff else "—",
232
- user.date_joined.strftime('%Y-%m-%d %H:%M')
233
- ]
234
- for user in recent_users
235
- ]
236
- }
237
- except Exception:
238
- return {"headers": [], "rows": []}
239
-
240
- def get_activity_tracker(self) -> List[Dict[str, Any]]:
241
- """
242
- Get activity tracker data for GitHub-style heatmap.
243
-
244
- Returns list of dicts with date and count for last 365 days.
245
- """
246
- from datetime import timedelta
247
-
248
- from django.contrib.auth import get_user_model
249
- from django.utils import timezone
250
-
251
- User = get_user_model()
252
-
253
- try:
254
- # Get activity for last 365 days
255
- today = timezone.now().date()
256
- activity_data = []
257
-
258
- for days_ago in range(364, -1, -1): # 365 days, newest last
259
- date = today - timedelta(days=days_ago)
260
-
261
- # Count user registrations on this day
262
- registrations = User.objects.filter(
263
- date_joined__date=date
264
- ).count()
265
-
266
- # Count logins on this day (if last_login exists)
267
- logins = 0
268
- if hasattr(User, 'last_login'):
269
- logins = User.objects.filter(
270
- last_login__date=date
271
- ).count()
272
-
273
- # Total activity for the day
274
- total_activity = registrations + logins
275
-
276
- activity_data.append({
277
- 'date': date.isoformat(),
278
- 'count': total_activity,
279
- 'level': self._get_activity_level(total_activity),
280
- })
281
-
282
- return activity_data
283
-
284
- except Exception:
285
- # Return empty on error
286
- return []
287
-
288
- def _get_activity_level(self, count: int) -> int:
289
- """
290
- Convert activity count to level (0-4) for heatmap colors.
291
-
292
- 0 = no activity (gray)
293
- 1 = low (light green)
294
- 2 = medium (green)
295
- 3 = high (dark green)
296
- 4 = very high (darkest green)
297
- """
298
- if count == 0:
299
- return 0
300
- elif count <= 2:
301
- return 1
302
- elif count <= 5:
303
- return 2
304
- elif count <= 10:
305
- return 3
306
- else:
307
- return 4
308
-
309
- def get_charts_data(self, days: int = 7) -> Dict[str, Any]:
310
- """Get charts data for Analytics Overview.
311
-
312
- Args:
313
- days: Number of days to include in charts (default: 7)
314
- """
315
- import json
316
- from datetime import datetime, timedelta
317
-
318
- from django.contrib.auth import get_user_model
319
- from django.utils import timezone
320
-
321
- User = get_user_model()
322
-
323
- try:
324
- # Get last N days of user registrations
325
- today = timezone.now().date()
326
- dates = [(today - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days-1, -1, -1)]
327
-
328
- # Count users registered each day
329
- registrations = []
330
- for date_str in dates:
331
- date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
332
- count = User.objects.filter(
333
- date_joined__date=date_obj
334
- ).count()
335
- registrations.append(count)
336
-
337
- # Count active users each day (last login)
338
- activity = []
339
- for date_str in dates:
340
- date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
341
- # Count users who logged in that day
342
- count = User.objects.filter(
343
- last_login__date=date_obj
344
- ).count() if hasattr(User, 'last_login') else 0
345
- activity.append(count)
346
-
347
- # Format for charts
348
- day_labels = [d.split('-')[2] for d in dates] # Just day numbers
349
-
350
- # Prepare chart data structures
351
- user_reg_data = {
352
- 'labels': day_labels,
353
- 'datasets': [{
354
- 'label': 'New Users',
355
- 'data': registrations,
356
- 'backgroundColor': 'rgba(59, 130, 246, 0.5)',
357
- 'borderColor': 'rgb(59, 130, 246)',
358
- 'borderWidth': 2,
359
- }]
360
- }
361
-
362
- user_activity_data = {
363
- 'labels': day_labels,
364
- 'datasets': [{
365
- 'label': 'Active Users',
366
- 'data': activity,
367
- 'backgroundColor': 'rgba(34, 197, 94, 0.5)',
368
- 'borderColor': 'rgb(34, 197, 94)',
369
- 'borderWidth': 2,
370
- }]
371
- }
372
-
373
- return {
374
- # User Registrations chart
375
- 'user_registrations': {
376
- 'labels': day_labels,
377
- 'datasets': [{
378
- 'label': 'New Users',
379
- 'data': registrations,
380
- }]
381
- },
382
- # JSON string for Unfold chart component (NO mark_safe - let Django escape quotes)
383
- 'user_registrations_json': json.dumps(user_reg_data),
384
-
385
- # User Activity chart
386
- 'user_activity': {
387
- 'labels': day_labels,
388
- 'datasets': [{
389
- 'label': 'Active Users',
390
- 'data': activity,
391
- }]
392
- },
393
- # JSON string for Unfold chart component (NO mark_safe - let Django escape quotes)
394
- 'user_activity_json': json.dumps(user_activity_data),
395
- }
396
- except Exception:
397
- # Return empty chart data
398
- return {}
@@ -1,48 +0,0 @@
1
- """Statistics section for dashboard."""
2
-
3
- from typing import Any, Dict, List
4
-
5
- from .base import DataSection
6
-
7
-
8
- class StatsSection(DataSection):
9
- """
10
- Statistics section showing detailed metrics.
11
- """
12
-
13
- template_name = "admin/sections/stats_section.html"
14
- title = "Statistics"
15
- icon = "analytics"
16
-
17
- def get_data(self) -> Dict[str, Any]:
18
- """Get statistics data."""
19
- return {
20
- 'app_stats': self.get_app_stats(),
21
- 'time_series': self.get_time_series(),
22
- }
23
-
24
- def get_app_stats(self) -> List[Dict[str, Any]]:
25
- """Get per-app statistics."""
26
- from django.apps import apps
27
-
28
- stats = []
29
-
30
- for app_config in apps.get_app_configs():
31
- if app_config.name.startswith('django.'):
32
- continue
33
-
34
- # Count models in app
35
- models = [m for m in apps.get_models() if m._meta.app_label == app_config.label]
36
-
37
- stats.append({
38
- 'name': app_config.verbose_name,
39
- 'label': app_config.label,
40
- 'models_count': len(models),
41
- })
42
-
43
- return stats
44
-
45
- def get_time_series(self) -> Dict[str, Any]:
46
- """Get time series data for charts."""
47
- # TODO: Implement time series data
48
- return {}
@@ -1,74 +0,0 @@
1
- """System section for dashboard."""
2
-
3
- from typing import Any, Dict
4
-
5
- from .base import DataSection
6
-
7
-
8
- class SystemSection(DataSection):
9
- """
10
- System management section.
11
- """
12
-
13
- template_name = "admin/sections/system_section.html"
14
- title = "System Management"
15
- icon = "settings"
16
-
17
- def get_data(self) -> Dict[str, Any]:
18
- """Get system data."""
19
- return {
20
- 'health': self.get_health_check(),
21
- 'services': self.get_services_status(),
22
- 'configuration': self.get_configuration(),
23
- }
24
-
25
- def get_health_check(self) -> Dict[str, Any]:
26
- """Get health check status."""
27
- import psutil
28
-
29
- return {
30
- 'status': 'healthy',
31
- 'checks': {
32
- 'database': self.check_database(),
33
- 'cache': self.check_cache(),
34
- 'disk_space': psutil.disk_usage('/').percent < 90,
35
- 'memory': psutil.virtual_memory().percent < 90,
36
- }
37
- }
38
-
39
- def check_database(self) -> bool:
40
- """Check database connectivity."""
41
- from django.db import connection
42
-
43
- try:
44
- connection.ensure_connection()
45
- return True
46
- except Exception:
47
- return False
48
-
49
- def check_cache(self) -> bool:
50
- """Check cache availability."""
51
- from django.core.cache import cache
52
-
53
- try:
54
- cache.set('health_check', True, 1)
55
- return cache.get('health_check') is True
56
- except Exception:
57
- return False
58
-
59
- def get_services_status(self) -> Dict[str, Any]:
60
- """Get services status."""
61
- # TODO: Implement services status check
62
- return {}
63
-
64
- def get_configuration(self) -> Dict[str, Any]:
65
- """Get system configuration."""
66
- from django_cfg.core.config import get_current_config
67
-
68
- config = get_current_config()
69
-
70
- return {
71
- 'debug': config.debug,
72
- 'env_mode': config.env_mode,
73
- 'project_name': config.project_name,
74
- }