django-cfg 1.4.107__py3-none-any.whl → 1.4.109__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-cfg might be problematic. Click here for more details.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/views/profile.py +19 -9
- django_cfg/apps/centrifugo/views/admin_api.py +4 -7
- django_cfg/apps/centrifugo/views/monitoring.py +3 -6
- django_cfg/apps/centrifugo/views/testing_api.py +3 -6
- django_cfg/apps/dashboard/services/system_health_service.py +16 -11
- django_cfg/apps/dashboard/views/activity_views.py +3 -5
- django_cfg/apps/dashboard/views/apizones_views.py +4 -5
- django_cfg/apps/dashboard/views/charts_views.py +4 -5
- django_cfg/apps/dashboard/views/overview_views.py +4 -5
- django_cfg/apps/dashboard/views/statistics_views.py +4 -5
- django_cfg/apps/dashboard/views/system_views.py +4 -5
- django_cfg/apps/knowbase/__init__.py +2 -2
- django_cfg/apps/knowbase/apps.py +2 -8
- django_cfg/apps/knowbase/views/base.py +9 -4
- django_cfg/apps/support/views/api.py +16 -7
- django_cfg/apps/tasks/__init__.py +61 -2
- django_cfg/apps/tasks/admin/__init__.py +3 -10
- django_cfg/apps/tasks/admin/config.py +98 -0
- django_cfg/apps/tasks/admin/task_log.py +265 -0
- django_cfg/apps/tasks/apps.py +7 -9
- django_cfg/apps/tasks/filters/__init__.py +10 -0
- django_cfg/apps/tasks/filters/task_log.py +121 -0
- django_cfg/apps/tasks/migrations/0001_initial.py +196 -0
- django_cfg/apps/tasks/models/__init__.py +4 -0
- django_cfg/apps/tasks/models/task_log.py +246 -0
- django_cfg/apps/tasks/serializers/__init__.py +28 -0
- django_cfg/apps/tasks/serializers/task_log.py +249 -0
- django_cfg/apps/tasks/services/__init__.py +10 -0
- django_cfg/apps/tasks/services/client/__init__.py +7 -0
- django_cfg/apps/tasks/services/client/client.py +234 -0
- django_cfg/apps/tasks/services/config_helper.py +63 -0
- django_cfg/apps/tasks/services/sync.py +204 -0
- django_cfg/apps/tasks/urls.py +7 -13
- django_cfg/apps/tasks/views/__init__.py +4 -10
- django_cfg/apps/tasks/views/task_log.py +41 -0
- django_cfg/apps/tasks/views/task_log_base.py +41 -0
- django_cfg/apps/tasks/views/task_log_overview.py +100 -0
- django_cfg/apps/tasks/views/task_log_related.py +41 -0
- django_cfg/apps/tasks/views/task_log_stats.py +91 -0
- django_cfg/apps/tasks/views/task_log_timeline.py +81 -0
- django_cfg/apps/urls.py +0 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/utils.py +1 -1
- django_cfg/core/base/config_model.py +1 -1
- django_cfg/core/builders/apps_builder.py +1 -1
- django_cfg/core/generation/integration_generators/__init__.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +14 -18
- django_cfg/core/generation/security_generators/crypto_fields.py +2 -1
- django_cfg/core/integration/display/startup.py +1 -1
- django_cfg/mixins/__init__.py +12 -0
- django_cfg/mixins/admin_api.py +37 -0
- django_cfg/mixins/client_api.py +39 -0
- django_cfg/models/django/constance.py +2 -8
- django_cfg/models/django/crypto_fields.py +13 -48
- django_cfg/models/tasks/__init__.py +8 -10
- django_cfg/models/tasks/backends.py +76 -207
- django_cfg/models/tasks/config.py +20 -127
- django_cfg/models/tasks/utils.py +17 -29
- django_cfg/modules/django_client/management/commands/generate_client.py +13 -1
- django_cfg/modules/django_unfold/navigation.py +121 -22
- django_cfg/pyproject.toml +2 -2
- django_cfg/registry/core.py +1 -1
- django_cfg/static/frontend/admin.zip +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/METADATA +3 -3
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/RECORD +70 -117
- django_cfg/apps/tasks/admin/actions.py +0 -29
- django_cfg/apps/tasks/admin/tasks_admin.py +0 -154
- django_cfg/apps/tasks/api/serializers.py +0 -82
- django_cfg/apps/tasks/api/views.py +0 -571
- django_cfg/apps/tasks/serializers.py +0 -82
- django_cfg/apps/tasks/static/tasks/css/dashboard-alpine.css +0 -299
- django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -120
- django_cfg/apps/tasks/static/tasks/js/alpine/README.md +0 -47
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/index.js +0 -8
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/management.js +0 -123
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/pagination.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/tasks.js +0 -101
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/workers.js +0 -59
- django_cfg/apps/tasks/static/tasks/js/alpine/computed.js +0 -35
- django_cfg/apps/tasks/static/tasks/js/alpine/index.js +0 -148
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/index.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/overview.js +0 -37
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/queues.js +0 -27
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/tasks.js +0 -32
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/workers.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/state.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/formatters.js +0 -42
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/helpers.js +0 -68
- django_cfg/apps/tasks/static/tasks/js/dashboard-alpine.js +0 -725
- django_cfg/apps/tasks/tasks/__init__.py +0 -10
- django_cfg/apps/tasks/tasks/demo_tasks.py +0 -127
- django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -71
- django_cfg/apps/tasks/templates/tasks/components/overview_content.html +0 -94
- django_cfg/apps/tasks/templates/tasks/components/queues_content.html +0 -44
- django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -45
- django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -151
- django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +0 -61
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +0 -269
- django_cfg/apps/tasks/templates/tasks/components/workers_content.html +0 -60
- django_cfg/apps/tasks/templates/tasks/layout/base.html +0 -20
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +0 -168
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +0 -77
- django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +0 -86
- django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +0 -90
- django_cfg/apps/tasks/urls_admin.py +0 -15
- django_cfg/apps/tasks/utils/__init__.py +0 -1
- django_cfg/apps/tasks/utils/simulator.py +0 -353
- django_cfg/apps/tasks/views/api.py +0 -571
- django_cfg/apps/tasks/views/dashboard.py +0 -89
- django_cfg/management/commands/rundramatiq.py +0 -24
- django_cfg/management/commands/rundramatiq_simulator.py +0 -22
- django_cfg/management/commands/task_clear.py +0 -25
- django_cfg/management/commands/task_status.py +0 -24
- django_cfg/modules/django_client/system/__init__.py +0 -24
- django_cfg/modules/django_client/system/base_generator.py +0 -123
- django_cfg/modules/django_client/system/generate_mjs_clients.py +0 -176
- django_cfg/modules/django_client/system/mjs_generator.py +0 -219
- django_cfg/modules/django_client/system/schema_parser.py +0 -199
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +0 -87
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +0 -13
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +0 -166
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +0 -80
- django_cfg/modules/django_client/system/templates/types.js.j2 +0 -24
- django_cfg/modules/django_tasks/__init__.py +0 -29
- django_cfg/modules/django_tasks/dramatiq_setup.py +0 -20
- django_cfg/modules/django_tasks/factory.py +0 -127
- django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +0 -253
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +0 -436
- django_cfg/modules/django_tasks/management/commands/task_clear.py +0 -226
- django_cfg/modules/django_tasks/management/commands/task_status.py +0 -257
- django_cfg/modules/django_tasks/service.py +0 -281
- django_cfg/modules/django_tasks/settings.py +0 -107
- /django_cfg/{modules/django_tasks/management → apps/tasks/migrations}/__init__.py +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Serializers for Django CFG Tasks app.
|
|
3
|
-
|
|
4
|
-
Provides DRF serializers for task management API endpoints.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from rest_framework import serializers
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class QueueStatusSerializer(serializers.Serializer):
|
|
12
|
-
"""Serializer for queue status data."""
|
|
13
|
-
|
|
14
|
-
queues = serializers.DictField(
|
|
15
|
-
child=serializers.DictField(
|
|
16
|
-
child=serializers.IntegerField()
|
|
17
|
-
),
|
|
18
|
-
help_text="Queue information with pending/failed counts"
|
|
19
|
-
)
|
|
20
|
-
workers = serializers.IntegerField(help_text="Number of active workers")
|
|
21
|
-
redis_connected = serializers.BooleanField(help_text="Redis connection status")
|
|
22
|
-
timestamp = serializers.CharField(help_text="Current timestamp")
|
|
23
|
-
error = serializers.CharField(required=False, help_text="Error message if any")
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class TaskStatisticsSerializer(serializers.Serializer):
|
|
27
|
-
"""Serializer for task statistics data."""
|
|
28
|
-
|
|
29
|
-
statistics = serializers.DictField(
|
|
30
|
-
child=serializers.IntegerField(),
|
|
31
|
-
help_text="Task count statistics"
|
|
32
|
-
)
|
|
33
|
-
recent_tasks = serializers.ListField(
|
|
34
|
-
child=serializers.DictField(),
|
|
35
|
-
help_text="List of recent tasks"
|
|
36
|
-
)
|
|
37
|
-
timestamp = serializers.CharField(help_text="Current timestamp")
|
|
38
|
-
error = serializers.CharField(required=False, help_text="Error message if any")
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class WorkerActionSerializer(serializers.Serializer):
|
|
42
|
-
"""Serializer for worker management actions."""
|
|
43
|
-
|
|
44
|
-
action = serializers.ChoiceField(
|
|
45
|
-
choices=['start', 'stop', 'restart'],
|
|
46
|
-
help_text="Action to perform on workers"
|
|
47
|
-
)
|
|
48
|
-
processes = serializers.IntegerField(
|
|
49
|
-
default=1,
|
|
50
|
-
min_value=1,
|
|
51
|
-
max_value=10,
|
|
52
|
-
help_text="Number of worker processes"
|
|
53
|
-
)
|
|
54
|
-
threads = serializers.IntegerField(
|
|
55
|
-
default=2,
|
|
56
|
-
min_value=1,
|
|
57
|
-
max_value=20,
|
|
58
|
-
help_text="Number of threads per process"
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class QueueActionSerializer(serializers.Serializer):
|
|
63
|
-
"""Serializer for queue management actions."""
|
|
64
|
-
|
|
65
|
-
action = serializers.ChoiceField(
|
|
66
|
-
choices=['clear', 'clear_all', 'purge', 'purge_failed', 'flush'],
|
|
67
|
-
help_text="Action to perform on queues"
|
|
68
|
-
)
|
|
69
|
-
queue_names = serializers.ListField(
|
|
70
|
-
child=serializers.CharField(),
|
|
71
|
-
required=False,
|
|
72
|
-
help_text="Specific queues to target (empty = all queues)"
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class APIResponseSerializer(serializers.Serializer):
|
|
77
|
-
"""Standard API response serializer."""
|
|
78
|
-
|
|
79
|
-
success = serializers.BooleanField(help_text="Operation success status")
|
|
80
|
-
message = serializers.CharField(required=False, help_text="Success message")
|
|
81
|
-
error = serializers.CharField(required=False, help_text="Error message")
|
|
82
|
-
data = serializers.DictField(required=False, help_text="Response data")
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tasks Dashboard Alpine.js Styles
|
|
3
|
-
* Styles for Alpine.js-powered dashboard components
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/* Alpine.js cloak - prevents flash of unstyled content */
|
|
7
|
-
[x-cloak] {
|
|
8
|
-
display: none !important;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/* Smooth transitions for tab switching */
|
|
12
|
-
.tab-content > div {
|
|
13
|
-
animation: fadeIn 0.2s ease-in-out;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@keyframes fadeIn {
|
|
17
|
-
from {
|
|
18
|
-
opacity: 0;
|
|
19
|
-
transform: translateY(10px);
|
|
20
|
-
}
|
|
21
|
-
to {
|
|
22
|
-
opacity: 1;
|
|
23
|
-
transform: translateY(0);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/* Loading spinner animation */
|
|
28
|
-
@keyframes spin {
|
|
29
|
-
to {
|
|
30
|
-
transform: rotate(360deg);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.animate-spin {
|
|
35
|
-
animation: spin 1s linear infinite;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/* Tab button transitions */
|
|
39
|
-
button[class*="tab"] {
|
|
40
|
-
transition: all 0.2s ease-in-out;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* Badge animations */
|
|
44
|
-
.badge {
|
|
45
|
-
transition: all 0.2s ease-in-out;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* Hover effects for interactive elements */
|
|
49
|
-
button:hover:not(:disabled) {
|
|
50
|
-
transform: translateY(-1px);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
button:active:not(:disabled) {
|
|
54
|
-
transform: translateY(0);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
button:disabled {
|
|
58
|
-
opacity: 0.5;
|
|
59
|
-
cursor: not-allowed;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* Card hover effects */
|
|
63
|
-
.card-hover {
|
|
64
|
-
transition: all 0.3s ease-in-out;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.card-hover:hover {
|
|
68
|
-
transform: translateY(-2px);
|
|
69
|
-
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* Status badge colors */
|
|
73
|
-
.status-badge {
|
|
74
|
-
display: inline-flex;
|
|
75
|
-
align-items: center;
|
|
76
|
-
padding: 0.25rem 0.75rem;
|
|
77
|
-
border-radius: 9999px;
|
|
78
|
-
font-size: 0.75rem;
|
|
79
|
-
font-weight: 500;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.status-badge.pending {
|
|
83
|
-
background-color: #fef3c7;
|
|
84
|
-
color: #92400e;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.dark .status-badge.pending {
|
|
88
|
-
background-color: #78350f;
|
|
89
|
-
color: #fef3c7;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.status-badge.running {
|
|
93
|
-
background-color: #dbeafe;
|
|
94
|
-
color: #1e3a8a;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.dark .status-badge.running {
|
|
98
|
-
background-color: #1e3a8a;
|
|
99
|
-
color: #dbeafe;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.status-badge.completed {
|
|
103
|
-
background-color: #d1fae5;
|
|
104
|
-
color: #065f46;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.dark .status-badge.completed {
|
|
108
|
-
background-color: #065f46;
|
|
109
|
-
color: #d1fae5;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.status-badge.failed {
|
|
113
|
-
background-color: #fee2e2;
|
|
114
|
-
color: #991b1b;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.dark .status-badge.failed {
|
|
118
|
-
background-color: #991b1b;
|
|
119
|
-
color: #fee2e2;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/* Filter controls */
|
|
123
|
-
.task-filters-widget select,
|
|
124
|
-
.task-filters-widget input {
|
|
125
|
-
transition: all 0.2s ease-in-out;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.task-filters-widget select:focus,
|
|
129
|
-
.task-filters-widget input:focus {
|
|
130
|
-
outline: none;
|
|
131
|
-
ring: 2px;
|
|
132
|
-
ring-color: var(--primary-500);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/* Responsive adjustments */
|
|
136
|
-
@media (max-width: 768px) {
|
|
137
|
-
.tab-content > div {
|
|
138
|
-
padding: 1rem;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.task-filters-widget {
|
|
142
|
-
flex-direction: column;
|
|
143
|
-
align-items: stretch;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.task-filters-widget > * {
|
|
147
|
-
width: 100%;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/* Auto-refresh indicator */
|
|
152
|
-
.auto-refresh-indicator {
|
|
153
|
-
position: relative;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.auto-refresh-indicator::after {
|
|
157
|
-
content: '';
|
|
158
|
-
position: absolute;
|
|
159
|
-
top: 0;
|
|
160
|
-
right: 0;
|
|
161
|
-
width: 8px;
|
|
162
|
-
height: 8px;
|
|
163
|
-
background-color: #10b981;
|
|
164
|
-
border-radius: 50%;
|
|
165
|
-
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
@keyframes pulse {
|
|
169
|
-
0%, 100% {
|
|
170
|
-
opacity: 1;
|
|
171
|
-
}
|
|
172
|
-
50% {
|
|
173
|
-
opacity: 0.5;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/* Empty state styling */
|
|
178
|
-
.empty-state {
|
|
179
|
-
display: flex;
|
|
180
|
-
flex-direction: column;
|
|
181
|
-
align-items: center;
|
|
182
|
-
justify-content: center;
|
|
183
|
-
padding: 3rem 1rem;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.empty-state .material-icons {
|
|
187
|
-
font-size: 4rem;
|
|
188
|
-
opacity: 0.3;
|
|
189
|
-
margin-bottom: 1rem;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/* Task table enhancements */
|
|
193
|
-
.task-row {
|
|
194
|
-
transition: all 0.2s ease-in-out;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.task-row:hover {
|
|
198
|
-
background-color: rgba(0, 0, 0, 0.02);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.dark .task-row:hover {
|
|
202
|
-
background-color: rgba(255, 255, 255, 0.02);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/* Scrollbar styling */
|
|
206
|
-
.custom-scrollbar::-webkit-scrollbar {
|
|
207
|
-
width: 8px;
|
|
208
|
-
height: 8px;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.custom-scrollbar::-webkit-scrollbar-track {
|
|
212
|
-
background: #f1f1f1;
|
|
213
|
-
border-radius: 4px;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.dark .custom-scrollbar::-webkit-scrollbar-track {
|
|
217
|
-
background: #374151;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.custom-scrollbar::-webkit-scrollbar-thumb {
|
|
221
|
-
background: #888;
|
|
222
|
-
border-radius: 4px;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
226
|
-
background: #555;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.dark .custom-scrollbar::-webkit-scrollbar-thumb {
|
|
230
|
-
background: #6b7280;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.dark .custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
234
|
-
background: #9ca3af;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/* Modal styles */
|
|
238
|
-
.modal-backdrop {
|
|
239
|
-
backdrop-filter: blur(4px);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/* Modal animation */
|
|
243
|
-
@keyframes modalSlideIn {
|
|
244
|
-
from {
|
|
245
|
-
opacity: 0;
|
|
246
|
-
transform: translateY(-20px) scale(0.95);
|
|
247
|
-
}
|
|
248
|
-
to {
|
|
249
|
-
opacity: 1;
|
|
250
|
-
transform: translateY(0) scale(1);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/* Prevent body scroll when modal is open */
|
|
255
|
-
body.modal-open {
|
|
256
|
-
overflow: hidden;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/* Modal content scrollbar */
|
|
260
|
-
.modal-content::-webkit-scrollbar {
|
|
261
|
-
width: 6px;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
.modal-content::-webkit-scrollbar-track {
|
|
265
|
-
background: transparent;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.modal-content::-webkit-scrollbar-thumb {
|
|
269
|
-
background: #d1d5db;
|
|
270
|
-
border-radius: 3px;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.dark .modal-content::-webkit-scrollbar-thumb {
|
|
274
|
-
background: #4b5563;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/* Code/pre blocks in modal */
|
|
278
|
-
.modal-content pre {
|
|
279
|
-
max-height: 300px;
|
|
280
|
-
overflow-y: auto;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/* Modal overlay transition */
|
|
284
|
-
.modal-overlay-enter {
|
|
285
|
-
animation: fadeIn 0.2s ease-out;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.modal-overlay-leave {
|
|
289
|
-
animation: fadeOut 0.2s ease-in;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
@keyframes fadeOut {
|
|
293
|
-
from {
|
|
294
|
-
opacity: 1;
|
|
295
|
-
}
|
|
296
|
-
to {
|
|
297
|
-
opacity: 0;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/* Tasks Dashboard CSS */
|
|
2
|
-
|
|
3
|
-
/* Tab styling */
|
|
4
|
-
.tab-button.active {
|
|
5
|
-
border-color: rgb(59 130 246) !important;
|
|
6
|
-
color: rgb(59 130 246) !important;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.tab-panel {
|
|
10
|
-
display: none;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.tab-panel.active {
|
|
14
|
-
display: block;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/* Custom scrollbar */
|
|
18
|
-
.task-table-widget::-webkit-scrollbar {
|
|
19
|
-
height: 8px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.task-table-widget::-webkit-scrollbar-track {
|
|
23
|
-
background: #f1f5f9;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.task-table-widget::-webkit-scrollbar-thumb {
|
|
27
|
-
background: #cbd5e1;
|
|
28
|
-
border-radius: 4px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.task-table-widget::-webkit-scrollbar-thumb:hover {
|
|
32
|
-
background: #94a3b8;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* Dark mode scrollbar */
|
|
36
|
-
.dark .task-table-widget::-webkit-scrollbar-track {
|
|
37
|
-
background: #374151;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.dark .task-table-widget::-webkit-scrollbar-thumb {
|
|
41
|
-
background: #6b7280;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.dark .task-table-widget::-webkit-scrollbar-thumb:hover {
|
|
45
|
-
background: #9ca3af;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* Loading animation */
|
|
49
|
-
@keyframes spin {
|
|
50
|
-
to {
|
|
51
|
-
transform: rotate(360deg);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.animate-spin {
|
|
56
|
-
animation: spin 1s linear infinite;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Status indicators */
|
|
60
|
-
.status-indicator {
|
|
61
|
-
width: 8px;
|
|
62
|
-
height: 8px;
|
|
63
|
-
border-radius: 50%;
|
|
64
|
-
display: inline-block;
|
|
65
|
-
margin-right: 8px;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.status-pending {
|
|
69
|
-
background-color: #f59e0b;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.status-running {
|
|
73
|
-
background-color: #3b82f6;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.status-completed {
|
|
77
|
-
background-color: #10b981;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.status-failed {
|
|
81
|
-
background-color: #ef4444;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/* Progress bar */
|
|
85
|
-
.progress-bar {
|
|
86
|
-
transition: width 0.3s ease-in-out;
|
|
87
|
-
}
|
|
88
|
-
|
|
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;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/* Button focus states */
|
|
97
|
-
.btn-focus:focus {
|
|
98
|
-
outline: 2px solid rgb(59 130 246);
|
|
99
|
-
outline-offset: 2px;
|
|
100
|
-
}
|
|
101
|
-
|
|
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;
|
|
120
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Alpine.js Dashboard Modules
|
|
2
|
-
|
|
3
|
-
Модульная архитектура для Tasks Dashboard.
|
|
4
|
-
|
|
5
|
-
## Структура
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
alpine/
|
|
9
|
-
├── state.js # Начальное состояние компонента
|
|
10
|
-
├── loaders/ # Загрузка данных из API
|
|
11
|
-
│ ├── overview.js # Загрузка статистики
|
|
12
|
-
│ ├── queues.js # Загрузка очередей
|
|
13
|
-
│ ├── workers.js # Загрузка воркеров
|
|
14
|
-
│ ├── tasks.js # Загрузка задач
|
|
15
|
-
│ └── index.js # Экспорт всех loaders
|
|
16
|
-
├── actions/ # Действия пользователя
|
|
17
|
-
│ ├── management.js # Управление (clear, purge, simulate)
|
|
18
|
-
│ ├── workers.js # Управление воркерами
|
|
19
|
-
│ ├── tasks.js # Управление задачами
|
|
20
|
-
│ ├── pagination.js # Пагинация
|
|
21
|
-
│ └── index.js # Экспорт всех actions
|
|
22
|
-
├── utils/ # Утилиты
|
|
23
|
-
│ ├── formatters.js # Форматирование дат, времени
|
|
24
|
-
│ └── helpers.js # Вспомогательные функции
|
|
25
|
-
└── index.js # Главный файл, собирает все вместе
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Использование
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
// Вместо:
|
|
32
|
-
<script src="{% static 'tasks/js/dashboard-alpine.js' %}"></script>
|
|
33
|
-
|
|
34
|
-
// Использовать:
|
|
35
|
-
<script type="module" src="{% static 'tasks/js/alpine/index.js' %}"></script>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Статус
|
|
39
|
-
|
|
40
|
-
🚧 В РАЗРАБОТКЕ - пока используется монолитный `dashboard-alpine.js` (716 строк)
|
|
41
|
-
|
|
42
|
-
TODO:
|
|
43
|
-
- [ ] Создать все action модули
|
|
44
|
-
- [ ] Создать utils модули
|
|
45
|
-
- [ ] Протестировать модульную версию
|
|
46
|
-
- [ ] Переключить dashboard.html на модульную версию
|
|
47
|
-
- [ ] Удалить старый dashboard-alpine.js
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Management Actions - Clear, Purge, Simulate
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export async function clearAllTasks() {
|
|
6
|
-
if (!confirm('Are you sure you want to clear all tasks?')) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
this.loading = true;
|
|
12
|
-
this.showActionMessage('Clearing all tasks...', 'info');
|
|
13
|
-
await window.tasksAPI.tasksApiClearCreate({});
|
|
14
|
-
await this.loadTasks();
|
|
15
|
-
|
|
16
|
-
this.showActionMessage('All tasks cleared successfully', 'success');
|
|
17
|
-
|
|
18
|
-
if (window.showNotification) {
|
|
19
|
-
window.showNotification('All tasks cleared successfully', 'success');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
console.log('✅ All tasks cleared');
|
|
23
|
-
} catch (error) {
|
|
24
|
-
console.error('❌ Failed to clear tasks:', error);
|
|
25
|
-
this.showActionMessage('Failed to clear tasks: ' + error.message, 'error');
|
|
26
|
-
|
|
27
|
-
if (window.showNotification) {
|
|
28
|
-
window.showNotification('Failed to clear tasks: ' + error.message, 'error');
|
|
29
|
-
}
|
|
30
|
-
} finally {
|
|
31
|
-
this.loading = false;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function clearAllQueues() {
|
|
36
|
-
if (!confirm('Are you sure you want to clear all queues?')) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
this.loading = true;
|
|
42
|
-
this.showActionMessage('Clearing all queues...', 'info');
|
|
43
|
-
await window.tasksAPI.tasksApiClearQueuesCreate({});
|
|
44
|
-
await this.loadQueues();
|
|
45
|
-
|
|
46
|
-
this.showActionMessage('All queues cleared successfully', 'success');
|
|
47
|
-
|
|
48
|
-
if (window.showNotification) {
|
|
49
|
-
window.showNotification('All queues cleared successfully', 'success');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
console.log('✅ All queues cleared');
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error('❌ Failed to clear queues:', error);
|
|
55
|
-
this.showActionMessage('Failed to clear queues: ' + error.message, 'error');
|
|
56
|
-
|
|
57
|
-
if (window.showNotification) {
|
|
58
|
-
window.showNotification('Failed to clear queues: ' + error.message, 'error');
|
|
59
|
-
}
|
|
60
|
-
} finally {
|
|
61
|
-
this.loading = false;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function purgeFailedTasks() {
|
|
66
|
-
if (!confirm('Are you sure you want to purge all failed tasks?')) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
this.loading = true;
|
|
72
|
-
this.showActionMessage('Purging failed tasks...', 'info');
|
|
73
|
-
await window.tasksAPI.tasksApiPurgeFailedCreate({});
|
|
74
|
-
await this.loadTasks();
|
|
75
|
-
|
|
76
|
-
this.showActionMessage('Failed tasks purged successfully', 'success');
|
|
77
|
-
|
|
78
|
-
if (window.showNotification) {
|
|
79
|
-
window.showNotification('Failed tasks purged successfully', 'success');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('✅ Failed tasks purged');
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error('❌ Failed to purge failed tasks:', error);
|
|
85
|
-
this.showActionMessage('Failed to purge failed tasks: ' + error.message, 'error');
|
|
86
|
-
|
|
87
|
-
if (window.showNotification) {
|
|
88
|
-
window.showNotification('Failed to purge failed tasks: ' + error.message, 'error');
|
|
89
|
-
}
|
|
90
|
-
} finally {
|
|
91
|
-
this.loading = false;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function simulateTasks(count = 5) {
|
|
96
|
-
try {
|
|
97
|
-
this.loading = true;
|
|
98
|
-
this.showActionMessage(`Simulating ${count} tasks...`, 'info');
|
|
99
|
-
await window.tasksAPI.tasksApiSimulateCreate({
|
|
100
|
-
count: count,
|
|
101
|
-
queue: 'default',
|
|
102
|
-
task_type: 'test'
|
|
103
|
-
});
|
|
104
|
-
await this.loadTasks();
|
|
105
|
-
|
|
106
|
-
this.showActionMessage(`Simulated ${count} tasks successfully`, 'success');
|
|
107
|
-
|
|
108
|
-
if (window.showNotification) {
|
|
109
|
-
window.showNotification(`Simulated ${count} tasks successfully`, 'success');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
console.log(`✅ Simulated ${count} tasks`);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.error('❌ Failed to simulate tasks:', error);
|
|
115
|
-
this.showActionMessage('Failed to simulate tasks: ' + error.message, 'error');
|
|
116
|
-
|
|
117
|
-
if (window.showNotification) {
|
|
118
|
-
window.showNotification('Failed to simulate tasks: ' + error.message, 'error');
|
|
119
|
-
}
|
|
120
|
-
} finally {
|
|
121
|
-
this.loading = false;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pagination Actions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export function nextPage() {
|
|
6
|
-
if (this.pagination.has_next) {
|
|
7
|
-
this.loadTasks(this.pagination.page + 1);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function previousPage() {
|
|
12
|
-
if (this.pagination.has_previous) {
|
|
13
|
-
this.loadTasks(this.pagination.page - 1);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function goToPage(page) {
|
|
18
|
-
if (page >= 1 && page <= this.pagination.total_pages) {
|
|
19
|
-
this.loadTasks(page);
|
|
20
|
-
}
|
|
21
|
-
}
|