django-cfg 1.3.7__py3-none-any.whl → 1.3.11__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 (246) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/__init__.py +24 -8
  3. django_cfg/apps/accounts/admin/activity_admin.py +146 -0
  4. django_cfg/apps/accounts/admin/filters.py +98 -22
  5. django_cfg/apps/accounts/admin/group_admin.py +86 -0
  6. django_cfg/apps/accounts/admin/inlines.py +42 -13
  7. django_cfg/apps/accounts/admin/otp_admin.py +115 -0
  8. django_cfg/apps/accounts/admin/registration_admin.py +173 -0
  9. django_cfg/apps/accounts/admin/resources.py +123 -19
  10. django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
  11. django_cfg/apps/accounts/admin/user_admin.py +362 -0
  12. django_cfg/apps/agents/admin/__init__.py +17 -4
  13. django_cfg/apps/agents/admin/execution_admin.py +204 -183
  14. django_cfg/apps/agents/admin/registry_admin.py +230 -255
  15. django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
  16. django_cfg/apps/agents/core/__init__.py +1 -1
  17. django_cfg/apps/agents/core/django_agent.py +221 -0
  18. django_cfg/apps/agents/core/exceptions.py +14 -0
  19. django_cfg/apps/agents/core/orchestrator.py +18 -3
  20. django_cfg/apps/knowbase/admin/__init__.py +1 -1
  21. django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
  22. django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
  23. django_cfg/apps/knowbase/admin/document_admin.py +269 -262
  24. django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
  25. django_cfg/apps/knowbase/config/settings.py +21 -4
  26. django_cfg/apps/knowbase/views/chat_views.py +3 -0
  27. django_cfg/apps/leads/admin/__init__.py +3 -1
  28. django_cfg/apps/leads/admin/leads_admin.py +235 -35
  29. django_cfg/apps/maintenance/admin/__init__.py +2 -2
  30. django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
  31. django_cfg/apps/maintenance/admin/log_admin.py +143 -61
  32. django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
  33. django_cfg/apps/maintenance/admin/site_admin.py +213 -352
  34. django_cfg/apps/newsletter/admin/__init__.py +29 -2
  35. django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
  36. django_cfg/apps/payments/admin/__init__.py +18 -27
  37. django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
  38. django_cfg/apps/payments/admin/balance_admin.py +166 -632
  39. django_cfg/apps/payments/admin/currencies_admin.py +235 -607
  40. django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
  41. django_cfg/apps/payments/admin/filters.py +83 -3
  42. django_cfg/apps/payments/admin/networks_admin.py +269 -0
  43. django_cfg/apps/payments/admin/payments_admin.py +183 -460
  44. django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
  45. django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
  46. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +153 -34
  47. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  48. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  49. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  50. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  51. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  52. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  53. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  54. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +43 -17
  55. django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
  56. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  57. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +109 -63
  58. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  59. django_cfg/apps/payments/config/__init__.py +14 -15
  60. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  61. django_cfg/apps/payments/config/helpers.py +8 -13
  62. django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
  63. django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
  64. django_cfg/apps/payments/middleware/api_access.py +32 -6
  65. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  66. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  67. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  68. django_cfg/apps/payments/models/balance.py +12 -0
  69. django_cfg/apps/payments/models/currencies.py +106 -32
  70. django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
  71. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  72. django_cfg/apps/payments/models/payments.py +94 -0
  73. django_cfg/apps/payments/services/core/base.py +4 -4
  74. django_cfg/apps/payments/services/core/currency_service.py +35 -28
  75. django_cfg/apps/payments/services/core/payment_service.py +266 -39
  76. django_cfg/apps/payments/services/providers/__init__.py +3 -0
  77. django_cfg/apps/payments/services/providers/base.py +303 -41
  78. django_cfg/apps/payments/services/providers/models/__init__.py +42 -0
  79. django_cfg/apps/payments/services/providers/models/base.py +145 -0
  80. django_cfg/apps/payments/services/providers/models/providers.py +87 -0
  81. django_cfg/apps/payments/services/providers/models/universal.py +48 -0
  82. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
  83. django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
  84. django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
  85. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
  86. django_cfg/apps/payments/services/providers/nowpayments/provider.py +557 -0
  87. django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
  88. django_cfg/apps/payments/services/providers/registry.py +9 -37
  89. django_cfg/apps/payments/services/providers/sync_service.py +277 -0
  90. django_cfg/apps/payments/services/types/requests.py +19 -7
  91. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  92. django_cfg/apps/payments/static/payments/js/api-client.js +29 -6
  93. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  94. django_cfg/apps/payments/static/payments/js/payment-form.js +98 -32
  95. django_cfg/apps/payments/tasks/__init__.py +39 -0
  96. django_cfg/apps/payments/tasks/types.py +73 -0
  97. django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
  98. django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
  99. django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
  100. django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
  101. django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
  102. django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
  103. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
  104. django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
  105. django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
  106. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  107. django_cfg/apps/payments/urls.py +3 -2
  108. django_cfg/apps/payments/urls_admin.py +1 -1
  109. django_cfg/apps/payments/views/api/currencies.py +8 -5
  110. django_cfg/apps/payments/views/overview/services.py +2 -2
  111. django_cfg/apps/payments/views/serializers/currencies.py +22 -8
  112. django_cfg/apps/support/admin/__init__.py +10 -1
  113. django_cfg/apps/support/admin/support_admin.py +338 -141
  114. django_cfg/apps/tasks/admin/__init__.py +11 -0
  115. django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
  116. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  117. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  118. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  119. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  120. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  121. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  122. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  123. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  124. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  125. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  126. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  127. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  128. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  129. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  130. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  131. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  132. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  133. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  134. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  135. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  136. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  137. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  138. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  139. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  140. django_cfg/apps/tasks/urls.py +2 -2
  141. django_cfg/apps/tasks/urls_admin.py +2 -2
  142. django_cfg/apps/tasks/utils/__init__.py +1 -0
  143. django_cfg/apps/tasks/utils/simulator.py +356 -0
  144. django_cfg/apps/tasks/views/__init__.py +16 -0
  145. django_cfg/apps/tasks/views/api.py +569 -0
  146. django_cfg/apps/tasks/views/dashboard.py +58 -0
  147. django_cfg/config.py +1 -1
  148. django_cfg/core/config.py +10 -5
  149. django_cfg/core/generation.py +1 -1
  150. django_cfg/core/integration/__init__.py +21 -0
  151. django_cfg/management/commands/__init__.py +13 -1
  152. django_cfg/management/commands/migrate_all.py +9 -3
  153. django_cfg/management/commands/migrator.py +11 -6
  154. django_cfg/management/commands/rundramatiq.py +3 -2
  155. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  156. django_cfg/middleware/__init__.py +0 -2
  157. django_cfg/models/api_keys.py +115 -0
  158. django_cfg/models/constance.py +0 -11
  159. django_cfg/models/payments.py +137 -3
  160. django_cfg/modules/django_admin/__init__.py +64 -0
  161. django_cfg/modules/django_admin/decorators/__init__.py +13 -0
  162. django_cfg/modules/django_admin/decorators/actions.py +106 -0
  163. django_cfg/modules/django_admin/decorators/display.py +106 -0
  164. django_cfg/modules/django_admin/mixins/__init__.py +14 -0
  165. django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
  166. django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
  167. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
  168. django_cfg/modules/django_admin/models/__init__.py +20 -0
  169. django_cfg/modules/django_admin/models/action_models.py +33 -0
  170. django_cfg/modules/django_admin/models/badge_models.py +20 -0
  171. django_cfg/modules/django_admin/models/base.py +26 -0
  172. django_cfg/modules/django_admin/models/display_models.py +31 -0
  173. django_cfg/modules/django_admin/utils/badges.py +159 -0
  174. django_cfg/modules/django_admin/utils/displays.py +247 -0
  175. django_cfg/modules/django_currency/__init__.py +2 -2
  176. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  177. django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
  178. django_cfg/modules/django_currency/core/converter.py +12 -12
  179. django_cfg/modules/django_currency/database/__init__.py +2 -2
  180. django_cfg/modules/django_currency/database/database_loader.py +93 -42
  181. django_cfg/modules/django_llm/llm/client.py +10 -2
  182. django_cfg/modules/django_tasks.py +54 -21
  183. django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
  184. django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
  185. django_cfg/modules/django_unfold/dashboard.py +14 -13
  186. django_cfg/modules/django_unfold/models/config.py +1 -1
  187. django_cfg/registry/core.py +7 -9
  188. django_cfg/registry/third_party.py +2 -2
  189. django_cfg/template_archive/django_sample.zip +0 -0
  190. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -1
  191. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/RECORD +198 -160
  192. django_cfg/apps/accounts/admin/activity.py +0 -96
  193. django_cfg/apps/accounts/admin/group.py +0 -17
  194. django_cfg/apps/accounts/admin/otp.py +0 -59
  195. django_cfg/apps/accounts/admin/registration_source.py +0 -97
  196. django_cfg/apps/accounts/admin/twilio_response.py +0 -227
  197. django_cfg/apps/accounts/admin/user.py +0 -300
  198. django_cfg/apps/agents/core/agent.py +0 -281
  199. django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
  200. django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
  201. django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
  202. django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
  203. django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
  204. django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
  205. django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
  206. django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
  207. django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
  208. django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
  209. django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
  210. django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
  211. django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
  212. django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
  213. django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
  214. django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
  215. django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
  216. django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
  217. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  218. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  219. django_cfg/apps/payments/config/constance/fields.py +0 -69
  220. django_cfg/apps/payments/config/constance/settings.py +0 -160
  221. django_cfg/apps/payments/services/providers/nowpayments.py +0 -478
  222. django_cfg/apps/tasks/admin.py +0 -320
  223. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  224. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  225. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  226. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  227. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  228. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  229. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  230. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  231. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  232. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  233. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  234. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  235. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  236. django_cfg/apps/tasks/views.py +0 -461
  237. django_cfg/management/commands/auto_generate.py +0 -486
  238. django_cfg/middleware/static_nocache.py +0 -55
  239. django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
  240. /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
  241. /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
  242. /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
  243. /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
  244. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  246. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,269 +1,120 @@
