diff --git a/resources/views/livewire/servers/show.blade.php b/resources/views/livewire/servers/show.blade.php index 5ad384a..b856a78 100644 --- a/resources/views/livewire/servers/show.blade.php +++ b/resources/views/livewire/servers/show.blade.php @@ -2,7 +2,7 @@ // Threshold tone for gauges/bars: >=90 offline, >=75 warning, else online. $tone = fn (int $v): string => $v >= 90 ? 'offline' : ($v >= 75 ? 'warning' : 'online'); $barColor = ['online' => 'bg-online', 'warning' => 'bg-warning', 'offline' => 'bg-offline']; - $statusLabel = ['online' => __('servers.status_online'), 'warning' => __('servers.status_warning'), 'offline' => __('servers.status_offline')][$server->status] ?? ucfirst($server->status); + $statusLabel = ['online' => __('servers.status_online'), 'warning' => __('servers.status_warning'), 'offline' => __('servers.status_offline'), 'pending' => __('servers.status_pending')][$server->status] ?? ucfirst($server->status); $specs = $server->specs ?? []; $cores = $specs['cores'] ?? null; @@ -51,6 +51,7 @@ 'border-online/30 bg-online/10 text-online' => $server->status === 'online', 'border-warning/30 bg-warning/10 text-warning' => $server->status === 'warning', 'border-offline/30 bg-offline/10 text-offline' => $server->status === 'offline', + 'border-cyan/30 bg-cyan/10 text-cyan' => $server->status === 'pending', ])> @@ -259,11 +260,14 @@ $f2bIgnore = $f2b['ignoreip'] ?? []; $f2bBanned = array_sum(array_map(fn ($j) => $j['currentlyBanned'] ?? 0, $f2bJails)); - // Show a panel ONLY when its tool is actually installed (active or inactive). - // When absent, the Sicherheit checklist row carries the "Aktivieren" install - // path — so the redundant "nicht installiert" box is gone. - $showFw = $fwSupported && $fwInstalled; - $showF2b = $f2bSupported && $f2bInstalled; + // Show a panel when its tool is actually installed (active or inactive), OR + // when the privileged read FAILED (readError) — a failed probe must stay + // visible so the operator can tell it apart from a genuinely-absent tool + // (both report installed=false). When truly absent, the Sicherheit checklist + // row carries the "Aktivieren" install path — so the redundant "nicht + // installiert" box is gone. + $showFw = $fwSupported && ($fwInstalled || $fwReadError); + $showF2b = $f2bSupported && ($f2bInstalled || $f2bReadError); $panelCount = ($showFw ? 1 : 0) + ($showF2b ? 1 : 0); @endphp diff --git a/tests/Feature/ServerShowPanelsTest.php b/tests/Feature/ServerShowPanelsTest.php index e0af616..f764cd0 100644 --- a/tests/Feature/ServerShowPanelsTest.php +++ b/tests/Feature/ServerShowPanelsTest.php @@ -41,4 +41,30 @@ class ServerShowPanelsTest extends TestCase ->assertSee(__('servers.firewall_title')) ->assertSee(__('servers.fail2ban_title')); } + + public function test_panel_stays_visible_on_read_error_even_when_not_installed(): void + { + // A failed privileged read reports installed=false + readError=true; it must + // stay visible so the operator can tell "probe failed" from "tool absent". + $this->actingAs(User::factory()->create()); + + Livewire::test(Show::class, ['server' => $this->server()]) + ->set('ready', true) + ->set('firewall', ['supported' => true, 'installed' => false, 'readError' => true]) + ->set('fail2ban', ['supported' => true, 'installed' => false, 'readError' => true]) + ->assertSee(__('servers.firewall_title')) + ->assertSee(__('servers.firewall_read_error')) + ->assertSee(__('servers.fail2ban_title')) + ->assertSee(__('servers.fail2ban_read_error')); + } + + public function test_pending_server_header_uses_localized_label(): void + { + $this->actingAs(User::factory()->create()); + $server = Server::create(['name' => 's', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'pending']); + + Livewire::test(Show::class, ['server' => $server]) + ->assertSee(__('servers.status_pending')) + ->assertDontSee('Pending'); + } }