django-cfg 1.4.83__py3-none-any.whl → 1.4.85__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 (169) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/dashboard/__init__.py +8 -0
  3. django_cfg/apps/dashboard/apps.py +23 -0
  4. django_cfg/apps/dashboard/serializers/__init__.py +55 -0
  5. django_cfg/apps/dashboard/serializers/activity.py +38 -0
  6. django_cfg/apps/dashboard/serializers/apizones.py +26 -0
  7. django_cfg/apps/dashboard/serializers/base.py +16 -0
  8. django_cfg/apps/dashboard/serializers/charts.py +44 -0
  9. django_cfg/apps/dashboard/serializers/commands.py +26 -0
  10. django_cfg/apps/dashboard/serializers/overview.py +34 -0
  11. django_cfg/apps/dashboard/serializers/statistics.py +46 -0
  12. django_cfg/apps/dashboard/serializers/system.py +58 -0
  13. django_cfg/apps/dashboard/services/__init__.py +20 -0
  14. django_cfg/apps/dashboard/services/apizones_service.py +119 -0
  15. django_cfg/apps/dashboard/services/charts_service.py +266 -0
  16. django_cfg/apps/dashboard/services/commands_service.py +142 -0
  17. django_cfg/apps/dashboard/services/statistics_service.py +393 -0
  18. django_cfg/apps/dashboard/services/system_health_service.py +280 -0
  19. django_cfg/apps/dashboard/urls.py +42 -0
  20. django_cfg/apps/dashboard/views/__init__.py +23 -0
  21. django_cfg/apps/dashboard/views/activity_views.py +83 -0
  22. django_cfg/apps/dashboard/views/apizones_views.py +73 -0
  23. django_cfg/apps/dashboard/views/charts_views.py +159 -0
  24. django_cfg/apps/dashboard/views/commands_views.py +73 -0
  25. django_cfg/apps/dashboard/views/overview_views.py +92 -0
  26. django_cfg/apps/dashboard/views/statistics_views.py +105 -0
  27. django_cfg/apps/dashboard/views/system_views.py +73 -0
  28. django_cfg/apps/frontend/views.py +5 -0
  29. django_cfg/apps/urls.py +2 -1
  30. django_cfg/core/builders/apps_builder.py +1 -0
  31. django_cfg/modules/django_client/core/parser/openapi30.py +12 -5
  32. django_cfg/modules/django_client/core/parser/openapi31.py +12 -5
  33. django_cfg/modules/django_unfold/callbacks/main.py +7 -6
  34. django_cfg/modules/django_unfold/dashboard.py +1 -36
  35. django_cfg/modules/django_unfold/models/config.py +102 -73
  36. django_cfg/modules/django_unfold/tailwind.py +31 -79
  37. django_cfg/pyproject.toml +1 -1
  38. django_cfg/static/frontend/admin/404.html +1 -1
  39. django_cfg/static/frontend/admin/500.html +1 -1
  40. django_cfg/static/frontend/admin/_next/static/BembwiEtlu4eFl3OX7n1k/_buildManifest.js +1 -0
  41. django_cfg/static/frontend/admin/_next/static/chunks/23004-faae121bbfecc163.js +1 -0
  42. django_cfg/static/frontend/admin/_next/static/chunks/{25033.d626f78bc99bc4a1.js → 25033.ee3e206d5a2877b6.js} +2 -2
  43. django_cfg/static/frontend/admin/_next/static/chunks/{25892.964150a58f94ce06.js → 25892.5cbed319f9226fdc.js} +1 -1
  44. django_cfg/static/frontend/admin/_next/static/chunks/{2d7a934f.dfef67639279d59d.js → 2d7a934f.329c61f23af1a7ec.js} +1 -1
  45. django_cfg/static/frontend/admin/_next/static/chunks/{30649.00c679812a56aee3.js → 30649.963cfb7268b5864a.js} +1 -1
  46. django_cfg/static/frontend/admin/_next/static/chunks/{30875.784491146c38dbcb.js → 30875.82c3741757b8aa32.js} +1 -1
  47. django_cfg/static/frontend/admin/_next/static/chunks/{32163.ab0ca435b3f26c04.js → 32163.109a03a7252f1508.js} +1 -1
  48. django_cfg/static/frontend/admin/_next/static/chunks/{49978.fb8ba7ee52ffe666.js → 49978.db5a86a8eb233f35.js} +1 -1
  49. django_cfg/static/frontend/admin/_next/static/chunks/50314-3b9d15242191c8bc.js +1 -0
  50. django_cfg/static/frontend/admin/_next/static/chunks/{50319.f786248384877960.js → 50319.fd78c7f7e3f1966e.js} +1 -1
  51. django_cfg/static/frontend/admin/_next/static/chunks/{52908.b690e323d8f8efdd.js → 52908.da5b850b0bc0970c.js} +1 -1
  52. django_cfg/static/frontend/admin/_next/static/chunks/{53710.80ca863525d137db.js → 53710.7176bbee6c7b78be.js} +1 -1
  53. django_cfg/static/frontend/admin/_next/static/chunks/{57982.251fed8d58adcf53.js → 57982.2c90b33b0934522a.js} +2 -2
  54. django_cfg/static/frontend/admin/_next/static/chunks/{60181.86e18057c4caaa97.js → 60181.c94d78d10eb5da37.js} +1 -1
  55. django_cfg/static/frontend/admin/_next/static/chunks/{60374.bde0ec1249aa79c6.js → 60374.5d80cfc45439b2b0.js} +1 -1
  56. django_cfg/static/frontend/admin/_next/static/chunks/{64330.2ef79bccd7d4e363.js → 64330.41858e98c0e5173b.js} +1 -1
  57. django_cfg/static/frontend/admin/_next/static/chunks/6766.8d01e44e83070e83.js +1 -0
  58. django_cfg/static/frontend/admin/_next/static/chunks/{6884.7b1db804c88280ed.js → 6884.624d563508cf6db4.js} +1 -1
  59. django_cfg/static/frontend/admin/_next/static/chunks/{69436.9515b854cdf4b57a.js → 69436.be44021e3d7c99c7.js} +1 -1
  60. django_cfg/static/frontend/admin/_next/static/chunks/{70628.00cdd98f672e684f.js → 70628.58e8c38a66543d5e.js} +1 -1
  61. django_cfg/static/frontend/admin/_next/static/chunks/{73218.a826c2248612b37f.js → 73218.d712e7bd678e23a8.js} +1 -1
  62. django_cfg/static/frontend/admin/_next/static/chunks/{76334.64fbaa923d9ac293.js → 76334.f43f2d8b4bbf8dd6.js} +1 -1
  63. django_cfg/static/frontend/admin/_next/static/chunks/{7799.2b280f8ddf067d49.js → 7799.1575cc212bc750c7.js} +1 -1
  64. django_cfg/static/frontend/admin/_next/static/chunks/{80574.620a8a5b4eb91c25.js → 80574.92638dd7b9979664.js} +1 -1
  65. django_cfg/static/frontend/admin/_next/static/chunks/{81127.a0603c3394892d4e.js → 81127.3ead500eec887152.js} +1 -1
  66. django_cfg/static/frontend/admin/_next/static/chunks/{8383.eb6188b22c453e14.js → 8383.e25a442df26b2e26.js} +1 -1
  67. django_cfg/static/frontend/admin/_next/static/chunks/{85833.35e6ca25ac32a7d2.js → 85833.b0dead4fbcbfdd1b.js} +1 -1
  68. django_cfg/static/frontend/admin/_next/static/chunks/{95365.fc9d7653a78839d0.js → 95365.2b430045fc2e5acf.js} +1 -1
  69. django_cfg/static/frontend/admin/_next/static/chunks/{96168.eb7fdb721b9cdb00.js → 96168.b7197f890097df6e.js} +1 -1
  70. django_cfg/static/frontend/admin/_next/static/chunks/{96424.0793b94836eb13a6.js → 96424.11d76570e9a94b85.js} +1 -1
  71. django_cfg/static/frontend/admin/_next/static/chunks/pages/{404-c283223d1afd02a2.js → 404-cf71cd7b3cb005e5.js} +1 -1
  72. django_cfg/static/frontend/admin/_next/static/chunks/pages/{500-389d6d3e1f2f7fda.js → 500-ff19c7842e3df415.js} +1 -1
  73. django_cfg/static/frontend/admin/_next/static/chunks/pages/_app-f62e5528fbcbb6b3.js +272 -0
  74. django_cfg/static/frontend/admin/_next/static/chunks/pages/{_error-5291033275c26d09.js → _error-87f3fdc2aa131e77.js} +1 -1
  75. django_cfg/static/frontend/admin/_next/static/chunks/pages/index-69f737d4802cc5b7.js +1 -0
  76. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{cookies-bb5507a122775f30.js → cookies-b39c7f22c066e2c6.js} +1 -1
  77. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{privacy-f8a3d8db1a197be3.js → privacy-5aedad0cf3a4f80f.js} +1 -1
  78. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{security-aba50addd2179f8f.js → security-dbd854d0d5d483e2.js} +1 -1
  79. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{terms-4aa35cd30b5c08ad.js → terms-f3e1d2b9e5edf12f.js} +1 -1
  80. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/centrifugo-f24beb6ed3955aa8.js +1 -0
  81. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/{profile-e93a65e8e7d9022b.js → profile-b8045f993287f1a7.js} +1 -1
  82. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/ui-373fff8b42878e64.js +1 -0
  83. django_cfg/static/frontend/admin/_next/static/chunks/pages/private-fe9faa86ecdb0ce6.js +1 -0
  84. django_cfg/static/frontend/admin/_next/static/chunks/{webpack-905bba30877f6490.js → webpack-7c456a65e96eb97e.js} +1 -1
  85. django_cfg/static/frontend/admin/_next/static/css/5f9a37b6e6a72303.css +3 -0
  86. django_cfg/static/frontend/admin/auth.html +1 -1
  87. django_cfg/static/frontend/admin/index.html +1 -1
  88. django_cfg/static/frontend/admin/legal/cookies.html +1 -1
  89. django_cfg/static/frontend/admin/legal/privacy.html +1 -1
  90. django_cfg/static/frontend/admin/legal/security.html +1 -1
  91. django_cfg/static/frontend/admin/legal/terms.html +1 -1
  92. django_cfg/static/frontend/admin/private/centrifugo.html +1 -1
  93. django_cfg/static/frontend/admin/private/profile.html +1 -1
  94. django_cfg/static/frontend/admin/private/ui.html +1 -0
  95. django_cfg/static/frontend/admin/private.html +1 -1
  96. django_cfg/templates/admin/index.html +328 -62
  97. django_cfg/templates/admin/sections/commands_section.html +5 -549
  98. django_cfg/templates/admin/sections/documentation_section.html +5 -152
  99. django_cfg/templates/admin/sections/overview_section.html +5 -112
  100. django_cfg/templates/admin/sections/stats_section.html +5 -35
  101. django_cfg/templates/admin/sections/system_section.html +5 -99
  102. django_cfg/templates/admin/sections/widgets_section.html +10 -128
  103. django_cfg/templates/admin_old/index.html +80 -0
  104. django_cfg/templates/admin_old/sections/commands_section.html +549 -0
  105. django_cfg/templates/admin_old/sections/documentation_section.html +152 -0
  106. django_cfg/templates/admin_old/sections/overview_section.html +112 -0
  107. django_cfg/templates/admin_old/sections/stats_section.html +35 -0
  108. django_cfg/templates/admin_old/sections/system_section.html +99 -0
  109. django_cfg/templates/admin_old/sections/widgets_section.html +129 -0
  110. django_cfg/templates/unfold/layouts/skeleton.html +27 -0
  111. django_cfg/templatetags/django_cfg.py +53 -0
  112. {django_cfg-1.4.83.dist-info → django_cfg-1.4.85.dist-info}/METADATA +1 -1
  113. {django_cfg-1.4.83.dist-info → django_cfg-1.4.85.dist-info}/RECORD +160 -124
  114. django_cfg/static/frontend/admin/_next/static/chunks/6766.d62fed7cd4761148.js +0 -1
  115. django_cfg/static/frontend/admin/_next/static/chunks/pages/_app-16701a4e1bc3e6ac.js +0 -272
  116. django_cfg/static/frontend/admin/_next/static/chunks/pages/index-88751d9f44a32105.js +0 -1
  117. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/centrifugo-1c5f00c26c77a47b.js +0 -1
  118. django_cfg/static/frontend/admin/_next/static/chunks/pages/private-2f58633ddf63a5bc.js +0 -1
  119. django_cfg/static/frontend/admin/_next/static/chunks/pages/ui-0e6c0e35862789ec.js +0 -1
  120. django_cfg/static/frontend/admin/_next/static/css/806300fb98c42afb.css +0 -3
  121. django_cfg/static/frontend/admin/_next/static/ibMHm1p66p0UGKsKnDWxn/_buildManifest.js +0 -1
  122. django_cfg/static/frontend/admin/ui.html +0 -92
  123. /django_cfg/static/frontend/admin/_next/static/{ibMHm1p66p0UGKsKnDWxn → BembwiEtlu4eFl3OX7n1k}/_ssgManifest.js +0 -0
  124. /django_cfg/templates/{admin → admin_old}/components/action_grid.html +0 -0
  125. /django_cfg/templates/{admin → admin_old}/components/card.html +0 -0
  126. /django_cfg/templates/{admin → admin_old}/components/data_table.html +0 -0
  127. /django_cfg/templates/{admin → admin_old}/components/metric_card.html +0 -0
  128. /django_cfg/templates/{admin → admin_old}/components/modal.html +0 -0
  129. /django_cfg/templates/{admin → admin_old}/components/progress_bar.html +0 -0
  130. /django_cfg/templates/{admin → admin_old}/components/section_header.html +0 -0
  131. /django_cfg/templates/{admin → admin_old}/components/stat_item.html +0 -0
  132. /django_cfg/templates/{admin → admin_old}/components/stats_grid.html +0 -0
  133. /django_cfg/templates/{admin → admin_old}/components/status_badge.html +0 -0
  134. /django_cfg/templates/{admin → admin_old}/components/user_avatar.html +0 -0
  135. /django_cfg/templates/{admin → admin_old}/constance/change_list.html +0 -0
  136. /django_cfg/templates/{admin → admin_old}/constance/includes/default_value.html +0 -0
  137. /django_cfg/templates/{admin → admin_old}/constance/includes/fieldset_header.html +0 -0
  138. /django_cfg/templates/{admin → admin_old}/constance/includes/results_list.html +0 -0
  139. /django_cfg/templates/{admin → admin_old}/constance/includes/setting_row.html +0 -0
  140. /django_cfg/templates/{admin → admin_old}/constance/includes/table_headers.html +0 -0
  141. /django_cfg/templates/{admin → admin_old}/examples/component_class_example.html +0 -0
  142. /django_cfg/templates/{admin → admin_old}/import_export/change_list_export.html +0 -0
  143. /django_cfg/templates/{admin → admin_old}/import_export/change_list_import.html +0 -0
  144. /django_cfg/templates/{admin → admin_old}/import_export/change_list_import_export.html +0 -0
  145. /django_cfg/templates/{admin → admin_old}/index_new.html +0 -0
  146. /django_cfg/templates/{admin → admin_old}/layouts/base_dashboard.html +0 -0
  147. /django_cfg/templates/{admin → admin_old}/layouts/dashboard_with_tabs.html +0 -0
  148. /django_cfg/templates/{admin → admin_old}/snippets/components/activity_tracker.html +0 -0
  149. /django_cfg/templates/{admin → admin_old}/snippets/components/charts_section.html +0 -0
  150. /django_cfg/templates/{admin → admin_old}/snippets/components/django_commands.html +0 -0
  151. /django_cfg/templates/{admin → admin_old}/snippets/components/quick_actions.html +0 -0
  152. /django_cfg/templates/{admin → admin_old}/snippets/components/recent_activity_improved.html +0 -0
  153. /django_cfg/templates/{admin → admin_old}/snippets/components/recent_users_table.html +0 -0
  154. /django_cfg/templates/{admin → admin_old}/snippets/components/stats_cards.html +0 -0
  155. /django_cfg/templates/{admin → admin_old}/snippets/components/stats_tiles.html +0 -0
  156. /django_cfg/templates/{admin → admin_old}/snippets/components/system_health.html +0 -0
  157. /django_cfg/templates/{admin → admin_old}/snippets/components/system_metrics.html +0 -0
  158. /django_cfg/templates/{admin → admin_old}/snippets/components/user_permissions.html +0 -0
  159. /django_cfg/templates/{admin → admin_old}/snippets/tabs/app_stats_tab.html +0 -0
  160. /django_cfg/templates/{admin → admin_old}/snippets/tabs/commands_tab.html +0 -0
  161. /django_cfg/templates/{admin → admin_old}/snippets/tabs/documentation_tab.html +0 -0
  162. /django_cfg/templates/{admin → admin_old}/snippets/tabs/overview_tab.html +0 -0
  163. /django_cfg/templates/{admin → admin_old}/snippets/tabs/stats_tab.html +0 -0
  164. /django_cfg/templates/{admin → admin_old}/snippets/tabs/users_tab.html +0 -0
  165. /django_cfg/templates/{admin → admin_old}/snippets/tabs/widgets_tab.html +0 -0
  166. /django_cfg/templates/{admin → admin_old}/snippets/zones/zones_table.html +0 -0
  167. {django_cfg-1.4.83.dist-info → django_cfg-1.4.85.dist-info}/WHEEL +0 -0
  168. {django_cfg-1.4.83.dist-info → django_cfg-1.4.85.dist-info}/entry_points.txt +0 -0
  169. {django_cfg-1.4.83.dist-info → django_cfg-1.4.85.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,152 @@
1
+ {% load static %}
2
+ <link rel="stylesheet" href="{% static 'admin/css/prose-unfold.css' %}">
3
+
4
+ <!-- Documentation Section -->
5
+ <div class="space-y-6" x-data="toggleSection()">
6
+ {% if error %}
7
+ <!-- Error State -->
8
+ <div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-default p-6">
9
+ <div class="flex items-center space-x-2 text-red-600 dark:text-red-400">
10
+ <span class="material-symbols-outlined">error</span>
11
+ <span class="font-semibold">Error loading documentation</span>
12
+ </div>
13
+ <p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ error }}</p>
14
+ </div>
15
+ {% elif commands_by_module %}
16
+ <!-- Commands by App -->
17
+ {% for app_key, app in commands_by_module.items %}
18
+ <div class="app-block bg-gradient-to-br from-white to-base-50 dark:from-base-800 dark:to-base-900 rounded-default shadow-md border border-base-200 dark:border-base-700 overflow-hidden mb-6">
19
+ <!-- App Header (Toggle) -->
20
+ <div @click="toggleSection('{{ app_key }}')"
21
+ class="cursor-pointer select-none p-6 border-b border-base-200 dark:border-base-700 hover:bg-base-100/50 dark:hover:bg-base-900/30 transition-all duration-200"
22
+ data-app="{{ app_key }}">
23
+ <div class="w-full flex items-center justify-between">
24
+ <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark flex items-center">
25
+ <div class="w-10 h-10 rounded-lg bg-primary-100 dark:bg-primary-900/30 flex items-center justify-center mr-3">
26
+ <span class="material-symbols-outlined text-primary-600 dark:text-primary-400">description</span>
27
+ </div>
28
+ <div>
29
+ <div class="flex items-center gap-2">
30
+ {{ app.display_name }}
31
+ <span class="px-2 py-0.5 text-xs font-medium rounded-full bg-base-200 dark:bg-base-700 text-font-default-light dark:text-font-default-dark app-count">
32
+ {{ app.commands|length }}
33
+ </span>
34
+ </div>
35
+ </div>
36
+ </h3>
37
+ <span
38
+ class="material-symbols-outlined text-base-400 dark:text-base-500 transition-transform duration-200 select-none"
39
+ x-text="isSectionExpanded('{{ app_key }}') ? 'expand_less' : 'expand_more'"
40
+ ></span>
41
+ </div>
42
+ </div>
43
+
44
+ <!-- App Content -->
45
+ <div class="app-content bg-base-50/30 dark:bg-base-900/30 p-6 space-y-4"
46
+ data-app="{{ app_key }}"
47
+ x-show="isSectionExpanded('{{ app_key }}')"
48
+ x-cloak>
49
+
50
+ <!-- Commands List -->
51
+ <div class="space-y-3">
52
+ {% for command in app.commands %}
53
+ <div class="documentation-card bg-white dark:bg-base-900 rounded-default border border-base-200/60 dark:border-base-700/60 p-4 hover:border-base-300 dark:hover:border-base-600 transition-all duration-200">
54
+ <!-- Command Header -->
55
+ <div class="flex items-start justify-between mb-3">
56
+ <div class="flex-1">
57
+ <div class="flex items-center flex-wrap gap-2 mb-2">
58
+ <code class="text-sm font-mono bg-base-100 dark:bg-base-800 px-2 py-1 rounded text-primary-600 dark:text-primary-400">
59
+ python manage.py {{ command.name }}
60
+ </code>
61
+ {% if command.is_destructive %}
62
+ <span class="text-xs bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400 px-2 py-0.5 rounded">
63
+ Destructive
64
+ </span>
65
+ {% endif %}
66
+ {% if command.web_executable %}
67
+ <span class="text-xs bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 px-2 py-0.5 rounded">
68
+ Web Executable
69
+ </span>
70
+ {% endif %}
71
+ </div>
72
+ <p class="text-sm text-font-default-light dark:text-font-default-dark">
73
+ {{ command.help }}
74
+ </p>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- Command Docstring -->
79
+ {% if command.docstring %}
80
+ <div class="mt-3 prose prose-unfold max-w-none text-sm">
81
+ {{ command.docstring }}
82
+ </div>
83
+ {% endif %}
84
+
85
+ <!-- Arguments -->
86
+ {% if command.arguments %}
87
+ <div class="mt-4 border-t border-base-200 dark:border-base-700 pt-3">
88
+ <h4 class="text-xs font-semibold text-font-important-light dark:text-font-important-dark uppercase mb-2">
89
+ Arguments
90
+ </h4>
91
+ <div class="space-y-2">
92
+ {% for arg in command.arguments %}
93
+ <div class="flex items-start space-x-2 text-sm">
94
+ <code class="font-mono bg-base-100 dark:bg-base-800 px-2 py-0.5 rounded text-xs text-primary-600 dark:text-primary-400 whitespace-nowrap">
95
+ {{ arg.options|join:", " }}
96
+ </code>
97
+ <div class="flex-1">
98
+ <span class="text-font-default-light dark:text-font-default-dark">
99
+ {{ arg.help }}
100
+ </span>
101
+ {% if arg.default %}
102
+ <span class="text-font-subtle-light dark:text-font-subtle-dark text-xs">
103
+ (default: {{ arg.default }})
104
+ </span>
105
+ {% endif %}
106
+ {% if arg.required %}
107
+ <span class="text-xs text-red-600 dark:text-red-400 ml-1">
108
+ *required
109
+ </span>
110
+ {% endif %}
111
+ </div>
112
+ </div>
113
+ {% endfor %}
114
+ </div>
115
+ </div>
116
+ {% endif %}
117
+ </div>
118
+ {% endfor %}
119
+ </div>
120
+ </div>
121
+ </div>
122
+ {% endfor %}
123
+
124
+ <!-- Summary Stats -->
125
+ <div class="bg-white dark:bg-base-800 rounded-default shadow-sm border border-base-200 dark:border-base-700 p-4 mt-6">
126
+ <div class="flex items-center justify-center gap-8 text-sm text-font-subtle-light dark:text-font-subtle-dark">
127
+ <div class="flex items-center gap-2">
128
+ <span class="material-symbols-outlined text-base">folder</span>
129
+ <span>{{ total_modules }} module{{ total_modules|pluralize }}</span>
130
+ </div>
131
+ <div class="flex items-center gap-2">
132
+ <span class="material-symbols-outlined text-base">terminal</span>
133
+ <span>{{ total_commands }} command{{ total_commands|pluralize }}</span>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ {% else %}
138
+ <!-- Empty State -->
139
+ <div class="bg-base-50 dark:bg-base-800 rounded-default border border-base-200 dark:border-base-700 p-12 text-center">
140
+ <span class="material-symbols-outlined text-6xl text-base-400 dark:text-base-500 mb-4">inbox</span>
141
+ <h3 class="text-lg font-medium text-font-important-light dark:text-font-important-dark mb-2">
142
+ No Commands Found
143
+ </h3>
144
+ <p class="text-font-subtle-light dark:text-font-subtle-dark">
145
+ No Django-CFG management commands available.
146
+ </p>
147
+ </div>
148
+ {% endif %}
149
+ </div>
150
+
151
+ <!-- Load Alpine component -->
152
+ <script src="{% static 'admin/js/alpine/toggle-section.js' %}"></script>
@@ -0,0 +1,112 @@
1
+ {% load unfold %}
2
+
3
+ <!-- Overview Section -->
4
+ <div class="space-y-10 flex flex-col gap-8">
5
+ <!-- Hero Section with Key Metrics -->
6
+ <div>
7
+ <div class="flex items-center justify-between mb-6">
8
+ <div>
9
+ <h1 class="text-2xl font-bold theme-text">{{ title|default:"System Overview" }}</h1>
10
+ <p class="text-gray-600 dark:text-gray-300 mt-2">
11
+ Real-time monitoring and key performance indicators
12
+ </p>
13
+ </div>
14
+ <div class="flex items-center space-x-2 text-sm text-gray-500 dark:text-gray-400">
15
+ <span class="material-icons text-green-500">fiber_manual_record</span>
16
+ <span>Live data</span>
17
+ </div>
18
+ </div>
19
+
20
+ <!-- Key Statistics Cards -->
21
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
22
+ {% for key, value in data.stats.items %}
23
+ <div class="theme-card p-6 rounded-lg shadow-sm border theme-border">
24
+ <div class="flex items-center justify-between">
25
+ <div>
26
+ <p class="text-sm text-gray-600 dark:text-gray-400 uppercase">{{ key }}</p>
27
+ <p class="text-3xl font-bold theme-text mt-2">{{ value }}</p>
28
+ </div>
29
+ <span class="material-icons text-blue-500 text-4xl">{{ icon|default:"analytics" }}</span>
30
+ </div>
31
+ </div>
32
+ {% endfor %}
33
+ </div>
34
+ </div>
35
+
36
+ <!-- System Health & Quick Actions -->
37
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
38
+ <div class="theme-card rounded-lg shadow-sm border theme-border">
39
+ <div class="p-6 border-b theme-border">
40
+ <h3 class="text-lg font-semibold theme-text flex items-center">
41
+ <span class="material-icons text-green-500 mr-2">favorite</span>
42
+ System Health
43
+ </h3>
44
+ </div>
45
+ <div class="p-6">
46
+ <div class="space-y-4">
47
+ {% for key, value in data.system_health.items %}
48
+ <div class="flex items-center justify-between">
49
+ <span class="text-gray-700 dark:text-gray-300">{{ key|title }}</span>
50
+ <span class="font-mono text-sm theme-text">{{ value }}</span>
51
+ </div>
52
+ {% endfor %}
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <!-- Quick Actions Card -->
58
+ <div class="theme-card rounded-lg border theme-border shadow-sm">
59
+ <div class="p-6">
60
+ {% include 'admin/snippets/components/quick_actions.html' %}
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <!-- Charts & Recent Activity -->
66
+ <div class="space-y-8">
67
+ <!-- Charts Section -->
68
+ {% include 'admin/snippets/components/charts_section.html' %}
69
+
70
+ <!-- Recent Activity Stream -->
71
+ <div class="theme-card rounded-lg shadow-sm border theme-border">
72
+ <div class="p-6 border-b theme-border">
73
+ <h3 class="text-lg font-semibold theme-text flex items-center">
74
+ <span class="material-icons text-blue-600 mr-2">timeline</span>
75
+ Recent Activity
76
+ </h3>
77
+ </div>
78
+ <div class="p-6">
79
+ {% include 'admin/snippets/components/recent_activity_improved.html' %}
80
+ </div>
81
+ </div>
82
+ </div>
83
+
84
+ <!-- Secondary Metrics Row -->
85
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
86
+ <!-- System Metrics -->
87
+ <div class="theme-card rounded-lg border theme-border shadow-sm">
88
+ <div class="p-6 border-b theme-border">
89
+ <h3 class="text-lg font-semibold theme-text flex items-center">
90
+ <span class="material-icons text-blue-500 mr-2">memory</span>
91
+ System Metrics
92
+ </h3>
93
+ </div>
94
+ <div class="p-6">
95
+ {% include 'admin/snippets/components/system_metrics.html' %}
96
+ </div>
97
+ </div>
98
+
99
+ <!-- Activity Tracker -->
100
+ <div class="theme-card rounded-lg border theme-border shadow-sm">
101
+ <div class="p-6 border-b theme-border">
102
+ <h3 class="text-lg font-semibold theme-text flex items-center">
103
+ <span class="material-icons text-blue-600 mr-2">track_changes</span>
104
+ Activity Tracker
105
+ </h3>
106
+ </div>
107
+ <div class="p-6">
108
+ {% include 'admin/snippets/components/activity_tracker.html' %}
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </div>
@@ -0,0 +1,35 @@
1
+ {% load unfold %}
2
+
3
+ <!-- Statistics Section -->
4
+ <div class="space-y-8">
5
+ <div class="flex items-center justify-between mb-6">
6
+ <div>
7
+ <h1 class="text-2xl font-bold theme-text">{{ title|default:"Statistics" }}</h1>
8
+ <p class="text-gray-600 dark:text-gray-300 mt-2">
9
+ Detailed metrics for each application module
10
+ </p>
11
+ </div>
12
+ </div>
13
+
14
+ <!-- App Statistics -->
15
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
16
+ {% for app in data.app_stats %}
17
+ <div class="theme-card p-6 rounded-lg shadow-sm border theme-border">
18
+ <div class="flex items-center justify-between mb-4">
19
+ <h3 class="font-semibold theme-text">{{ app.name }}</h3>
20
+ <span class="material-icons text-blue-500">{{ app.icon|default:"apps" }}</span>
21
+ </div>
22
+ <div class="space-y-2">
23
+ <div class="flex justify-between text-sm">
24
+ <span class="text-gray-600 dark:text-gray-400">Label:</span>
25
+ <span class="theme-text">{{ app.label }}</span>
26
+ </div>
27
+ <div class="flex justify-between text-sm">
28
+ <span class="text-gray-600 dark:text-gray-400">Models:</span>
29
+ <span class="theme-text font-mono">{{ app.models_count }}</span>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ {% endfor %}
34
+ </div>
35
+ </div>
@@ -0,0 +1,99 @@
1
+ {% load unfold %}
2
+
3
+ <!-- System Management Section -->
4
+ <div class="space-y-8">
5
+ <div class="flex items-center justify-between mb-6">
6
+ <div>
7
+ <h1 class="text-2xl font-bold theme-text">{{ title|default:"System Management" }}</h1>
8
+ <p class="text-gray-600 dark:text-gray-300 mt-2">
9
+ System health checks and configuration overview
10
+ </p>
11
+ </div>
12
+ <div class="flex items-center space-x-2">
13
+ {% if data.health.status == 'healthy' %}
14
+ <span class="material-icons text-green-500">check_circle</span>
15
+ <span class="text-sm text-green-600 dark:text-green-400 font-medium">Healthy</span>
16
+ {% else %}
17
+ <span class="material-icons text-red-500">error</span>
18
+ <span class="text-sm text-red-600 dark:text-red-400 font-medium">Issues Detected</span>
19
+ {% endif %}
20
+ </div>
21
+ </div>
22
+
23
+ <!-- Health Checks Grid -->
24
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
25
+ {% for check_name, check_status in data.health.checks.items %}
26
+ <div class="theme-card p-6 rounded-lg shadow-sm border theme-border">
27
+ <div class="flex items-center justify-between">
28
+ <div>
29
+ <p class="text-sm text-gray-600 dark:text-gray-400 uppercase">{{ check_name|title }}</p>
30
+ <p class="text-lg font-semibold theme-text mt-2">
31
+ {% if check_status %}
32
+ <span class="text-green-600 dark:text-green-400">Operational</span>
33
+ {% else %}
34
+ <span class="text-red-600 dark:text-red-400">Failed</span>
35
+ {% endif %}
36
+ </p>
37
+ </div>
38
+ {% if check_status %}
39
+ <span class="material-icons text-green-500 text-3xl">check_circle</span>
40
+ {% else %}
41
+ <span class="material-icons text-red-500 text-3xl">cancel</span>
42
+ {% endif %}
43
+ </div>
44
+ </div>
45
+ {% endfor %}
46
+ </div>
47
+
48
+ <!-- Configuration & Services -->
49
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
50
+ <!-- Configuration Card -->
51
+ <div class="theme-card rounded-lg shadow-sm border theme-border">
52
+ <div class="p-6 border-b theme-border">
53
+ <h3 class="text-lg font-semibold theme-text flex items-center">
54
+ <span class="material-icons text-blue-500 mr-2">settings</span>
55
+ Configuration
56
+ </h3>
57
+ </div>
58
+ <div class="p-6">
59
+ <div class="space-y-4">
60
+ {% for key, value in data.configuration.items %}
61
+ <div class="flex items-center justify-between">
62
+ <span class="text-gray-700 dark:text-gray-300">{{ key|title }}</span>
63
+ <span class="font-mono text-sm theme-text">{{ value }}</span>
64
+ </div>
65
+ {% endfor %}
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- Services Status Card -->
71
+ <div class="theme-card rounded-lg shadow-sm border theme-border">
72
+ <div class="p-6 border-b theme-border">
73
+ <h3 class="text-lg font-semibold theme-text flex items-center">
74
+ <span class="material-icons text-purple-500 mr-2">cloud</span>
75
+ Services
76
+ </h3>
77
+ </div>
78
+ <div class="p-6">
79
+ {% if data.services %}
80
+ <div class="space-y-3">
81
+ {% for service_name, service_status in data.services.items %}
82
+ <div class="flex items-center justify-between text-sm">
83
+ <span class="theme-text">{{ service_name }}</span>
84
+ <div class="status-indicator">
85
+ <span class="status-dot {% if service_status %}success{% else %}error{% endif %}"></span>
86
+ <span class="text-gray-600 dark:text-gray-400">
87
+ {% if service_status %}Active{% else %}Inactive{% endif %}
88
+ </span>
89
+ </div>
90
+ </div>
91
+ {% endfor %}
92
+ </div>
93
+ {% else %}
94
+ <p class="text-gray-500 dark:text-gray-400 text-sm">No external services configured</p>
95
+ {% endif %}
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </div>
@@ -0,0 +1,129 @@
1
+ {% load unfold %}
2
+
3
+ <!-- Widgets Section -->
4
+ <div class="space-y-8">
5
+ <!-- Header -->
6
+ <div class="flex items-center justify-between mb-6">
7
+ <div>
8
+ <h1 class="text-2xl font-bold theme-text flex items-center">
9
+ <span class="material-icons mr-3 text-blue-500">widgets</span>
10
+ {{ title|default:"Dashboard Widgets" }}
11
+ </h1>
12
+ <p class="text-gray-600 dark:text-gray-300 mt-2">
13
+ {% if data.has_widgets %}
14
+ Showing {{ data.widgets_count }} widget{{ data.widgets_count|pluralize }}
15
+ {% else %}
16
+ No widgets configured
17
+ {% endif %}
18
+ </p>
19
+ </div>
20
+ </div>
21
+
22
+ {% if data.has_widgets %}
23
+ <!-- Stats Widgets -->
24
+ {% if stats_widgets %}
25
+ {% for widget in stats_widgets %}
26
+ <div class="theme-card rounded-lg shadow-sm border theme-border mb-6">
27
+ <!-- Widget Header -->
28
+ <div class="p-6 border-b theme-border">
29
+ <h2 class="text-lg font-semibold theme-text flex items-center">
30
+ <span class="material-icons text-blue-500 mr-2">dashboard</span>
31
+ {{ widget.title }}
32
+ </h2>
33
+ </div>
34
+
35
+ <!-- Widget Content: Stats Cards -->
36
+ <div class="p-6">
37
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
38
+ {% for card in widget.cards %}
39
+ <div class="theme-card p-6 rounded-lg shadow-sm border theme-border">
40
+ <div class="flex items-start justify-between mb-4">
41
+ <div class="flex-1">
42
+ <p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
43
+ {{ card.title }}
44
+ </p>
45
+ <p class="text-2xl font-bold theme-text">
46
+ {{ card.value_template }}
47
+ </p>
48
+ </div>
49
+ {% if card.icon %}
50
+ <span class="material-icons text-{{ card.color }}-500 text-3xl">
51
+ {{ card.icon }}
52
+ </span>
53
+ {% endif %}
54
+ </div>
55
+
56
+ {% if card.description %}
57
+ <p class="text-xs text-gray-500 dark:text-gray-400 mt-2">
58
+ {{ card.description }}
59
+ </p>
60
+ {% endif %}
61
+
62
+ {% if card.change %}
63
+ <div class="mt-3 flex items-center">
64
+ <span class="text-xs px-2 py-1 rounded
65
+ {% if card.change_type == 'positive' %}
66
+ bg-green-100 text-green-700 dark:bg-green-900/20 dark:text-green-400
67
+ {% elif card.change_type == 'negative' %}
68
+ bg-red-100 text-red-700 dark:bg-red-900/20 dark:text-red-400
69
+ {% else %}
70
+ bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-400
71
+ {% endif %}
72
+ ">
73
+ {{ card.change }}
74
+ </span>
75
+ </div>
76
+ {% endif %}
77
+ </div>
78
+ {% endfor %}
79
+ </div>
80
+ </div>
81
+ </div>
82
+ {% endfor %}
83
+ {% endif %}
84
+
85
+ <!-- Chart Widgets (if any) -->
86
+ {% if chart_widgets %}
87
+ {% for widget in chart_widgets %}
88
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-6 mb-6">
89
+ <h2 class="text-lg font-semibold theme-text mb-4">
90
+ {{ widget.title }}
91
+ </h2>
92
+ <!-- Chart rendering would go here -->
93
+ <div class="h-64 flex items-center justify-center text-gray-400">
94
+ Chart widget rendering (TODO)
95
+ </div>
96
+ </div>
97
+ {% endfor %}
98
+ {% endif %}
99
+
100
+ <!-- Custom Widgets (if any) -->
101
+ {% if custom_widgets %}
102
+ {% for widget in custom_widgets %}
103
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-6 mb-6">
104
+ <h2 class="text-lg font-semibold theme-text mb-4">
105
+ {{ widget.title }}
106
+ </h2>
107
+ <!-- Custom widget rendering -->
108
+ <div class="text-gray-600 dark:text-gray-300">
109
+ Custom widget type: {{ widget.type }}
110
+ </div>
111
+ </div>
112
+ {% endfor %}
113
+ {% endif %}
114
+
115
+ {% else %}
116
+ <!-- No Widgets State -->
117
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-12 text-center">
118
+ <span class="material-icons text-gray-300 dark:text-gray-600 text-6xl mb-4">
119
+ widgets
120
+ </span>
121
+ <h3 class="text-lg font-semibold text-gray-600 dark:text-gray-400 mb-2">
122
+ No Widgets Configured
123
+ </h3>
124
+ <p class="text-sm text-gray-500 dark:text-gray-500">
125
+ Widgets can be added in DashboardManager.get_widgets_config()
126
+ </p>
127
+ </div>
128
+ {% endif %}
129
+ </div>
@@ -0,0 +1,27 @@
1
+ {% extends "unfold/layouts/skeleton.html" %}
2
+
3
+ {% block extrastyle %}
4
+ {{ block.super }}
5
+ <style id="django-cfg-theme-sync">
6
+ /* ============================================== */
7
+ /* Django CFG - Force Color Variables */
8
+ /* Ensures COLORS from get_color_scheme() apply */
9
+ /* ============================================== */
10
+
11
+ /*
12
+ * NOTE: Colors are already defined via UNFOLD['COLORS'] in:
13
+ * django_cfg/modules/django_unfold/models/config.py:get_color_scheme()
14
+ *
15
+ * This CSS just ensures Tailwind classes use those variables correctly.
16
+ */
17
+
18
+ /* Ensure color-scheme is set for proper dark mode rendering */
19
+ html.dark {
20
+ color-scheme: dark;
21
+ }
22
+
23
+ html:not(.dark) {
24
+ color-scheme: light;
25
+ }
26
+ </style>
27
+ {% endblock %}
@@ -4,6 +4,7 @@ Django-CFG Template Tags
4
4
  Provides template tags for accessing django-cfg configuration constants.
