@php $runs = $runs ?? collect(); $overflowCount = (int) ($overflowCount ?? 0); $tenant = $tenant ?? null; $visibleRunCount = $runs->count(); $activeRunCount = (int) ($activeRunCount ?? ($runs->filter(fn ($run): bool => $run instanceof \App\Models\OperationRun && $run->isCurrentlyActive())->count() + $overflowCount)); $primaryRun = $runs->first(); $hasActiveVisibleRuns = $runs->contains(fn ($run): bool => $run instanceof \App\Models\OperationRun && $run->isCurrentlyActive()); $hasTerminalFollowUpVisibleRuns = $runs->contains(fn ($run): bool => $run instanceof \App\Models\OperationRun && ! $run->isCurrentlyActive() && $run->requiresOperatorReview()); $hasTerminalVisibleRuns = $runs->contains(fn ($run): bool => $run instanceof \App\Models\OperationRun && ! $run->isCurrentlyActive()); $usesCollectivePrimaryAction = $visibleRunCount > 1; $operationsCollectionLabel = \App\Support\OperationRunLinks::collectionLabel(); $operationsIndexUrl = $tenant ? \App\Support\OpsUx\OperationRunUrl::index($tenant) : null; $primaryActionLabel = $usesCollectivePrimaryAction ? 'Review operations' : 'View operation'; $bannerTitle = $hasActiveVisibleRuns && ! $hasTerminalVisibleRuns ? 'Active operations' : 'Operation updates'; $bannerHelper = match (true) { $hasActiveVisibleRuns && $hasTerminalFollowUpVisibleRuns => 'Active and recent operation updates that may need review.', $hasActiveVisibleRuns => 'Queued and running work stays here until diagnostics are needed.', $hasTerminalFollowUpVisibleRuns => 'Recent operation updates that may need review.', $hasTerminalVisibleRuns => 'Successful operation updates stay briefly visible so you can confirm completion and keep working.', default => 'Recent operation updates.', }; $primaryActionUrl = null; if ($usesCollectivePrimaryAction) { $primaryActionUrl = $operationsIndexUrl; } elseif ($tenant && $primaryRun) { $primaryActionUrl = \App\Support\OpsUx\OperationRunUrl::view($primaryRun, $tenant); } $tertiaryActionLabel = $hasTerminalFollowUpVisibleRuns ? 'Acknowledge' : ($hasActiveVisibleRuns ? 'Hide activity' : 'Dismiss'); @endphp {{-- Cleanup is delegated to the shared poller helper, which uses teardownObserver and new MutationObserver. --}} {{-- Widget must always be mounted, even when empty, so it can receive Livewire events --}}
@if($runs->isNotEmpty())

{{ $bannerTitle }}

{{ $bannerHelper }}

@if ($primaryActionUrl) {{ $primaryActionLabel }} @endif @if ($operationsIndexUrl) Show all operations @endif
@foreach ($runs as $run) @php $uxStatus = \App\Support\OpsUx\OperationStatusNormalizer::toUxStatus($run->status, $run->outcome); $isTerminalRun = ! $run->isCurrentlyActive(); $progress = \App\Support\OpsUx\OperationRunProgressContract::forRun($run); $hasDeterminateProgress = $progress['display'] === 'counted'; $lifecycleAttention = \App\Support\OpsUx\OperationUxPresenter::lifecycleAttentionSummary($run); $showsLifecycleAttention = $lifecycleAttention !== null && ($lifecycleAttention !== 'Likely stale' || $run->status === 'queued' || ! $hasDeterminateProgress); $progressLabel = $progress['label']; $progressPercent = $progress['percent']; $showsIndeterminateProgress = $progress['display'] === 'indeterminate'; $statusLabel = match ($uxStatus) { 'queued' => 'Queued for execution', 'running' => 'In progress', 'succeeded' => 'Completed successfully', 'partial' => 'Completed with follow-up', 'blocked' => 'Blocked by prerequisite', default => 'Execution failed', }; $statusClasses = match ($uxStatus) { 'queued' => 'bg-primary-50 text-primary-700 ring-1 ring-inset ring-primary-100 dark:bg-primary-500/10 dark:text-primary-200 dark:ring-primary-400/20', 'running' => 'bg-primary-100 text-primary-800 ring-1 ring-inset ring-primary-200 dark:bg-primary-500/20 dark:text-primary-100 dark:ring-primary-400/25', 'succeeded' => 'bg-success-50 text-success-800 ring-1 ring-inset ring-success-200 dark:bg-success-500/15 dark:text-success-100 dark:ring-success-400/25', 'partial', 'blocked' => 'bg-warning-50 text-warning-800 ring-1 ring-inset ring-warning-200 dark:bg-warning-500/10 dark:text-warning-100 dark:ring-warning-400/25', default => 'bg-danger-50 text-danger-800 ring-1 ring-inset ring-danger-200 dark:bg-danger-500/10 dark:text-danger-100 dark:ring-danger-400/25', }; $elapsedLabel = \App\Support\OpsUx\RunDurationInsights::elapsedCompact($run); $surfaceGuidance = \App\Support\OpsUx\OperationUxPresenter::surfaceGuidance($run); $activitySummaryLine = $isTerminalRun ? sprintf('Completed · %s', \App\Support\OpsUx\RunDurationInsights::completedRecency($run)) : sprintf( '%s · %s · %s', $run->status === 'queued' ? 'Queued' : 'Running', $elapsedLabel, $progressLabel ?? 'Progress details pending.', ); @endphp

{{ \App\Support\OperationCatalog::label((string) $run->type) }}

{{ $statusLabel }} @if ($showsLifecycleAttention) {{ $lifecycleAttention }} @endif

{{ $activitySummaryLine }}

@if ($isTerminalRun && $surfaceGuidance)

{{ $surfaceGuidance }}

@endif @if ($progressPercent !== null && $progressLabel !== null)
@elseif ($showsIndeterminateProgress)
@endif
@endforeach
@if ($overflowCount > 0)

{{ $overflowCount }} more operation update{{ $overflowCount === 1 ? '' : 's' }} available in @if ($operationsIndexUrl) {{ $operationsCollectionLabel }}. @else {{ $operationsCollectionLabel }}. @endif

@endif
{{ $activeRunCount }} active operation{{ $activeRunCount === 1 ? '' : 's' }}
@if($tenant) Show all operations @endif
@endif