@zintrust/workers 0.1.29 → 0.1.30

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 (111) hide show
  1. package/README.md +16 -1
  2. package/dist/AnomalyDetection.d.ts +4 -0
  3. package/dist/AnomalyDetection.js +8 -0
  4. package/dist/BroadcastWorker.d.ts +2 -0
  5. package/dist/CanaryController.js +49 -5
  6. package/dist/ChaosEngineering.js +13 -0
  7. package/dist/ClusterLock.js +21 -10
  8. package/dist/DeadLetterQueue.js +12 -8
  9. package/dist/MultiQueueWorker.d.ts +1 -1
  10. package/dist/MultiQueueWorker.js +12 -7
  11. package/dist/NotificationWorker.d.ts +2 -0
  12. package/dist/PriorityQueue.d.ts +2 -2
  13. package/dist/PriorityQueue.js +20 -21
  14. package/dist/ResourceMonitor.js +65 -38
  15. package/dist/WorkerFactory.d.ts +23 -3
  16. package/dist/WorkerFactory.js +420 -40
  17. package/dist/WorkerInit.js +8 -3
  18. package/dist/WorkerMetrics.d.ts +2 -1
  19. package/dist/WorkerMetrics.js +152 -93
  20. package/dist/WorkerRegistry.d.ts +6 -0
  21. package/dist/WorkerRegistry.js +70 -1
  22. package/dist/WorkerShutdown.d.ts +21 -0
  23. package/dist/WorkerShutdown.js +82 -9
  24. package/dist/WorkerShutdownDurableObject.d.ts +12 -0
  25. package/dist/WorkerShutdownDurableObject.js +41 -0
  26. package/dist/build-manifest.json +171 -99
  27. package/dist/createQueueWorker.d.ts +2 -0
  28. package/dist/createQueueWorker.js +42 -27
  29. package/dist/dashboard/types.d.ts +5 -0
  30. package/dist/dashboard/workers-api.js +136 -43
  31. package/dist/http/WorkerApiController.js +1 -0
  32. package/dist/http/WorkerController.js +133 -85
  33. package/dist/http/WorkerMonitoringService.d.ts +11 -0
  34. package/dist/http/WorkerMonitoringService.js +62 -0
  35. package/dist/http/middleware/CustomValidation.js +1 -1
  36. package/dist/http/middleware/EditWorkerValidation.d.ts +1 -1
  37. package/dist/http/middleware/EditWorkerValidation.js +7 -6
  38. package/dist/http/middleware/ProcessorPathSanitizer.js +101 -35
  39. package/dist/http/middleware/WorkerValidationChain.js +1 -0
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js +1 -0
  42. package/dist/routes/workers.js +48 -6
  43. package/dist/storage/WorkerStore.d.ts +4 -1
  44. package/dist/storage/WorkerStore.js +55 -7
  45. package/dist/telemetry/api/TelemetryAPI.d.ts +46 -0
  46. package/dist/telemetry/api/TelemetryAPI.js +219 -0
  47. package/dist/telemetry/api/TelemetryMonitoringService.d.ts +17 -0
  48. package/dist/telemetry/api/TelemetryMonitoringService.js +113 -0
  49. package/dist/telemetry/components/AlertPanel.d.ts +1 -0
  50. package/dist/telemetry/components/AlertPanel.js +13 -0
  51. package/dist/telemetry/components/CostTracking.d.ts +1 -0
  52. package/dist/telemetry/components/CostTracking.js +14 -0
  53. package/dist/telemetry/components/ResourceUsageChart.d.ts +1 -0
  54. package/dist/telemetry/components/ResourceUsageChart.js +11 -0
  55. package/dist/telemetry/components/WorkerHealthChart.d.ts +1 -0
  56. package/dist/telemetry/components/WorkerHealthChart.js +11 -0
  57. package/dist/telemetry/index.d.ts +15 -0
  58. package/dist/telemetry/index.js +60 -0
  59. package/dist/telemetry/routes/dashboard.d.ts +6 -0
  60. package/dist/telemetry/routes/dashboard.js +608 -0
  61. package/dist/ui/router/EmbeddedAssets.d.ts +4 -0
  62. package/dist/ui/router/EmbeddedAssets.js +13 -0
  63. package/dist/ui/router/ui.js +100 -4
  64. package/package.json +10 -6
  65. package/src/AnomalyDetection.ts +9 -0
  66. package/src/CanaryController.ts +41 -5
  67. package/src/ChaosEngineering.ts +14 -0
  68. package/src/ClusterLock.ts +22 -9
  69. package/src/DeadLetterQueue.ts +13 -8
  70. package/src/MultiQueueWorker.ts +15 -8
  71. package/src/PriorityQueue.ts +21 -22
  72. package/src/ResourceMonitor.ts +72 -40
  73. package/src/WorkerFactory.ts +545 -49
  74. package/src/WorkerInit.ts +8 -3
  75. package/src/WorkerMetrics.ts +183 -105
  76. package/src/WorkerRegistry.ts +80 -1
  77. package/src/WorkerShutdown.ts +115 -9
  78. package/src/WorkerShutdownDurableObject.ts +64 -0
  79. package/src/createQueueWorker.ts +73 -30
  80. package/src/dashboard/types.ts +5 -0
  81. package/src/dashboard/workers-api.ts +165 -52
  82. package/src/http/WorkerApiController.ts +1 -0
  83. package/src/http/WorkerController.ts +167 -90
  84. package/src/http/WorkerMonitoringService.ts +77 -0
  85. package/src/http/middleware/CustomValidation.ts +1 -1
  86. package/src/http/middleware/EditWorkerValidation.ts +7 -6
  87. package/src/http/middleware/ProcessorPathSanitizer.ts +123 -36
  88. package/src/http/middleware/WorkerValidationChain.ts +1 -0
  89. package/src/index.ts +6 -1
  90. package/src/routes/workers.ts +66 -9
  91. package/src/storage/WorkerStore.ts +59 -9
  92. package/src/telemetry/api/TelemetryAPI.ts +292 -0
  93. package/src/telemetry/api/TelemetryMonitoringService.ts +149 -0
  94. package/src/telemetry/components/AlertPanel.ts +13 -0
  95. package/src/telemetry/components/CostTracking.ts +14 -0
  96. package/src/telemetry/components/ResourceUsageChart.ts +11 -0
  97. package/src/telemetry/components/WorkerHealthChart.ts +11 -0
  98. package/src/telemetry/index.ts +121 -0
  99. package/src/telemetry/public/assets/zintrust-logo.svg +15 -0
  100. package/src/telemetry/routes/dashboard.ts +638 -0
  101. package/src/telemetry/styles/tailwind.css +1 -0
  102. package/src/telemetry/styles/zintrust-theme.css +8 -0
  103. package/src/ui/router/EmbeddedAssets.ts +13 -0
  104. package/src/ui/router/ui.ts +112 -5
  105. package/src/ui/workers/index.html +2 -2
  106. package/src/ui/workers/main.js +232 -61
  107. package/src/ui/workers/zintrust.svg +30 -0
  108. package/dist/dashboard/workers-dashboard-ui.d.ts +0 -3
  109. package/dist/dashboard/workers-dashboard-ui.js +0 -1026
  110. package/dist/dashboard/workers-dashboard.d.ts +0 -4
  111. package/dist/dashboard/workers-dashboard.js +0 -904