5
5
  """
6
6
 
7
+ import os
7
8
  from django import template
8
9
  from django.utils.safestring import mark_safe
9
10
  from rest_framework_simplejwt.tokens import RefreshToken
@@ -134,3 +135,55 @@ def inject_jwt_tokens_script(context):
134
135
  }})();
135
136
  </script>"""
136
137
  return mark_safe(script)
138
+
139
+
140
+ @register.simple_tag
141
+ def nextjs_admin_url(path=''):
142
+ """
143
+ Get the URL for Next.js Admin Panel.
144
+
145
+ In development mode (when DJANGO_CFG_FRONTEND_DEV_MODE=true):
146
+ Returns http://localhost:3000/{path}
147
+
148
+ In production mode:
149
+ Returns /cfg/admin/{path}
150
+
151
+ Usage in template:
152
+ {% load django_cfg %}
153
+ <iframe src="{% nextjs_admin_url 'private' %}"></iframe>
154
+
155
+ Environment variable:
156
+ DJANGO_CFG_FRONTEND_DEV_MODE=true # Enable dev mode
157
+ DJANGO_CFG_FRONTEND_DEV_PORT=3000 # Custom dev port (default: 3000)
158
+ """
159
+ # Check if frontend dev mode is enabled
160
+ is_dev_mode = os.environ.get('DJANGO_CFG_FRONTEND_DEV_MODE', '').lower() in ('true', '1', 'yes')
161
+
162
+ # Normalize path - ensure trailing slash for Django static view
163
+ if path and not path.endswith('/'):
164
+ path = f'{path}/'
165
+
166
+ if is_dev_mode:
167
+ # Development mode: use Next.js dev server
168
+ dev_port = os.environ.get('DJANGO_CFG_FRONTEND_DEV_PORT', '3000')
169
+ base_url = f'http://localhost:{dev_port}'
170
+ return f'{base_url}/{path}' if path else base_url
171
+ else:
172
+ # Production mode: use Django static files
173
+ return f'/cfg/admin/{path}' if path else '/cfg/admin/'
174
+
175
+
176
+ @register.simple_tag
177
+ def is_frontend_dev_mode():
178
+ """
179
+ Check if frontend is in development mode.
180
+
181
+ Returns True if DJANGO_CFG_FRONTEND_DEV_MODE environment variable is set to true.
182
+
183
+ Usage in template:
184
+ {% load django_cfg %}
185
+ {% if is_frontend_dev_mode %}
186
+ <div class="dev-badge">Dev Mode</div>
187
+ {% endif %}
188
+ """
189
+ return os.environ.get('DJANGO_CFG_FRONTEND_DEV_MODE', '').lower() in ('true', '1', 'yes')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.4.83
3
+ Version: 1.4.85
4
4
  Summary: Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django.
5
5
  Project-URL: Homepage, https://djangocfg.com
6
6
  Project-URL: Documentation, https://djangocfg.com