1
- /**
2
- * Dashboard Custom Styles
3
- * Additional styles for the Dramatiq Tasks Dashboard
4
- */
1
+ /* Tasks Dashboard CSS */
5
2
 
6
- /* Custom scrollbar for dark mode */
7
- ::-webkit-scrollbar {
8
- width: 8px;
9
- height: 8px;
3
+ /* Tab styling */
4
+ .tab-button.active {
5
+ border-color: rgb(59 130 246) !important;
6
+ color: rgb(59 130 246) !important;
10
7
  }
11
8
 
12
- ::-webkit-scrollbar-track {
13
- background: transparent;
9
+ .tab-panel {
10
+ display: none;
14
11
  }
15
12
 
16
- ::-webkit-scrollbar-thumb {
17
- background: rgba(156, 163, 175, 0.5);
18
- border-radius: 4px;
13
+ .tab-panel.active {
14
+ display: block;
19
15
  }
20
16
 
21
- ::-webkit-scrollbar-thumb:hover {
22
- background: rgba(156, 163, 175, 0.7);
17
+ /* Custom scrollbar */
18
+ .task-table-widget::-webkit-scrollbar {
19
+ height: 8px;
23
20
  }
24
21
 
25
- .dark ::-webkit-scrollbar-thumb {
26
- background: rgba(75, 85, 99, 0.5);
22
+ .task-table-widget::-webkit-scrollbar-track {
23
+ background: #f1f5f9;
27
24
  }
28
25
 
29
- .dark ::-webkit-scrollbar-thumb:hover {
30
- background: rgba(75, 85, 99, 0.7);
26
+ .task-table-widget::-webkit-scrollbar-thumb {
27
+ background: #cbd5e1;
28
+ border-radius: 4px;
31
29
  }
32
30
 
33
- /* Tab transitions */
34
- .tab-button {
35
- transition: all 0.2s ease-in-out;
31
+ .task-table-widget::-webkit-scrollbar-thumb:hover {
32
+ background: #94a3b8;
36
33
  }
37
34
 
38
- .tab-panel {
39
- transition: opacity 0.2s ease-in-out;
35
+ /* Dark mode scrollbar */
36
+ .dark .task-table-widget::-webkit-scrollbar-track {
37
+ background: #374151;
40
38
  }
41
39
 
42
- .tab-panel.hidden {
43
- opacity: 0;
40
+ .dark .task-table-widget::-webkit-scrollbar-thumb {
41
+ background: #6b7280;
44
42
  }
45
43
 
46
- .tab-panel.active {
47
- opacity: 1;
44
+ .dark .task-table-widget::-webkit-scrollbar-thumb:hover {
45
+ background: #9ca3af;
48
46
  }
49
47
 
50
- /* Loading animations */
51
- @keyframes pulse {
52
- 0%, 100% {
53
- opacity: 1;
54
- }
55
- 50% {
56
- opacity: 0.5;
48
+ /* Loading animation */
49
+ @keyframes spin {
50
+ to {
51
+ transform: rotate(360deg);
57
52
  }
58
53
  }
59
54
 
60
- .animate-pulse {
61
- animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
55
+ .animate-spin {
56
+ animation: spin 1s linear infinite;
62
57
  }
63
58
 
64
59
  /* Status indicators */
65
60
  .status-indicator {
66
- position: relative;
67
- display: inline-block;
68
- }
69
-
70
- .status-indicator::before {
71
- content: '';
72
- position: absolute;
73
- top: 0;
74
- right: 0;
75
61
  width: 8px;
76
62
  height: 8px;
77
63
  border-radius: 50%;
78
- border: 2px solid white;
79
- }
80
-
81
- .status-indicator.online::before {
82
- background-color: #10b981;
83
- }
84
-
85
- .status-indicator.offline::before {
86
- background-color: #ef4444;
64
+ display: inline-block;
65
+ margin-right: 8px;
87
66
  }
88
67
 
89
- .status-indicator.warning::before {
68
+ .status-pending {
90
69
  background-color: #f59e0b;
91
70
  }
92
71
 
93
- /* Card hover effects */
94
- .card-hover {
95
- transition: all 0.2s ease-in-out;
96
- }
97
-
98
- .card-hover:hover {
99
- transform: translateY(-2px);
100
- box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
101
- }
102
-
103
- .dark .card-hover:hover {
104
- box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
105
- }
106
-
107
- /* Button loading state */
108
- .btn-loading {
109
- position: relative;
110
- pointer-events: none;
111
- }
112
-
113
- .btn-loading::after {
114
- content: '';
115
- position: absolute;
116
- top: 50%;
117
- left: 50%;
118
- width: 16px;
119
- height: 16px;
120
- margin: -8px 0 0 -8px;
121
- border: 2px solid transparent;
122
- border-top: 2px solid currentColor;
123
- border-radius: 50%;
124
- animation: spin 1s linear infinite;
125
- }
126
-
127
- @keyframes spin {
128
- 0% {
129
- transform: rotate(0deg);
130
- }
131
- 100% {
132
- transform: rotate(360deg);
133
- }
134
- }
135
-
136
- /* Modal backdrop blur */
137
- .modal-backdrop {
138
- backdrop-filter: blur(4px);
139
- -webkit-backdrop-filter: blur(4px);
140
- }
141
-
142
- /* Custom focus styles */
143
- .focus-ring:focus {
144
- outline: 2px solid transparent;
145
- outline-offset: 2px;
146
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
147
- }
148
-
149
- .dark .focus-ring:focus {
150
- box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.5);
151
- }
152
-
153
- /* Progress bars */
154
- .progress-bar {
155
- position: relative;
156
- overflow: hidden;
157
- background-color: #e5e7eb;
158
- border-radius: 0.25rem;
159
- height: 0.5rem;
160
- }
161
-
162
- .dark .progress-bar {
163
- background-color: #374151;
164
- }
165
-
166
- .progress-bar-fill {
167
- height: 100%;
72
+ .status-running {
168
73
  background-color: #3b82f6;
169
- transition: width 0.3s ease-in-out;
170
74
  }
171
75
 
172
- .progress-bar-fill.success {
76
+ .status-completed {
173
77
  background-color: #10b981;
174
78
  }
175
79
 
176
- .progress-bar-fill.warning {
177
- background-color: #f59e0b;
178
- }
179
-
180
- .progress-bar-fill.error {
80
+ .status-failed {
181
81
  background-color: #ef4444;
182
82
  }
183
83
 
184
- /* Tooltip styles */
185
- .tooltip {
186
- position: relative;
187
- }
188
-
189
- .tooltip::before {
190
- content: attr(data-tooltip);
191
- position: absolute;
192
- bottom: 100%;
193
- left: 50%;
194
- transform: translateX(-50%);
195
- padding: 0.5rem;
196
- background-color: #1f2937;
197
- color: white;
198
- font-size: 0.75rem;
199
- border-radius: 0.25rem;
200
- white-space: nowrap;
201
- opacity: 0;
202
- pointer-events: none;
203
- transition: opacity 0.2s ease-in-out;
204
- z-index: 1000;
205
- }
206
-
207
- .tooltip:hover::before {
208
- opacity: 1;
84
+ /* Progress bar */
85
+ .progress-bar {
86
+ transition: width 0.3s ease-in-out;
209
87
  }
210
88
 
211
- /* Responsive adjustments */
212
- @media (max-width: 768px) {
213
- .tab-button {
214
- padding: 0.5rem 0.25rem;
215
- font-size: 0.75rem;
216
- }
217
-
218
- .tab-button .material-icons {
219
- display: none;
220
- }
221
-
222
- .status-cards {
223
- grid-template-columns: repeat(2, 1fr);
224
- gap: 1rem;
225
- }
226
-
227
- .info-cards {
228
- grid-template-columns: 1fr;
229
- }
89
+ /* Hover effects */
90
+ .hover-card:hover {
91
+ transform: translateY(-2px);
92
+ box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
93
+ transition: all 0.2s ease-in-out;
230
94
  }
231
95
 
232
- @media (max-width: 640px) {
233
- .status-cards {
234
- grid-template-columns: 1fr;
235
- }
236
-
237
- .tab-navigation {
238
- overflow-x: auto;
239
- scrollbar-width: none;
240
- -ms-overflow-style: none;
241
- }
242
-
243
- .tab-navigation::-webkit-scrollbar {
244
- display: none;
245
- }
96
+ /* Button focus states */
97
+ .btn-focus:focus {
98
+ outline: 2px solid rgb(59 130 246);
99
+ outline-offset: 2px;
246
100
  }
247
101
 
248
- /* Print styles */
249
- @media print {
250
- .tab-navigation,
251
- .modal-container,
252
- button {
253
- display: none !important;
254
- }
255
-
256
- .tab-panel {
257
- display: block !important;
258
- }
259
-
260
- .bg-gray-50,
261
- .dark\:bg-gray-900 {
262
- background: white !important;
263
- }
264
-
265
- .text-gray-900,
266
- .dark\:text-white {
267
- color: black !important;
268
- }
102
+ /* Material icons alignment */
103
+ .material-icons {
104
+ vertical-align: middle;
105
+ line-height: 1;
106
+ }
107
+
108
+ /* Custom primary color */
109
+ :root {
110
+ --primary-50: #eff6ff;
111
+ --primary-100: #dbeafe;
112
+ --primary-200: #bfdbfe;
113
+ --primary-300: #93c5fd;
114
+ --primary-400: #60a5fa;
115
+ --primary-500: #3b82f6;
116
+ --primary-600: #2563eb;
117
+ --primary-700: #1d4ed8;
118
+ --primary-800: #1e40af;
119
+ --primary-900: #1e3a8a;
269
120
  }
@@ -1,51 +1,32 @@
1
1
  /**
2
- * API Client for Dramatiq Tasks Dashboard
3
- * Handles all API communication with the backend
2
+ * Tasks API Client
3
+ * Handles all API communication for the Tasks Dashboard
4
4
  */
5
-
6
5
  class TasksAPI {
7
- constructor(baseUrl = '/cfg/tasks/api') {
6
+ constructor(baseUrl = '/api/tasks/api') {
8
7
  this.baseUrl = baseUrl;
9
8
  }
10
9
 
11
10
  /**
12
- * Make an API request
11
+ * Make API request
13
12
  * @param {string} endpoint - API endpoint
14
- * @param {Object} options - Fetch options
15
- * @returns {Promise<Object>} API response
13
+ * @param {Object} options - Request options
14
+ * @returns {Promise<Object>} - API response
16
15
  */
17
16
  async request(endpoint, options = {}) {
18
17
  const url = `${this.baseUrl}${endpoint}`;
19
18
  const defaultOptions = {
19
+ method: 'GET',
20
20
  headers: {
21
21
  'Content-Type': 'application/json',
22
- 'X-Requested-With': 'XMLHttpRequest',
22
+ 'X-CSRFToken': this.getCSRFToken(),
23
23
  },
24
- credentials: 'same-origin', // Include cookies for session authentication
25
24
  };
26
25
 
27
- // Add CSRF token if available
28
- let csrfToken = document.querySelector('[name=csrfmiddlewaretoken]');
29
- if (!csrfToken) {
30
- // Try alternative selectors
31
- csrfToken = document.querySelector('input[name="csrfmiddlewaretoken"]');
32
- }
33
- if (!csrfToken) {
34
- // Try getting from cookie
35
- const cookies = document.cookie.split(';');
36
- for (let cookie of cookies) {
37
- const [name, value] = cookie.trim().split('=');
38
- if (name === 'csrftoken') {
39
- defaultOptions.headers['X-CSRFToken'] = value;
40
- break;
41
- }
42
- }
43
- } else {
44
- defaultOptions.headers['X-CSRFToken'] = csrfToken.value;
45
- }
26
+ const config = { ...defaultOptions, ...options };
46
27
 
47
28
  try {
48
- const response = await fetch(url, { ...defaultOptions, ...options });
29
+ const response = await fetch(url, config);
49
30
 
50
31
  if (!response.ok) {
51
32
  throw new Error(`HTTP error! status: ${response.status}`);
@@ -59,86 +40,61 @@ class TasksAPI {
59
40
  }
60
41
 
61
42
  /**
62
- * Get queue status
63
- * @returns {Promise<Object>} Queue status data
43
+ * Get CSRF token from DOM
44
+ * @returns {string} - CSRF token
64
45
  */
46
+ getCSRFToken() {
47
+ const token = document.querySelector('[name=csrfmiddlewaretoken]');
48
+ return token ? token.value : '';
49
+ }
50
+
51
+ // Queue endpoints
65
52
  async getQueueStatus() {
66
53
  return this.request('/queues/status/');
67
54
  }
68
55
 
69
- /**
70
- * Get task statistics
71
- * @returns {Promise<Object>} Task statistics data
72
- */
56
+ // Task endpoints
73
57
  async getTaskStatistics() {
74
58
  return this.request('/tasks/stats/');
75
59
  }
76
60
 
77
- /**
78
- * Get detailed task list
79
- * @param {Object} params - Query parameters (status, queue, search, limit, offset)
80
- * @returns {Promise<Object>} Task list
81
- */
82
61
  async getTaskList(params = {}) {
83
62
  const queryString = new URLSearchParams(params).toString();
84
- const url = `/tasks/list/${queryString ? '?' + queryString : ''}`;
85
- return this.request(url);
63
+ const endpoint = queryString ? `/tasks/list/?${queryString}` : '/tasks/list/';
64
+ return this.request(endpoint);
86
65
  }
87
66
 
88
- /**
89
- * Start workers
90
- * @param {Object} config - Worker configuration
91
- * @returns {Promise<Object>} Operation result
92
- */
93
- async startWorkers(config = {}) {
94
- return this.request('/workers/manage/', {
95
- method: 'POST',
96
- body: JSON.stringify({
97
- action: 'start',
98
- ...config
99
- })
67
+ // Worker endpoints
68
+ async getWorkersList() {
69
+ return this.request('/workers/list/');
70
+ }
71
+
72
+ // Management endpoints
73
+ async simulateData() {
74
+ return this.request('/simulate/', {
75
+ method: 'POST'
100
76
  });
101
77
  }
102
78
 
103
- /**
104
- * Stop workers
105
- * @returns {Promise<Object>} Operation result
106
- */
107
- async stopWorkers() {
108
- return this.request('/workers/manage/', {
109
- method: 'POST',
110
- body: JSON.stringify({
111
- action: 'stop'
112
- })
79
+ async clearData() {
80
+ return this.request('/clear/', {
81
+ method: 'POST'
113
82
  });
114
83
  }
115
84
 
116
- /**
117
- * Clear all queues
118
- * @returns {Promise<Object>} Operation result
119
- */
120
85
  async clearQueues() {
121
- return this.request('/queues/manage/', {
122
- method: 'POST',
123
- body: JSON.stringify({
124
- action: 'clear_all'
125
- })
86
+ return this.request('/clear-queues/', {
87
+ method: 'POST'
126
88
  });
127
89
  }
128
90
 
129
- /**
130
- * Purge failed tasks
131
- * @returns {Promise<Object>} Operation result
132
- */
133
- async purgeFailedTasks() {
134
- return this.request('/queues/manage/', {
135
- method: 'POST',
136
- body: JSON.stringify({
137
- action: 'purge_failed'
138
- })
91
+ async purgeFailed() {
92
+ return this.request('/purge-failed/', {
93
+ method: 'POST'
139
94
  });
140
95
  }
141
96
  }
142
97
 
143
- // Create global API instance
98
+ // Export for use in modules
99
+ window.TasksAPI = TasksAPI;
144
100
  window.tasksAPI = new TasksAPI();
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Data Manager - Handles data fetching and caching
3
+ */
4
+ export class DataManager {
5
+ constructor(api) {
6
+ this.api = api;
7
+ this.cache = new Map();
8
+ }
9
+
10
+ async getData(key, fetcher, ttl = 30000) {
11
+ const cached = this.cache.get(key);
12
+ if (cached && Date.now() - cached.timestamp < ttl) {
13
+ return cached.data;
14
+ }
15
+
16
+ const data = await fetcher();
17
+ this.cache.set(key, { data, timestamp: Date.now() });
18
+ return data;
19
+ }
20
+
21
+ clearCache() {
22
+ this.cache.clear();
23
+ }
24
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * TabManager - Handles tab switching and navigation
3
+ */
4
+ export class TabManager {
5
+ constructor() {
6
+ this.currentTab = 'overview';
7
+ this.setupEventListeners();
8
+ }
9
+
10
+ setupEventListeners() {
11
+ // Tab buttons
12
+ document.querySelectorAll('.tab-button').forEach(button => {
13
+ button.addEventListener('click', (e) => {
14
+ const tabId = e.currentTarget.dataset.tab;
15
+ this.switchTab(tabId);
16
+ });
17
+ });
18
+ }
19
+
20
+ /**
21
+ * Switch to a specific tab
22
+ * @param {string} tabId - Tab identifier
23
+ */
24
+ switchTab(tabId) {
25
+ // Update active tab styling
26
+ document.querySelectorAll('.tab-button').forEach(tab => {
27
+ tab.classList.remove('active', 'border-primary-500', 'text-primary-600', 'dark:text-primary-400');
28
+ tab.classList.add('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300');
29
+ });
30
+
31
+ // Add active to selected tab
32
+ const activeTab = document.querySelector(`[data-tab="${tabId}"]`);
33
+ if (activeTab) {
34
+ activeTab.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300');
35
+ activeTab.classList.add('active', 'border-primary-500', 'text-primary-600', 'dark:text-primary-400');
36
+ }
37
+
38
+ // Hide all tab panels
39
+ document.querySelectorAll('.tab-panel').forEach(panel => {
40
+ panel.classList.add('hidden');
41
+ panel.classList.remove('active');
42
+ });
43
+
44
+ // Show selected tab panel
45
+ const activePanel = document.querySelector(`#${tabId}-tab`);
46
+ if (activePanel) {
47
+ activePanel.classList.remove('hidden');
48
+ activePanel.classList.add('active');
49
+ }
50
+
51
+ this.currentTab = tabId;
52
+
53
+ // Trigger tab change event
54
+ this.onTabChange(tabId);
55
+ }
56
+
57
+ /**
58
+ * Get current active tab
59
+ * @returns {string} - Current tab ID
60
+ */
61
+ getCurrentTab() {
62
+ return this.currentTab;
63
+ }
64
+
65
+ /**
66
+ * Tab change callback - override in dashboard
67
+ * @param {string} tabId - New tab ID
68
+ */
69
+ onTabChange(tabId) {
70
+ // Override this method in the main dashboard
71
+ console.log('Tab changed to:', tabId);
72
+ }
73
+
74
+ /**
75
+ * Update tab badge count
76
+ * @param {string} tabId - Tab identifier
77
+ * @param {number} count - Badge count
78
+ */
79
+ updateTabBadge(tabId, count) {
80
+ const badge = document.querySelector(`#${tabId}-count-badge`);
81
+ if (badge) {
82
+ badge.textContent = count;
83
+ }
84
+ }
85
+ }