django-cfg 1.3.9__py3-none-any.whl → 1.3.13__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 (188) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  4. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  5. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  14. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  15. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  16. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  17. django_cfg/apps/payments/config/__init__.py +14 -15
  18. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  19. django_cfg/apps/payments/config/helpers.py +8 -13
  20. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  21. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  22. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  23. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  24. django_cfg/apps/payments/models/payments.py +94 -0
  25. django_cfg/apps/payments/services/core/base.py +4 -4
  26. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  27. django_cfg/apps/payments/services/providers/base.py +209 -3
  28. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  29. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  31. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  32. django_cfg/apps/payments/services/providers/registry.py +5 -5
  33. django_cfg/apps/payments/services/types/requests.py +19 -7
  34. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  35. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  36. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  37. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  38. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  39. django_cfg/apps/payments/urls.py +3 -2
  40. django_cfg/apps/payments/views/api/currencies.py +3 -0
  41. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  42. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  43. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  44. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  45. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  47. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  52. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  53. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  54. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  55. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  56. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  57. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  58. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  59. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  60. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  61. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  62. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  63. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  66. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  67. django_cfg/apps/tasks/urls.py +2 -2
  68. django_cfg/apps/tasks/urls_admin.py +2 -2
  69. django_cfg/apps/tasks/utils/__init__.py +1 -0
  70. django_cfg/apps/tasks/utils/simulator.py +356 -0
  71. django_cfg/apps/tasks/views/__init__.py +16 -0
  72. django_cfg/apps/tasks/views/api.py +569 -0
  73. django_cfg/apps/tasks/views/dashboard.py +58 -0
  74. django_cfg/core/integration/__init__.py +21 -0
  75. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  76. django_cfg/models/constance.py +0 -11
  77. django_cfg/models/payments.py +137 -3
  78. django_cfg/modules/django_tasks.py +54 -21
  79. django_cfg/registry/core.py +4 -9
  80. django_cfg/template_archive/django_sample.zip +0 -0
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/METADATA +2 -2
  82. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/RECORD +85 -153
  83. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  84. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  85. django_cfg/apps/payments/config/constance/fields.py +0 -69
  86. django_cfg/apps/payments/config/constance/settings.py +0 -160
  87. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  88. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  89. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  90. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  91. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  92. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  93. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  94. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  95. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  96. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  97. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  98. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  99. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  100. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  101. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  102. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  103. django_cfg/apps/tasks/views.py +0 -461
  104. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  105. django_cfg/management/commands/app_agent_generate.py +0 -342
  106. django_cfg/management/commands/app_agent_info.py +0 -308
  107. django_cfg/management/commands/auto_generate.py +0 -486
  108. django_cfg/modules/django_app_agent/__init__.py +0 -87
  109. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  110. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  111. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  112. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  113. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  114. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  119. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  120. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  121. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  122. django_cfg/modules/django_app_agent/core/config.py +0 -300
  123. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  124. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  125. django_cfg/modules/django_app_agent/models/base.py +0 -283
  126. django_cfg/modules/django_app_agent/models/context.py +0 -496
  127. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  128. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  129. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  130. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  131. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  132. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  133. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  134. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  135. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  136. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  137. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  138. django_cfg/modules/django_app_agent/services/base.py +0 -437
  139. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  140. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  141. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  142. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  143. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  144. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  145. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  146. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  147. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  148. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  149. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  150. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  151. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  152. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  153. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  154. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  155. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  156. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  157. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  158. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  159. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  160. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  161. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  171. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  172. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  173. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  174. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  175. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  176. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  177. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  178. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  179. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  180. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  181. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  182. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  183. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  184. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  185. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/WHEEL +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/entry_points.txt +0 -0
  188. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.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
+ }