76 lines
4.9 KiB
PHP
76 lines
4.9 KiB
PHP
<div wire:poll.3s="loadRuns">
|
|
<!-- Bulk Operation Progress Component: {{ $runs->count() }} active runs -->
|
|
@if($runs->isNotEmpty())
|
|
<div class="fixed bottom-4 right-4 z-[999999] w-96 space-y-2" style="pointer-events: auto;">
|
|
@foreach ($runs as $run)
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl border-2 border-primary-500 dark:border-primary-400 p-4 transition-all animate-in slide-in-from-right duration-300"
|
|
wire:key="run-{{ $run->id }}">
|
|
|
|
<div class="flex justify-between items-start mb-3">
|
|
<div class="flex-1">
|
|
<h4 class="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
{{ ucfirst($run->action) }} {{ ucfirst(str_replace('_', ' ', $run->resource)) }}
|
|
</h4>
|
|
<p class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
|
@if($run->status === 'pending')
|
|
<span class="inline-flex items-center">
|
|
<svg class="animate-spin -ml-1 mr-1.5 h-3 w-3 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
Starting...
|
|
</span>
|
|
@elseif($run->status === 'running')
|
|
<span class="inline-flex items-center">
|
|
<svg class="animate-spin -ml-1 mr-1.5 h-3 w-3 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
Processing...
|
|
</span>
|
|
@endif
|
|
</p>
|
|
</div>
|
|
<div class="text-right">
|
|
<span class="text-xs font-medium text-gray-700 dark:text-gray-300">
|
|
{{ $run->processed_items }} / {{ $run->total_items }}
|
|
</span>
|
|
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
|
{{ $run->total_items > 0 ? round(($run->processed_items / $run->total_items) * 100) : 0 }}%
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full bg-gray-200 rounded-full h-3 dark:bg-gray-700 overflow-hidden">
|
|
<div class="bg-primary-600 dark:bg-primary-500 h-3 rounded-full transition-all duration-300 ease-out"
|
|
style="width: {{ $run->total_items > 0 ? ($run->processed_items / $run->total_items) * 100 : 0 }}%"></div>
|
|
</div>
|
|
|
|
<div class="mt-2 flex items-center justify-between text-xs">
|
|
<div class="flex items-center gap-3">
|
|
@if ($run->succeeded > 0)
|
|
<span class="text-success-600 dark:text-success-400">
|
|
✓ {{ $run->succeeded }} succeeded
|
|
</span>
|
|
@endif
|
|
@if ($run->failed > 0)
|
|
<span class="text-danger-600 dark:text-danger-400">
|
|
✗ {{ $run->failed }} failed
|
|
</span>
|
|
@endif
|
|
@if ($run->skipped > 0)
|
|
<span class="text-gray-500 dark:text-gray-400">
|
|
⊘ {{ $run->skipped }} skipped
|
|
</span>
|
|
@endif
|
|
</div>
|
|
<span class="text-gray-400 dark:text-gray-500">
|
|
{{ $run->created_at->diffForHumans(null, true, true) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|