71 lines
3.9 KiB
PHP
71 lines
3.9 KiB
PHP
<div class="space-y-4" @if (! $ready) wire:init="scan" @endif>
|
|
{{-- Header --}}
|
|
<div>
|
|
<p class="font-mono text-[11px] uppercase tracking-[0.2em] text-accent-text">{{ __('patch.eyebrow') }}</p>
|
|
<h2 class="mt-0.5 font-display text-xl font-semibold text-ink sm:text-2xl">{{ __('patch.title') }}</h2>
|
|
<p class="mt-1 text-sm text-ink-3">{{ __('patch.subtitle') }}</p>
|
|
</div>
|
|
|
|
{{-- Fleet KPIs --}}
|
|
@if ($ready)
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<x-kpi :label="__('patch.total_pending')" :value="$totalPending" icon="rotate" :tone="$totalPending > 0 ? 'warning' : 'online'" />
|
|
<x-kpi :label="__('patch.total_security')" :value="$totalSecurity" icon="shield-alert" :tone="$totalSecurity > 0 ? 'offline' : 'online'" />
|
|
</div>
|
|
@endif
|
|
|
|
@if ($servers->isEmpty())
|
|
<x-panel>
|
|
<div class="py-8 text-center">
|
|
<p class="font-display text-sm font-semibold text-ink">{{ __('patch.no_servers_title') }}</p>
|
|
<p class="mt-1 text-xs text-ink-3">{{ __('patch.no_servers') }}</p>
|
|
</div>
|
|
</x-panel>
|
|
@elseif (! $ready)
|
|
<div class="space-y-2">
|
|
@foreach ($servers as $s)
|
|
<div wire:key="pl-{{ $s->uuid }}" class="h-16 animate-pulse rounded-lg bg-raised/50"></div>
|
|
@endforeach
|
|
<p class="text-center font-mono text-[11px] text-ink-4">{{ __('patch.scan_hint') }}</p>
|
|
</div>
|
|
@else
|
|
<x-panel :padded="false">
|
|
<div class="divide-y divide-line">
|
|
@foreach ($servers as $s)
|
|
@php($c = $counts[$s->uuid] ?? null)
|
|
@php($result = $results[$s->uuid] ?? null)
|
|
<div wire:key="pr-{{ $s->uuid }}" class="px-4 py-3 sm:px-5">
|
|
<div class="flex flex-wrap items-center gap-3">
|
|
<div class="min-w-0 flex-1">
|
|
<a href="{{ route('servers.show', $s->uuid) }}" wire:navigate class="truncate font-mono text-sm text-ink hover:text-accent-text">{{ $s->name }}</a>
|
|
</div>
|
|
|
|
@if (! $c || isset($c['error']))
|
|
<span class="font-mono text-[11px] text-offline">{{ __('patch.scan_error') }}</span>
|
|
@elseif (is_null($c['pending']))
|
|
<span class="font-mono text-[11px] text-ink-4">{{ __('patch.unknown') }}</span>
|
|
@elseif ($c['pending'] === 0)
|
|
<x-status-pill status="online">{{ __('patch.up_to_date') }}</x-status-pill>
|
|
@else
|
|
<div class="flex items-center gap-1.5">
|
|
<x-status-pill status="warning">{{ __('patch.pending_label', ['count' => $c['pending']]) }}</x-status-pill>
|
|
@if (($c['security'] ?? 0) > 0)
|
|
<x-status-pill status="offline">{{ __('patch.security_label', ['count' => $c['security']]) }}</x-status-pill>
|
|
@endif
|
|
@can('operate')
|
|
<x-modal-trigger variant="accent" action="patch('{{ $s->uuid }}')" wire:loading.attr="disabled">{{ __('patch.apply') }}</x-modal-trigger>
|
|
@endcan
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
@if ($result)
|
|
<pre class="mt-2 max-h-40 overflow-auto rounded-md border border-line bg-void p-3 font-mono text-[11px] leading-relaxed {{ $result['ok'] ? 'text-ink-2' : 'text-offline' }}">{{ $result['output'] }}</pre>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</x-panel>
|
|
@endif
|
|
</div>
|