@@ -1,1026 +0,0 @@
1
- const getRootVariables = () => `
2
- :root {
3
- --bg: #0b1220;
4
- --card: #0f172a;
5
- --border: #1e293b;
6
- --text: #e2e8f0;
7
- --muted: #94a3b8;
8
- --accent: #38bdf8;
9
- --accent-hover: #0ea5e9;
10
-
11
- /* Modern Utilities */
12
- --surface-hover: #1e293b;
13
- --surface-active: #334155;
14
- --input-bg: #0f172a;
15
-
16
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
17
- --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
18
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
19
-
20
- /* Brand Colors */
21
- --primary: #0ea5e9;
22
- --success: #22c55e;
23
- --warning: #f59e0b;
24
- --danger: #ef4444;
25
- --info: #3b82f6;
26
- }
27
-
28
- html[data-theme='light'] {
29
- --bg: #f1f5f9;
30
- --card: #ffffff;
31
- --border: #e2e8f0;
32
- --text: #334155;
33
- --muted: #64748b;
34
-
35
- --surface-hover: #f8fafc;
36
- --surface-active: #e2e8f0;
37
- --input-bg: #ffffff;
38
-
39
- --shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
40
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.05), 0 4px 6px -4px rgb(0 0 0 / 0.02);
41
- }`;
42
- const getResetAndBaseStyles = () => `
43
- * {
44
- margin: 0;
45
- padding: 0;
46
- box-sizing: border-box;
47
- }
48
-
49
- body {
50
- font-family:
51
- 'Inter',
52
- system-ui,
53
- -apple-system,
54
- sans-serif;
55
- background: var(--bg);
56
- color: var(--text);
57
- line-height: 1.5;
58
- transition:
59
- background-color 0.3s ease,
60
- color 0.3s ease;
61
- -webkit-font-smoothing: antialiased;
62
- }
63
-
64
- .container {
65
- max-width: 1400px;
66
- margin: 0 auto;
67
- padding: 40px 24px;
68
- }
69
-
70
- /* Transitions */
71
- .card,
72
- .header,
73
- .table-container,
74
- .btn,
75
- .action-btn,
76
- input,
77
- select {
78
- transition: all 0.2s ease-in-out;
79
- }`;
80
- const getHeaderStyles = () => `
81
- /* Header Styles */
82
- .header {
83
- background: var(--card);
84
- padding: 24px 32px;
85
- border: 1px solid var(--border);
86
- border-radius: 16px;
87
- margin-bottom: 32px;
88
- box-shadow: var(--shadow);
89
- }
90
-
91
- .header-top {
92
- display: flex;
93
- justify-content: space-between;
94
- align-items: center;
95
- margin-bottom: 24px;
96
- }
97
-
98
- .header h1 {
99
- font-size: 24px;
100
- font-weight: 700;
101
- letter-spacing: -0.025em;
102
- color: var(--text);
103
- }
104
-
105
- .header-actions {
106
- display: flex;
107
- gap: 12px;
108
- align-items: center;
109
- }
110
-
111
- /* Navigation Bar */
112
- .nav-bar {
113
- padding-bottom: 24px;
114
- border-bottom: 1px solid var(--border);
115
- margin-bottom: 24px;
116
- }
117
-
118
- .nav-links {
119
- display: flex;
120
- gap: 32px;
121
- align-items: center;
122
- }
123
-
124
- .nav-link {
125
- color: var(--muted);
126
- text-decoration: none;
127
- font-size: 14px;
128
- font-weight: 500;
129
- padding: 8px 12px;
130
- border-radius: 8px;
131
- transition: all 0.2s ease;
132
- position: relative;
133
- }
134
-
135
- .nav-link:hover {
136
- color: var(--text);
137
- background: var(--surface-hover);
138
- }
139
-
140
- .nav-link.active {
141
- color: var(--primary);
142
- background: rgba(14, 165, 233, 0.1);
143
- }
144
-
145
- .nav-link.active::after {
146
- content: '';
147
- position: absolute;
148
- bottom: -25px;
149
- left: 50%;
150
- transform: translateX(-50%);
151
- width: 40px;
152
- height: 3px;
153
- background: var(--primary);
154
- border-radius: 2px;
155
- }
156
- `;
157
- const getButtonsAndInputsStyles = () => `
158
- /* Buttons & Inputs */
159
- .btn {
160
- display: inline-flex;
161
- align-items: center;
162
- gap: 8px;
163
- padding: 10px 16px;
164
- border-radius: 8px;
165
- font-size: 14px;
166
- font-weight: 500;
167
- cursor: pointer;
168
- border: 1px solid var(--border);
169
- background: var(--card);
170
- color: var(--text);
171
- box-shadow: var(--shadow-sm);
172
- height: 40px;
173
- }
174
-
175
- .btn:hover {
176
- background: var(--surface-hover);
177
- transform: translateY(-1px);
178
- border-color: var(--muted);
179
- }
180
-
181
- .btn-primary {
182
- background: var(--primary);
183
- color: white;
184
- border: 1px solid var(--primary);
185
- }
186
-
187
- .btn-primary:hover {
188
- background: #0284c7; /* Darker blue */
189
- transform: translateY(-1px);
190
- box-shadow: 0 4px 12px rgba(14, 165, 233, 0.25);
191
- color: white;
192
- }
193
-
194
- .theme-toggle {
195
- background: transparent;
196
- color: var(--text);
197
- border: 1px solid var(--border);
198
- padding: 8px 12px;
199
- border-radius: 8px;
200
- font-size: 13px;
201
- font-weight: 500;
202
- cursor: pointer;
203
- display: flex;
204
- align-items: center;
205
- gap: 8px;
206
- height: 40px;
207
- }
208
-
209
- .theme-toggle:hover {
210
- background: var(--surface-hover);
211
- }`;
212
- const getFilterStyles = () => `
213
- /* Filters */
214
- .filters-bar {
215
- display: flex;
216
- gap: 16px;
217
- align-items: center;
218
- flex-wrap: wrap;
219
- padding-top: 24px;
220
- border-top: 1px solid var(--border);
221
- }
222
-
223
- .filter-group {
224
- display: flex;
225
- align-items: center;
226
- gap: 10px;
227
- }
228
-
229
- .filter-group label {
230
- font-size: 13px;
231
- font-weight: 600;
232
- color: var(--muted);
233
- text-transform: uppercase;
234
- letter-spacing: 0.05em;
235
- }
236
-
237
- .filter-group select,
238
- .filter-group input {
239
- padding: 8px 12px;
240
- border: 1px solid var(--border);
241
- border-radius: 8px;
242
- font-size: 14px;
243
- background: var(--input-bg);
244
- color: var(--text);
245
- min-width: 140px;
246
- height: 38px;
247
- }
248
-
249
- .filter-group select:focus,
250
- .filter-group input:focus {
251
- outline: none;
252
- border-color: var(--primary);
253
- box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.1);
254
- }
255
-
256
- .search-box {
257
- position: relative;
258
- display: flex;
259
- align-items: center;
260
- width: 280px;
261
- }
262
-
263
- .search-box .search-icon {
264
- position: absolute;
265
- left: 12px;
266
- width: 16px;
267
- height: 16px;
268
- color: var(--muted);
269
- stroke: currentColor;
270
- stroke-width: 2;
271
- fill: none;
272
- pointer-events: none;
273
- }
274
-
275
- .search-box input {
276
- width: 100%;
277
- height: 40px;
278
- padding: 8px 12px 8px 36px;
279
- background: var(--input-bg);
280
- border: 1px solid var(--border);
281
- border-radius: 8px;
282
- color: var(--text);
283
- font-size: 14px;
284
- transition: all 0.2s ease;
285
- }
286
-
287
- .search-box input:focus {
288
- outline: none;
289
- border-color: var(--primary);
290
- box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.1);
291
- }
292
- `;
293
- const getSummaryStyles = () => `
294
- /* Summary Bar */
295
- .summary-bar {
296
- margin: 16px 0 0;
297
- padding: 16px 20px;
298
- background: var(--card);
299
- border: 1px solid var(--border);
300
- border-radius: 12px;
301
- display: flex;
302
- flex-wrap: wrap;
303
- gap: 16px 24px;
304
- align-items: center;
305
- box-shadow: var(--shadow-sm);
306
- }
307
-
308
- .summary-item {
309
- display: flex;
310
- flex-direction: column;
311
- gap: 4px;
312
- min-width: 120px;
313
- }
314
-
315
- .summary-label {
316
- font-size: 12px;
317
- text-transform: uppercase;
318
- letter-spacing: 0.05em;
319
- color: var(--muted);
320
- font-weight: 600;
321
- }
322
-
323
- .summary-value {
324
- font-size: 16px;
325
- font-weight: 700;
326
- color: var(--text);
327
- }
328
-
329
- .drivers-list {
330
- display: flex;
331
- gap: 8px;
332
- flex-wrap: wrap;
333
- align-items: center;
334
- }
335
-
336
- .driver-chip {
337
- font-size: 12px;
338
- font-weight: 600;
339
- color: var(--text);
340
- background: var(--surface-hover);
341
- border: 1px solid var(--border);
342
- padding: 4px 10px;
343
- border-radius: 9999px;
344
- }
345
- `;
346
- const getTableStyles = () => `
347
- /* Table Container */
348
- .table-container {
349
- background: var(--card);
350
- border: 1px solid var(--border);
351
- border-radius: 16px;
352
- overflow: hidden;
353
- box-shadow: var(--shadow-lg);
354
- }
355
-
356
- table {
357
- width: 100%;
358
- border-collapse: separate;
359
- border-spacing: 0;
360
- }
361
-
362
- th {
363
- background: var(--surface-hover);
364
- padding: 16px 24px;
365
- text-align: left;
366
- font-weight: 600;
367
- font-size: 12px;
368
- color: var(--muted);
369
- text-transform: uppercase;
370
- letter-spacing: 0.05em;
371
- border-bottom: 1px solid var(--border);
372
- white-space: nowrap;
373
- }
374
-
375
- td {
376
- padding: 20px 24px;
377
- border-bottom: 1px solid var(--border);
378
- font-size: 14px;
379
- vertical-align: middle;
380
- }
381
-
382
- tbody tr {
383
- transition: background-color 0.15s ease;
384
- }
385
-
386
- tbody tr:hover {
387
- background: var(--surface-hover);
388
- }
389
-
390
- tbody tr:last-child td {
391
- border-bottom: none;
392
- }
393
-
394
- /* Worker Identity */
395
- .worker-name {
396
- font-weight: 600;
397
- color: var(--text);
398
- font-size: 15px;
399
- margin-bottom: 4px;
400
- }
401
-
402
- .worker-queue {
403
- font-size: 12px;
404
- color: var(--muted);
405
- font-family: monospace;
406
- background: var(--surface-active);
407
- padding: 2px 6px;
408
- border-radius: 4px;
409
- display: inline-block;
410
- }`;
411
- const getStatusBadgeStyles = () => `
412
- /* Typography & Badges */
413
- .status-badge {
414
- display: inline-flex;
415
- align-items: center;
416
- gap: 8px;
417
- padding: 6px 10px;
418
- border-radius: 9999px; /* Pill shape */
419
- font-size: 12px;
420
- font-weight: 600;
421
- width: fit-content;
422
- }
423
-
424
- .status-running {
425
- background: rgba(34, 197, 94, 0.1);
426
- color: var(--success);
427
- border: 1px solid rgba(34, 197, 94, 0.2);
428
- }
429
-
430
- .status-stopped {
431
- background: rgba(239, 68, 68, 0.1);
432
- color: var(--danger);
433
- border: 1px solid rgba(239, 68, 68, 0.2);
434
- }
435
-
436
- .status-error {
437
- background: rgba(245, 158, 11, 0.1);
438
- color: var(--warning);
439
- border: 1px solid rgba(245, 158, 11, 0.2);
440
- }
441
-
442
- .status-dot {
443
- width: 8px;
444
- height: 8px;
445
- border-radius: 50%;
446
- box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1);
447
- }
448
-
449
- .status-running .status-dot {
450
- background: var(--success);
451
- }
452
- .status-stopped .status-dot {
453
- background: var(--danger);
454
- }
455
- .status-error .status-dot {
456
- background: var(--warning);
457
- }
458
-
459
- .health-indicator {
460
- display: flex;
461
- align-items: center;
462
- }
463
-
464
- .health-dot {
465
- display: inline-block;
466
- width: 8px;
467
- height: 8px;
468
- border-radius: 50%;
469
- margin-right: 6px;
470
- }
471
- .health-healthy { background: var(--success); }
472
- .health-unhealthy { background: var(--danger); }
473
- .health-degraded { background: var(--warning); }
474
- .health-warning { background: var(--warning); }
475
- .health-unknown { background: var(--muted); }
476
-
477
- /* Driver & Version */
478
- .driver-badge {
479
- background: var(--surface-hover);
480
- color: var(--text);
481
- padding: 4px 8px;
482
- border-radius: 6px;
483
- font-size: 12px;
484
- font-weight: 600;
485
- border: 1px solid var(--border);
486
- }
487
-
488
- .version-badge {
489
- font-family: monospace;
490
- color: var(--muted);
491
- font-size: 12px;
492
- }`;
493
- const getPerformanceIconsStyles = () => `
494
- /* Performance Icons */
495
- .performance-icons {
496
- display: flex;
497
- gap: 16px;
498
- }
499
-
500
- .perf-icon {
501
- display: flex;
502
- align-items: center;
503
- gap: 6px;
504
- font-size: 13px;
505
- font-weight: 500;
506
- }
507
-
508
- .perf-icon svg {
509
- width: 16px;
510
- height: 16px;
511
- stroke-width: 2.5;
512
- }
513
-
514
- .perf-icon.processed {
515
- color: var(--success);
516
- }
517
- .perf-icon.time {
518
- color: var(--primary);
519
- }
520
- .perf-icon.memory {
521
- color: #8b5cf6;
522
- }
523
- `;
524
- const getActionButtonsStyles = () => `
525
- /* Action Buttons with SVGs */
526
- .actions-cell {
527
- display: flex;
528
- gap: 8px;
529
- }
530
-
531
- .action-btn {
532
- width: 34px;
533
- height: 34px;
534
- padding: 0;
535
- display: flex;
536
- align-items: center;
537
- justify-content: center;
538
- border: 1px solid var(--border);
539
- border-radius: 8px;
540
- background: var(--card);
541
- color: var(--muted);
542
- transition: all 0.2s;
543
- }
544
-
545
- .action-btn:hover {
546
- background: var(--surface-hover);
547
- color: var(--text);
548
- border-color: var(--muted);
549
- transform: translateY(-1px);
550
- box-shadow: var(--shadow-sm);
551
- }
552
-
553
- .action-btn svg {
554
- width: 16px;
555
- height: 16px;
556
- stroke: currentColor;
557
- stroke-width: 2;
558
- fill: none;
559
- stroke-linecap: round;
560
- stroke-linejoin: round;
561
- }
562
- `;
563
- const getActionButtonHoverStyles = () => `
564
- /* Specific Action Colors On Hover */
565
- .action-btn.start:hover {
566
- color: var(--success);
567
- border-color: var(--success);
568
- background: rgba(34, 197, 94, 0.1);
569
- }
570
- .action-btn.stop:hover {
571
- color: var(--danger);
572
- border-color: var(--danger);
573
- background: rgba(239, 68, 68, 0.1);
574
- }
575
- .action-btn.restart:hover {
576
- color: var(--warning);
577
- border-color: var(--warning);
578
- background: rgba(245, 158, 11, 0.1);
579
- }
580
- .action-btn.debug:hover {
581
- color: var(--info);
582
- border-color: var(--info);
583
- background: rgba(59, 130, 246, 0.1);
584
- }
585
- .action-btn.delete:hover {
586
- color: var(--danger);
587
- border-color: var(--danger);
588
- background: rgba(239, 68, 68, 0.1);
589
- }
590
- `;
591
- const getPerformanceAndActionStyles = () => `
592
- ${getPerformanceIconsStyles()}
593
- ${getActionButtonsStyles()}
594
- ${getActionButtonHoverStyles()}
595
- `;
596
- const getExpandedRowStyles = () => `
597
- /* Expandable Rows */
598
- .expandable-row {
599
- display: none;
600
- }
601
-
602
- .expandable-row.open {
603
- display: table-row;
604
- }
605
-
606
- .expander {
607
- cursor: pointer;
608
- }
609
-
610
- .details-content {
611
- padding: 32px;
612
- background: var(--surface-hover);
613
- border-top: 1px solid var(--border);
614
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.02);
615
- }
616
-
617
- .details-grid {
618
- display: grid;
619
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
620
- gap: 24px;
621
- }
622
-
623
- .detail-section {
624
- background: var(--card);
625
- padding: 20px;
626
- border-radius: 12px;
627
- border: 1px solid var(--border);
628
- box-shadow: var(--shadow-sm);
629
- }
630
-
631
- .detail-section h4 {
632
- font-size: 13px;
633
- text-transform: uppercase;
634
- letter-spacing: 0.05em;
635
- color: var(--muted);
636
- margin-bottom: 16px;
637
- font-weight: 700;
638
- display: flex;
639
- align-items: center;
640
- gap: 8px;
641
- }
642
-
643
- .detail-item {
644
- display: flex;
645
- justify-content: space-between;
646
- align-items: center;
647
- padding: 8px 0;
648
- font-size: 13px;
649
- border-bottom: 1px solid var(--border);
650
- }
651
-
652
- .detail-item:last-child {
653
- border-bottom: none;
654
- }
655
-
656
- .detail-item span:first-child {
657
- color: var(--muted);
658
- font-weight: 500;
659
- }
660
-
661
- .detail-item span:last-child {
662
- color: var(--text);
663
- font-weight: 600;
664
- }
665
- `;
666
- const getLogoAndIconStyles = () => `
667
- /* Logo */
668
- .logo-frame {
669
- width: 40px;
670
- height: 40px;
671
- border-radius: 10px;
672
- background: linear-gradient(
673
- 135deg,
674
- rgba(14, 165, 233, 0.1) 0%,
675
- rgba(56, 189, 248, 0.2) 100%
676
- );
677
- border: 1px solid rgba(14, 165, 233, 0.3);
678
- display: flex;
679
- align-items: center;
680
- justify-content: center;
681
- }
682
-
683
- .logo-img {
684
- width: 26px;
685
- height: 26px;
686
- display: block;
687
- }
688
-
689
- .logo {
690
- width: 34px;
691
- height: 34px;
692
- border-radius: 9px;
693
- border: 1px solid rgba(14, 165, 233, 0.35);
694
- background: linear-gradient(180deg, rgba(14, 165, 233, 0.25), rgba(2, 132, 199, 0.12));
695
- }
696
-
697
- /* Icons Generic */
698
- .icon {
699
- width: 18px;
700
- height: 18px;
701
- fill: none;
702
- stroke: currentColor;
703
- stroke-width: 2;
704
- stroke-linecap: round;
705
- stroke-linejoin: round;
706
- }`;
707
- const getPageSizeSelectorStyles = () => `
708
- /* Page Size Selector */
709
- .pagination-controls {
710
- display: flex;
711
- align-items: center;
712
- gap: 8px;
713
- flex-wrap: wrap;
714
- }
715
-
716
- .page-size-selector {
717
- display: flex;
718
- align-items: center;
719
- gap: 8px;
720
- margin-left: 16px;
721
- padding-left: 16px;
722
- border-left: 1px solid var(--border);
723
- }
724
-
725
- .page-size-selector label {
726
- font-size: 13px;
727
- color: var(--muted);
728
- font-weight: 500;
729
- }
730
-
731
- .page-size-selector select {
732
- padding: 0 32px 0 12px;
733
- height: 38px;
734
- border: 1px solid var(--border);
735
- border-radius: 10px;
736
- background-color: var(--card);
737
- color: var(--text);
738
- font-size: 13px;
739
- font-weight: 500;
740
- cursor: pointer;
741
- appearance: none;
742
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2394a3b8'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
743
- background-repeat: no-repeat;
744
- background-position: right 8px center;
745
- background-size: 16px;
746
- transition: all 0.2s;
747
- }
748
-
749
- .page-size-selector select:hover {
750
- background-color: var(--surface-hover);
751
- border-color: var(--muted);
752
- }
753
-
754
- .page-size-selector select:focus {
755
- outline: none;
756
- border-color: var(--primary);
757
- box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
758
- }
759
- `;
760
- const getPaginationStyles = () => `
761
- /* Pagination */
762
- .pagination {
763
- margin-top: 20px;
764
- display: flex;
765
- justify-content: space-between;
766
- align-items: center;
767
- padding: 16px 24px;
768
- background: var(--card);
769
- border: 1px solid var(--border);
770
- border-radius: 12px;
771
- box-shadow: var(--shadow);
772
- }
773
-
774
- .page-btn {
775
- width: 38px;
776
- height: 38px;
777
- display: inline-flex;
778
- align-items: center;
779
- justify-content: center;
780
- padding: 0;
781
- border: 1px solid var(--border);
782
- border-radius: 10px;
783
- background: var(--card);
784
- color: var(--muted);
785
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
786
- font-size: 14px;
787
- font-weight: 500;
788
- cursor: pointer;
789
- }
790
-
791
- .page-btn:hover:not(:disabled) {
792
- background: var(--surface-hover);
793
- color: var(--text);
794
- border-color: var(--border);
795
- transform: translateY(-1px);
796
- box-shadow: var(--shadow-sm);
797
- }
798
-
799
- .page-btn.active {
800
- background: var(--primary);
801
- color: white;
802
- border-color: var(--primary);
803
- box-shadow: 0 4px 6px -1px rgba(14, 165, 233, 0.3);
804
- }
805
-
806
- .page-btn:disabled {
807
- opacity: 0.4;
808
- cursor: not-allowed;
809
- background: var(--bg);
810
- }
811
-
812
- .page-btn svg {
813
- width: 18px;
814
- height: 18px;
815
- stroke-width: 2px;
816
- }
817
-
818
- ${getPageSizeSelectorStyles()}
819
- `;
820
- const getToggleStartStyles = () => `
821
- /* Toggle Switch */
822
- .auto-start-toggle,
823
- .auto-switch-toggle {
824
- position: relative;
825
- display: inline-block;
826
- width: 44px;
827
- height: 24px;
828
- cursor: pointer;
829
- }
830
-
831
- .auto-start-toggle input,
832
- .auto-switch-toggle input {
833
- opacity: 0;
834
- width: 0;
835
- height: 0;
836
- }
837
-
838
- .toggle-slider {
839
- position: absolute;
840
- cursor: pointer;
841
- top: 0;
842
- left: 0;
843
- right: 0;
844
- bottom: 0;
845
- background-color: var(--surface-active);
846
- border: 1px solid var(--border);
847
- transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
848
- border-radius: 34px;
849
- }
850
-
851
- .toggle-slider:before {
852
- position: absolute;
853
- content: '';
854
- height: 18px;
855
- width: 18px;
856
- left: 2px;
857
- bottom: 2px;
858
- background-color: var(--muted);
859
- transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
860
- border-radius: 50%;
861
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
862
- }
863
-
864
- input:checked + .toggle-slider {
865
- background-color: rgba(14, 165, 233, 0.15); /* Primary transparent */
866
- border-color: var(--primary);
867
- }
868
-
869
- input:checked + .toggle-slider:before {
870
- transform: translateX(20px);
871
- background-color: var(--primary);
872
- }
873
-
874
- /* Hover generic for toggles */
875
- .auto-start-toggle:hover .toggle-slider,
876
- .auto-switch-toggle:hover .toggle-slider {
877
- border-color: var(--muted);
878
- }`;
879
- const getTabletResponsiveStyles = () => `
880
- /* Responsive Design - Tablet */
881
- @media (max-width: 1024px) {
882
- .filters-bar {
883
- gap: 12px;
884
- }
885
-
886
- .search-input {
887
- width: 200px;
888
- }
889
-
890
- .header-top {
891
- flex-direction: column;
892
- align-items: flex-start;
893
- gap: 16px;
894
- }
895
-
896
- .header-actions {
897
- width: 100%;
898
- justify-content: flex-start;
899
- flex-wrap: wrap;
900
- }
901
- }
902
- `;
903
- const getMobileResponsiveStyles = () => `
904
- /* Responsive Design - Mobile */
905
- @media (max-width: 768px) {
906
- .container {
907
- padding: 20px 16px;
908
- }
909
-
910
- .header {
911
- padding: 20px;
912
- margin-bottom: 24px;
913
- }
914
-
915
- .filters-bar {
916
- flex-direction: column;
917
- align-items: stretch;
918
- }
919
-
920
- .filter-group {
921
- flex-direction: column;
922
- align-items: flex-start;
923
- width: 100%;
924
- }
925
-
926
- .filter-group select,
927
- .filter-group input {
928
- width: 100%;
929
- }
930
-
931
- .search-input {
932
- width: 100%;
933
- }
934
-
935
- .table-container {
936
- border-radius: 12px;
937
- overflow-x: auto;
938
- -webkit-overflow-scrolling: touch;
939
- }
940
-
941
- table {
942
- min-width: 800px; /* Force scroll */
943
- }
944
-
945
- .pagination {
946
- flex-direction: column;
947
- gap: 16px;
948
- align-items: center;
949
- }
950
-
951
- .pagination-controls {
952
- justify-content: center;
953
- }
954
-
955
- .page-size-selector {
956
- margin-left: 0;
957
- padding-left: 0;
958
- border-left: none;
959
- width: 100%;
960
- justify-content: center;
961
- margin-top: 12px;
962
- padding-top: 12px;
963
- border-top: 1px solid var(--border);
964
- }
965
- }
966
- `;
967
- const getMobileColumnHideStyles = () => `
968
- /* Hide/Show columns for mobile */
969
- @media (max-width: 768px) {
970
- .hide-mobile {
971
- display: none;
972
- }
973
- }
974
-
975
- @media (max-width: 576px) {
976
- .hide-small {
977
- display: none;
978
- }
979
- }
980
- `;
981
- const getTableScrollHintStyles = () => `
982
- /* Mobile table scroll hint */
983
- @media (max-width: 992px) {
984
- .table-wrapper {
985
- position: relative;
986
- }
987
- .table-wrapper::after {
988
- content: '';
989
- position: absolute;
990
- top: 0;
991
- right: 0;
992
- width: 20px;
993
- height: 100%;
994
- background: linear-gradient(to right, transparent, var(--card));
995
- pointer-events: none;
996
- opacity: 0;
997
- transition: opacity 0.3s;
998
- }
999
- .table-wrapper:hover::after {
1000
- opacity: 1;
1001
- }
1002
- }
1003
- `;
1004
- const getResponsiveStyles = () => `
1005
- ${getTabletResponsiveStyles()}
1006
- ${getMobileResponsiveStyles()}
1007
- ${getMobileColumnHideStyles()}
1008
- ${getTableScrollHintStyles()}
1009
- `;
1010
- const getWorkersDashboardStyles = () => [
1011
- getRootVariables(),
1012
- getResetAndBaseStyles(),
1013
- getHeaderStyles(),
1014
- getButtonsAndInputsStyles(),
1015
- getFilterStyles(),
1016
- getSummaryStyles(),
1017
- getTableStyles(),
1018
- getStatusBadgeStyles(),
1019
- getPerformanceAndActionStyles(),
1020
- getExpandedRowStyles(),
1021
- getLogoAndIconStyles(),
1022
- getPaginationStyles(),
1023
- getToggleStartStyles(),
1024
- getResponsiveStyles(),
1025
- ].join('\n');
1026
- export { getWorkersDashboardStyles };