-
-
{{ $queue['name'] }}
-
- {{ __('admin.ops_health.queue.thresholds') }}:
- @if($queue['warning'] || $queue['critical'])
- W {{ number_format($queue['warning']) }} / C {{ number_format($queue['critical']) }}
- @else
- -
- @endif
-
-
-
-
- {{ __('admin.ops_health.queue.size') }}:
- {{ $queue['size_label'] }}
-
-
- {{ __('admin.ops_health.queue.failed') }}:
- {{ $queue['failed_label'] }}
-
- $queue['severity'] === 'ok',
- 'bg-amber-100 text-amber-800 dark:bg-amber-400/20 dark:text-amber-200' => $queue['severity'] === 'warning',
- 'bg-rose-100 text-rose-800 dark:bg-rose-400/20 dark:text-rose-200' => $queue['severity'] === 'critical',
- 'bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200' => ! in_array($queue['severity'], ['ok', 'warning', 'critical'], true),
- ])>
- {{ __('admin.ops_health.severity.'.$queue['severity']) }}
-
-
+
+ @foreach($statusSummary as $summary)
+
+
+
+ {{ $summary['label'] }}
+
+
+ {{ number_format($summary['count']) }}
+
-
- @empty
-
{{ __('admin.ops_health.queue.no_queues') }}
- @endforelse
+
+ @endforeach
-
- {{ __('admin.ops_health.queue.alerts_heading') }}
-
- @foreach($alerts as $alert)
-
-
- @if($alert['queue'])
- {{ $alert['queue'] }}
- @endif
-
- @switch($alert['type'])
- @case('size')
- {{ __('admin.ops_health.alert_types.size', ['size' => number_format($alert['size'] ?? 0)]) }}
- @break
- @case('failed_jobs')
- {{ __('admin.ops_health.alert_types.failed_jobs', ['failed' => number_format($alert['failed'] ?? 0)]) }}
- @break
- @case('pending_assets')
- {{ __('admin.ops_health.alert_types.pending_assets', ['count' => number_format($alert['count'] ?? 0), 'minutes' => $alert['older_than_minutes'] ?? $stalledMinutes]) }}
- @break
- @default
- {{ __('admin.ops_health.snapshot_missing') }}
- @endswitch
-
-
-
$alert['severity'] === 'ok',
- 'bg-amber-100 text-amber-800 dark:bg-amber-400/20 dark:text-amber-200' => $alert['severity'] === 'warning',
- 'bg-rose-100 text-rose-800 dark:bg-rose-400/20 dark:text-rose-200' => $alert['severity'] === 'critical',
- 'bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200' => ! in_array($alert['severity'], ['ok', 'warning', 'critical'], true),
- ])>
- {{ __('admin.ops_health.severity.'.$alert['severity']) }}
-
-
- @endforeach
+
+
+
+ @forelse($queues as $queue)
+
+
+
+ {{ __('admin.ops_health.severity.'.$queue['severity']) }}
+
+
+
+
+
+ {{ __('admin.ops_health.queue.size') }}: {{ $queue['size_label'] }}
+
+
+ {{ __('admin.ops_health.queue.failed') }}: {{ $queue['failed_label'] }}
+
+
+ {{ __('admin.ops_health.queue.utilization') }}: {{ $queue['utilization_label'] }}
+
+
+
+ @empty
+
+ @endforelse
+
- @endif
+
+
+
+
+ @forelse($alerts as $alert)
+
+
+
+ {{ __('admin.ops_health.severity.'.$alert['severity']) }}
+
+
+
+
+ @if($alert['queue'])
+
+ {{ $alert['queue'] }}
+
+ @endif
+
+ @switch($alert['type'])
+ @case('size')
+ {{ __('admin.ops_health.alert_types.size', ['size' => number_format($alert['size'] ?? 0)]) }}
+ @break
+ @case('failed_jobs')
+ {{ __('admin.ops_health.alert_types.failed_jobs', ['failed' => number_format($alert['failed'] ?? 0)]) }}
+ @break
+ @case('pending_assets')
+ {{ __('admin.ops_health.alert_types.pending_assets', ['count' => number_format($alert['count'] ?? 0), 'minutes' => $alert['older_than_minutes'] ?? $stalledMinutes]) }}
+ @break
+ @default
+ {{ __('admin.ops_health.snapshot_missing') }}
+ @endswitch
+
+
+
+ @empty
+
+ @endforelse
+
+
+
+
@endif
diff --git a/tests/Feature/OpsHealthWidgetsTest.php b/tests/Feature/OpsHealthWidgetsTest.php
new file mode 100644
index 0000000..54ae8d3
--- /dev/null
+++ b/tests/Feature/OpsHealthWidgetsTest.php
@@ -0,0 +1,67 @@
+setLocale('en');
+ Cache::forget('storage:queue-health:last');
+
+ Livewire::test(QueueHealthWidget::class)
+ ->assertStatus(200)
+ ->assertSee(__('admin.ops_health.queue.no_snapshot'));
+ }
+
+ public function test_queue_health_widget_renders_with_snapshot(): void
+ {
+ app()->setLocale('en');
+ Cache::put('storage:queue-health:last', [
+ 'generated_at' => now()->toIso8601String(),
+ 'connection' => 'redis',
+ 'queues' => [
+ [
+ 'queue' => 'default',
+ 'size' => 120,
+ 'failed' => 2,
+ 'severity' => 'warning',
+ 'limits' => [
+ 'warning' => 100,
+ 'critical' => 200,
+ ],
+ ],
+ ],
+ 'alerts' => [
+ [
+ 'queue' => 'default',
+ 'type' => 'size',
+ 'severity' => 'warning',
+ 'size' => 120,
+ ],
+ ],
+ 'stalled_assets' => 1,
+ ], now()->addMinutes(5));
+
+ Livewire::test(QueueHealthWidget::class)
+ ->assertStatus(200)
+ ->assertSee('default')
+ ->assertSee(__('admin.ops_health.queue.alerts_heading'));
+ }
+
+ public function test_upload_pipeline_widget_renders_without_snapshot(): void
+ {
+ app()->setLocale('en');
+ Cache::forget('storage:monitor:last');
+
+ Livewire::test(UploadPipelineHealthWidget::class)
+ ->assertStatus(200)
+ ->assertSee(__('admin.ops_health.pipeline.no_snapshot'));
+ }
+}