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