From b3bac276301d86a54e635930a49801f19e2c6285 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 23 Oct 2026 19:31:59 +0200 Subject: [PATCH] fix(ui): disable server menus that need a validated server --- .../views/components/server/sidebar.blade.php | 8 ++++ .../views/livewire/server/navbar.blade.php | 7 +-- tests/Feature/LocalhostServerDetailsTest.php | 47 +++++++++++++++++-- tests/Feature/ServerDockerRegistriesTest.php | 2 + 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/resources/views/components/server/sidebar.blade.php b/resources/views/components/server/sidebar.blade.php index 663a0ef06f..a0f950c74d 100644 --- a/resources/views/components/server/sidebar.blade.php +++ b/resources/views/components/server/sidebar.blade.php @@ -49,6 +49,7 @@ 'active' => $activeMenu === 'ca-certificate', 'icon' => 'file', 'group' => 'Settings', + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Cloudflare Tunnel', @@ -66,6 +67,7 @@ 'group' => 'Platform', 'visible' => ! $server->isSwarmWorker() && $server->canHostResources(), 'warning' => $server->hasCurrentTraefikOutdatedInfo(), + 'disabled' => ! $server->isFunctional(), 'tracks_proxy_configuration' => true, 'children' => [ ['label' => 'Configuration', 'route' => 'server.proxy', 'active' => $activeSubMenu === 'configuration', 'icon' => 'settings'], @@ -95,6 +97,7 @@ 'active' => $activeMenu === 'resources', 'icon' => 'projects', 'group' => 'Platform', + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Terminal', @@ -104,6 +107,7 @@ 'group' => 'Operations', 'navigate' => false, 'visible' => auth()->user()?->can('canAccessTerminal'), + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Destinations', @@ -145,6 +149,7 @@ 'group' => 'Operations', 'visible' => ! $server->isLocalhost(), 'beta' => true, + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Registries', @@ -153,6 +158,7 @@ 'icon' => 'layers', 'group' => 'Operations', 'visible' => auth()->user()?->can('update', $server), + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Log Drains', @@ -186,6 +192,7 @@ 'icon' => 'shield-alert', 'group' => 'Security', 'visible' => auth()->user()?->can('update', $server), + 'disabled' => ! $server->isFunctional(), 'children' => [ ['label' => 'Patching', 'route' => 'server.security.patches', 'active' => $activeSubMenu === 'patches', 'icon' => 'bandage', 'beta' => true], ['label' => 'Terminal Access', 'route' => 'server.security.terminal-access', 'active' => $activeSubMenu === 'terminal-access', 'icon' => 'browser-terminal', 'navigate' => false], @@ -199,6 +206,7 @@ 'beta' => true, 'group' => 'Operations', 'visible' => ! $server->isLocalhost() && auth()->user()?->can('update', $server), + 'disabled' => ! $server->isFunctional(), ], [ 'label' => 'Danger Zone', diff --git a/resources/views/livewire/server/navbar.blade.php b/resources/views/livewire/server/navbar.blade.php index 8172da75ea..2aef058129 100644 --- a/resources/views/livewire/server/navbar.blade.php +++ b/resources/views/livewire/server/navbar.blade.php @@ -42,7 +42,7 @@ 'label' => 'Proxy', 'route' => 'server.proxy', 'active' => request()->routeIs('server.proxy', 'server.proxy.*'), - 'visible' => ! $server->isSwarmWorker() && $server->canHostResources(), + 'visible' => $server->isFunctional() && ! $server->isSwarmWorker() && $server->canHostResources(), 'warning' => $this->hasTraefikOutdated || $this->hasPendingProxyConfiguration, ], [ @@ -59,19 +59,20 @@ 'label' => 'Resources', 'route' => 'server.resources', 'active' => request()->routeIs('server.resources'), + 'visible' => $server->isFunctional(), ], [ 'label' => 'Terminal', 'route' => 'server.command', 'active' => $currentRoute === 'server.command', 'navigate' => false, - 'visible' => auth()->user()?->can('canAccessTerminal'), + 'visible' => $server->isFunctional() && auth()->user()?->can('canAccessTerminal'), ], [ 'label' => 'Security', 'route' => 'server.security.patches', 'active' => request()->routeIs('server.security.*'), - 'visible' => auth()->user()?->can('update', $server), + 'visible' => $server->isFunctional() && auth()->user()?->can('update', $server), ], ]; diff --git a/tests/Feature/LocalhostServerDetailsTest.php b/tests/Feature/LocalhostServerDetailsTest.php index af8c9cc8b1..68e2e4d9ec 100644 --- a/tests/Feature/LocalhostServerDetailsTest.php +++ b/tests/Feature/LocalhostServerDetailsTest.php @@ -207,16 +207,53 @@ it('shows validation-only menus as disabled until the server is validated', func 'is_usable' => false, ]); - Livewire::test(Show::class, ['server_uuid' => $this->server->uuid]) + $validationOnlyRoutes = collect([ + 'server.docker-cleanup', + 'server.ca-certificate', + 'server.proxy', + 'server.resources', + 'server.registries', + 'server.security.patches', + 'server.command', + ])->map(fn (string $name): string => 'href="'.route($name, ['server_uuid' => $this->server->uuid]).'"'); + + $component = Livewire::test(Show::class, ['server_uuid' => $this->server->uuid]) ->assertSee('Docker Cleanup') - ->assertSee('aria-disabled="true"', false) - ->assertDontSee(route('server.docker-cleanup', ['server_uuid' => $this->server->uuid]), false); + ->assertSee('aria-disabled="true"', false); + $validationOnlyRoutes->each(fn (string $href) => $component->assertDontSee($href, false)); $this->server->settings()->update([ 'is_reachable' => true, 'is_usable' => true, ]); - Livewire::test(Show::class, ['server_uuid' => $this->server->uuid]) - ->assertSee(route('server.docker-cleanup', ['server_uuid' => $this->server->uuid]), false); + $component = Livewire::test(Show::class, ['server_uuid' => $this->server->uuid]); + $validationOnlyRoutes->each(fn (string $href) => $component->assertSee($href, false)); +}); + +it('disables remote-only menus until a remote server is validated', function () { + $remoteServer = Server::factory()->create([ + 'team_id' => $this->team->id, + 'private_key_id' => $this->privateKey->id, + ]); + $remoteServer->settings()->update([ + 'is_reachable' => false, + 'is_usable' => false, + ]); + + $remoteOnlyRoutes = collect(['server.github-runners', 'server.transfer', 'server.command']) + ->map(fn (string $name): string => 'href="'.route($name, ['server_uuid' => $remoteServer->uuid]).'"'); + + $component = Livewire::test(Show::class, ['server_uuid' => $remoteServer->uuid]) + ->assertSee('GitHub Runners') + ->assertSee('Transfer'); + $remoteOnlyRoutes->each(fn (string $href) => $component->assertDontSee($href, false)); + + $remoteServer->settings()->update([ + 'is_reachable' => true, + 'is_usable' => true, + ]); + + $component = Livewire::test(Show::class, ['server_uuid' => $remoteServer->uuid]); + $remoteOnlyRoutes->each(fn (string $href) => $component->assertSee($href, false)); }); diff --git a/tests/Feature/ServerDockerRegistriesTest.php b/tests/Feature/ServerDockerRegistriesTest.php index 8020833cea..9c7cd9ee45 100644 --- a/tests/Feature/ServerDockerRegistriesTest.php +++ b/tests/Feature/ServerDockerRegistriesTest.php @@ -125,6 +125,8 @@ it('lists the team servers for admins on the registries page', function () { ->assertOk() ->assertSee('href="'.route('registries.index').'"', false); + $this->server->settings()->update(['is_reachable' => true, 'is_usable' => true]); + $this->get(route('server.registries', ['server_uuid' => $this->server->uuid])) ->assertOk() ->assertSee('href="'.route('server.registries', ['server_uuid' => $this->server->uuid]).'"', false);