@@ -256,39 +256,17 @@ const getWaitTimeData = () => {
256
256
const throughputData = ref (getThroughputData ())
257
257
const waitTimeData = ref (getWaitTimeData ())
258
258
259
- const queueStatusColors: Record <string , string > = {
260
- queued: ' bg-blue-500' ,
261
- processing: ' bg-yellow-500' ,
262
- processed: ' bg-green-500' ,
263
- released: ' bg-purple-500' ,
264
- failed: ' bg-red-500' ,
265
- }
266
-
267
259
const jobStatusColors: Record <string , string > = {
268
260
queued: ' text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/50 ring-blue-600/20' ,
269
261
processing: ' text-yellow-700 dark:text-yellow-300 bg-yellow-50 dark:bg-yellow-900/50 ring-yellow-600/20' ,
270
262
completed: ' text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-900/50 ring-green-600/20' ,
271
263
failed: ' text-red-700 dark:text-red-300 bg-red-50 dark:bg-red-900/50 ring-red-600/20' ,
272
264
}
273
265
274
- const workerStatusColors: Record <string , string > = {
275
- running: ' text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-900/50 ring-green-600/20' ,
276
- paused: ' text-yellow-700 dark:text-yellow-300 bg-yellow-50 dark:bg-yellow-900/50 ring-yellow-600/20' ,
277
- stopped: ' text-red-700 dark:text-red-300 bg-red-50 dark:bg-red-900/50 ring-red-600/20' ,
278
- }
279
-
280
- const getQueueStatusColor = (status : string ): string => {
281
- return queueStatusColors [status ] || ' bg-gray-500'
282
- }
283
-
284
266
const getJobStatusColor = (status : string ): string => {
285
267
return jobStatusColors [status ] || ' text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ring-gray-600/20'
286
268
}
287
269
288
- const getWorkerStatusColor = (status : string ): string => {
289
- return workerStatusColors [status ] || ' text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ring-gray-600/20'
290
- }
291
-
292
270
// Watch for time range changes
293
271
watch ([timeRange , selectedQueue ], async () => {
294
272
isLoading .value = true
@@ -318,7 +296,7 @@ const handleRetry = async (job: Job) => {
318
296
<div class =" mb-8 px-4 lg:px-8 sm:px-6" >
319
297
<div >
320
298
<h3 class =" text-base text-gray-900 dark:text-gray-100 font-semibold leading-6" >
321
- Queue Overview
299
+ Jobs Overview
322
300
</h3 >
323
301
324
302
<dl class =" mt-5 grid grid-cols-1 gap-5 lg:grid-cols-3 sm:grid-cols-2" >
@@ -388,7 +366,58 @@ const handleRetry = async (job: Job) => {
388
366
</div >
389
367
</div >
390
368
391
- <!-- Recent Jobs -->
369
+ <!-- Queue Performance -->
370
+ <div class =" px-4 lg:px-8 sm:px-6" >
371
+ <div class =" grid grid-cols-1 gap-6 lg:grid-cols-2" >
372
+ <!-- Throughput Chart -->
373
+ <div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
374
+ <div class =" p-6" >
375
+ <div class =" flex items-center justify-between mb-6" >
376
+ <div >
377
+ <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Job Throughput</h3 >
378
+ <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Processed vs failed jobs over time</p >
379
+ </div >
380
+ <div class =" flex items-center space-x-4" >
381
+ <select
382
+ v-model =" timeRange"
383
+ class =" h-9 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-1.5 pl-3 pr-8 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600"
384
+ >
385
+ <option value =" hour" >Last Hour</option >
386
+ <option value =" day" >Last 24 Hours</option >
387
+ <option value =" week" >Last Week</option >
388
+ </select >
389
+ </div >
390
+ </div >
391
+ <div class =" h-[300px] relative" >
392
+ <div v-if =" isLoading" class =" absolute inset-0 flex items-center justify-center bg-white bg-opacity-75 dark:bg-blue-gray-700 dark:bg-opacity-75 z-10" >
393
+ <div class =" animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" ></div >
394
+ </div >
395
+ <Line :data =" throughputData" :options =" chartOptions" />
396
+ </div >
397
+ </div >
398
+ </div >
399
+
400
+ <!-- Wait Time Chart -->
401
+ <div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
402
+ <div class =" p-6" >
403
+ <div class =" flex items-center justify-between mb-6" >
404
+ <div >
405
+ <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Job Wait Time</h3 >
406
+ <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Average time jobs spend in queue</p >
407
+ </div >
408
+ </div >
409
+ <div class =" h-[300px] relative" >
410
+ <div v-if =" isLoading" class =" absolute inset-0 flex items-center justify-center bg-white bg-opacity-75 dark:bg-blue-gray-700 dark:bg-opacity-75 z-10" >
411
+ <div class =" animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" ></div >
412
+ </div >
413
+ <Line :data =" waitTimeData" :options =" chartOptions" />
414
+ </div >
415
+ </div >
416
+ </div >
417
+ </div >
418
+ </div >
419
+
420
+ <!-- Recent Jobs -->
392
421
<div class =" my-8 px-4 lg:px-8 sm:px-6" >
393
422
<div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
394
423
<div class =" px-4 py-5 sm:p-6" >
@@ -398,7 +427,7 @@ const handleRetry = async (job: Job) => {
398
427
to =" /jobs/history"
399
428
class =" inline-flex items-center space-x-1 text-sm text-blue-600 hover:text-blue-500 dark:text-blue-400 dark:hover:text-blue-300"
400
429
>
401
- <span >View Full History </span >
430
+ <span >View All </span >
402
431
<div class =" i-heroicons-arrow-right h-4 w-4" />
403
432
</router-link >
404
433
</div >
@@ -459,166 +488,5 @@ const handleRetry = async (job: Job) => {
459
488
</div >
460
489
</div >
461
490
</div >
462
-
463
- <!-- Queue Performance -->
464
- <div class =" px-4 lg:px-8 sm:px-6" >
465
- <div class =" grid grid-cols-1 gap-6 lg:grid-cols-2" >
466
- <!-- Throughput Chart -->
467
- <div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
468
- <div class =" p-6" >
469
- <div class =" flex items-center justify-between mb-6" >
470
- <div >
471
- <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Job Throughput</h3 >
472
- <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Processed vs failed jobs over time</p >
473
- </div >
474
- <div class =" flex items-center space-x-4" >
475
- <select
476
- v-model =" timeRange"
477
- class =" h-9 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-1.5 pl-3 pr-8 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600"
478
- >
479
- <option value =" hour" >Last Hour</option >
480
- <option value =" day" >Last 24 Hours</option >
481
- <option value =" week" >Last Week</option >
482
- </select >
483
- </div >
484
- </div >
485
- <div class =" h-[300px] relative" >
486
- <div v-if =" isLoading" class =" absolute inset-0 flex items-center justify-center bg-white bg-opacity-75 dark:bg-blue-gray-700 dark:bg-opacity-75 z-10" >
487
- <div class =" animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" ></div >
488
- </div >
489
- <Line :data =" throughputData" :options =" chartOptions" />
490
- </div >
491
- </div >
492
- </div >
493
-
494
- <!-- Wait Time Chart -->
495
- <div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
496
- <div class =" p-6" >
497
- <div class =" flex items-center justify-between mb-6" >
498
- <div >
499
- <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Job Wait Time</h3 >
500
- <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Average time jobs spend in queue</p >
501
- </div >
502
- </div >
503
- <div class =" h-[300px] relative" >
504
- <div v-if =" isLoading" class =" absolute inset-0 flex items-center justify-center bg-white bg-opacity-75 dark:bg-blue-gray-700 dark:bg-opacity-75 z-10" >
505
- <div class =" animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" ></div >
506
- </div >
507
- <Line :data =" waitTimeData" :options =" chartOptions" />
508
- </div >
509
- </div >
510
- </div >
511
- </div >
512
- </div >
513
-
514
- <!-- Queue Stats -->
515
- <div class =" mt-8 px-4 lg:px-8 sm:px-6" >
516
- <div class =" sm:flex sm:items-center" >
517
- <div class =" sm:flex-auto" >
518
- <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Queue Statistics</h3 >
519
- <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Detailed breakdown of jobs by queue and status</p >
520
- </div >
521
- </div >
522
-
523
- <div class =" mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3 sm:grid-cols-2" >
524
- <div v-for =" (stats, name) in queues" :key =" name" class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow p-6" >
525
- <div class =" flex items-center justify-between mb-4" >
526
- <h4 class =" inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-blue-gray-600 dark:text-gray-200" >
527
- {{ name }}
528
- </h4 >
529
- </div >
530
-
531
- <div class =" space-y-4" >
532
- <!-- Queue Stats -->
533
- <div class =" grid grid-cols-3 gap-4" >
534
- <div v-for =" (value, status) in stats" :key =" status" class =" text-center" >
535
- <div class =" text-2xl font-semibold font-mono" :class =" {
536
- 'text-blue-600 dark:text-blue-400': status === 'queued',
537
- 'text-yellow-600 dark:text-yellow-400': status === 'processing',
538
- 'text-green-600 dark:text-green-400': status === 'processed',
539
- 'text-purple-600 dark:text-purple-400': status === 'released',
540
- 'text-red-600 dark:text-red-400': status === 'failed'
541
- }" >{{ value }}</div >
542
- <div class =" text-xs text-gray-500 dark:text-gray-400 capitalize" >{{ status }}</div >
543
- </div >
544
- </div >
545
-
546
- <!-- Queue Progress -->
547
- <div class =" h-2 bg-gray-100 dark:bg-blue-gray-600 rounded-full overflow-hidden" >
548
- <div class =" flex h-full" >
549
- <div class =" bg-green-500 h-full" :style =" { width: `${(stats.processed / (stats.processed + stats.failed)) * 100}%` }" />
550
- <div class =" bg-red-500 h-full" :style =" { width: `${(stats.failed / (stats.processed + stats.failed)) * 100}%` }" />
551
- </div >
552
- </div >
553
- <div class =" flex justify-between text-xs text-gray-500 dark:text-gray-400" >
554
- <span >Success Rate: {{ ((stats.processed / (stats.processed + stats.failed)) * 100).toFixed(1) }}%</span >
555
- <span >Failure Rate: {{ ((stats.failed / (stats.processed + stats.failed)) * 100).toFixed(1) }}%</span >
556
- </div >
557
- </div >
558
- </div >
559
- </div >
560
- </div >
561
-
562
- <!-- Workers -->
563
- <div class =" mt-8 px-4 lg:px-8 sm:px-6" >
564
- <div class =" bg-white dark:bg-blue-gray-700 rounded-lg shadow" >
565
- <div class =" p-6" >
566
- <div class =" sm:flex sm:items-center" >
567
- <div class =" sm:flex-auto" >
568
- <h3 class =" text-base font-medium text-gray-900 dark:text-gray-100" >Workers</h3 >
569
- <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >Active job processing workers</p >
570
- </div >
571
- </div >
572
-
573
- <div class =" mt-6" >
574
- <div class =" overflow-x-auto" >
575
- <table class =" min-w-full divide-y divide-gray-200 dark:divide-gray-600" >
576
- <thead >
577
- <tr >
578
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >Name</th >
579
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >Status</th >
580
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >Queue</th >
581
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >Jobs Processed</th >
582
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >Memory</th >
583
- <th scope =" col" class =" px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-100" >CPU</th >
584
- <th scope =" col" class =" px-3 py-3.5 text-right text-sm font-semibold text-gray-900 dark:text-gray-100" >Last Heartbeat</th >
585
- </tr >
586
- </thead >
587
- <tbody class =" divide-y divide-gray-200 dark:divide-gray-600" >
588
- <tr v-for =" worker in workers" :key =" worker.id" class =" hover:bg-gray-50 dark:hover:bg-blue-gray-600/50" >
589
- <td class =" whitespace-nowrap px-3 py-4 text-sm" >
590
- <div class =" font-medium text-gray-900 dark:text-gray-100" >{{ worker.name }}</div >
591
- <div class =" text-gray-500 dark:text-gray-400 font-mono text-xs" >{{ worker.id }}</div >
592
- </td >
593
- <td class =" whitespace-nowrap px-3 py-4 text-sm" >
594
- <span class =" inline-flex items-center rounded-md px-2 py-1 text-xs font-medium ring-1 ring-inset"
595
- :class =" getWorkerStatusColor(worker.status)" >
596
- {{ worker.status }}
597
- </span >
598
- </td >
599
- <td class =" whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400" >
600
- {{ worker.queue }}
601
- </td >
602
- <td class =" whitespace-nowrap px-3 py-4 text-sm" >
603
- <div class =" text-gray-900 dark:text-gray-100" >{{ worker.jobs_processed }}</div >
604
- <div class =" text-gray-500 dark:text-gray-400 text-xs" >{{ worker.failed_jobs }} failed</div >
605
- </td >
606
- <td class =" whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400 font-mono" >
607
- {{ worker.memory_usage.toFixed(1) }}MB
608
- </td >
609
- <td class =" whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400 font-mono" >
610
- {{ worker.cpu_usage.toFixed(1) }}%
611
- </td >
612
- <td class =" whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400 text-right" >
613
- {{ worker.last_heartbeat }}
614
- </td >
615
- </tr >
616
- </tbody >
617
- </table >
618
- </div >
619
- </div >
620
- </div >
621
- </div >
622
- </div >
623
491
</div >
624
492
</template >
0 commit comments