fix(ui): re-sync active server on every details-page request (bfcache-safe)
Add a hydrate() hook so Show re-asserts its server as active on the wire:poll tick and any action — covering a wire:navigate bfcache restore that skips mount(), without the earlier racy client-side POST. Idempotent + server-side, no race. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>feat/v1-foundation
parent
0088122ff1
commit
7ea789c078
|
|
@ -61,15 +61,29 @@ 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]);
|
||||
$this->syncActiveServer();
|
||||
|
||||
// identity + gauges render from the persisted row immediately;
|
||||
// the live snapshot loads lazily via wire:init -> load().
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-assert this server as the ACTIVE one on EVERY request to this component (mount,
|
||||
* the wire:poll tick, any action). This is what keeps the sidebar switcher + scoped
|
||||
* sections in sync with the server on screen — and it also covers a wire:navigate
|
||||
* bfcache restore (Back/Forward), which skips mount() but still hits the server on
|
||||
* the next poll/interaction. Server-side + idempotent, so there is no request race.
|
||||
*/
|
||||
public function hydrate(): void
|
||||
{
|
||||
$this->syncActiveServer();
|
||||
}
|
||||
|
||||
private function syncActiveServer(): void
|
||||
{
|
||||
session(['active_server_id' => $this->server->id]);
|
||||
}
|
||||
|
||||
/** Lazy: pull the full SSH snapshot after the shell renders, behind skeletons. */
|
||||
public function load(FleetService $fleet): void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,22 @@ class ServerContextSyncTest extends TestCase
|
|||
$this->assertSame($b->id, session('active_server_id'));
|
||||
}
|
||||
|
||||
public function test_interacting_with_a_details_page_resyncs_active_server(): void
|
||||
{
|
||||
// Simulates a bfcache restore where mount() did not run and the session points
|
||||
// elsewhere: the next request to the component (poll/action → hydrate) re-syncs.
|
||||
$this->actingAs(User::factory()->create());
|
||||
$a = $this->server('A');
|
||||
$b = $this->server('B');
|
||||
|
||||
$component = Livewire::test(Show::class, ['server' => $a]);
|
||||
session(['active_server_id' => $b->id]); // drift (as after Back/Forward)
|
||||
|
||||
$component->call('pollMetrics');
|
||||
|
||||
$this->assertSame($a->id, session('active_server_id'));
|
||||
}
|
||||
|
||||
public function test_switching_on_a_details_page_targets_the_new_server(): void
|
||||
{
|
||||
$a = $this->server('A');
|
||||
|
|
|
|||
Loading…
Reference in New Issue