fix(ui): keep the sidebar server-switcher in sync with the viewed server

Two "current server" notions diverged: the sidebar switcher (session active_server_id)
vs the server-details URL. Now viewing a server's details sets it active (sidebar
always matches the page), and switching the sidebar while on a details page navigates
to the chosen server (instead of reloading the old one). One current server, in sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat/v1-foundation
boban 2026-06-14 19:24:56 +02:00
parent 5ae0b7d135
commit 784566d06b
3 changed files with 69 additions and 1 deletions

View File

@ -18,7 +18,19 @@ class ServerSwitcher extends Component
session(['active_server_id' => $server->id]);
$this->redirect($this->safeReturnUrl(), navigate: true);
$this->redirect($this->targetFor($server, $this->safeReturnUrl()), navigate: true);
}
/**
* Where to land after selecting a server. On a server-details page, switching should
* VIEW the chosen server (so the URL, sidebar and scoped context never diverge);
* everywhere else just reload the current page so the active context updates.
*/
public function targetFor(Server $server, string $current): string
{
return preg_match('#^/servers/[^/]+#', $current) === 1
? route('servers.show', $server)
: $current;
}
/**

View File

@ -61,6 +61,11 @@ class Show extends Component
*/
public function mount(): void
{
// Viewing a server's details makes it the ACTIVE server, so the sidebar switcher
// (and the server-scoped sections) always reflect the server on screen — no drift
// between the URL subject and the sidebar selection.
session(['active_server_id' => $this->server->id]);
// identity + gauges render from the persisted row immediately;
// the live snapshot loads lazily via wire:init -> load().
}

View File

@ -0,0 +1,51 @@
<?php
namespace Tests\Feature;
use App\Livewire\Servers\Show;
use App\Livewire\ServerSwitcher;
use App\Models\Server;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;
class ServerContextSyncTest extends TestCase
{
use RefreshDatabase;
private function server(string $name): Server
{
return Server::create(['name' => $name, 'ip' => '10.0.0.'.rand(2, 250), 'ssh_port' => 22, 'status' => 'online']);
}
public function test_viewing_server_details_sets_it_active(): void
{
$this->actingAs(User::factory()->create());
$b = $this->server('B');
Livewire::test(Show::class, ['server' => $b]);
$this->assertSame($b->id, session('active_server_id'));
}
public function test_switching_on_a_details_page_targets_the_new_server(): void
{
$a = $this->server('A');
$b = $this->server('B');
$switcher = new ServerSwitcher;
// On A's details page, selecting B targets B's details (not a reload of A).
$this->assertSame(route('servers.show', $b), $switcher->targetFor($b, '/servers/'.$a->uuid));
}
public function test_switching_elsewhere_keeps_the_current_page(): void
{
$b = $this->server('B');
$switcher = new ServerSwitcher;
// Off a server-details page, the current page is reloaded as-is.
$this->assertSame('/files', $switcher->targetFor($b, '/files'));
$this->assertSame('/servers', $switcher->targetFor($b, '/servers')); // fleet list, not a details page
}
}