diff --git a/resources/views/livewire/traffic/_geo.blade.php b/resources/views/livewire/traffic/_geo.blade.php index f47e0506bf..06f24bfee6 100644 --- a/resources/views/livewire/traffic/_geo.blade.php +++ b/resources/views/livewire/traffic/_geo.blade.php @@ -50,10 +50,35 @@ @else
{{-- Interactive dotted globe (40%). wire:ignore so live-poll morphs never tear - down the WebGL canvas. --}} -
+ down the WebGL canvas. Mounted via Alpine, not Livewire's script directive: + it ran before the lazy-loaded canvas was in the DOM, and only once per + component, so a globe inserted by a later render (no data -> data after a + range change or live poll) never mounted either. Alpine's + init()/destroy() run each time this element enters or leaves the DOM. --}} +
-
@@ -108,31 +133,5 @@ {{ $attribution }}

@endif - - @script - - @endscript @endif
diff --git a/tests/Feature/TrafficAnalytics/GeoVisualizationTest.php b/tests/Feature/TrafficAnalytics/GeoVisualizationTest.php index bf239a743c..13e230d6a1 100644 --- a/tests/Feature/TrafficAnalytics/GeoVisualizationTest.php +++ b/tests/Feature/TrafficAnalytics/GeoVisualizationTest.php @@ -114,3 +114,24 @@ it('shows a plain no-data state when no country data has been recorded', functio ->assertSee('Countries') ->assertSee('No country data for the selected range'); }); + +it('mounts the globe from the element itself when country data arrives after the first render', function () { + $server = bootGeoServer(); + + $fake = new FakeGeoTrafficClient($server); + $fake->responses = fakeGeoResponses([]); + app()->bind(SentinelTrafficClient::class, fn () => $fake); + + $component = loadLazy(Livewire::test(Analytics::class)) + ->assertSee('No country data for the selected range'); + + $fake->responses = fakeGeoResponses([ + ['value' => 'US', 'requests' => 600, 'bytes_out' => 15000], + ]); + + // A @script block runs only once per component, so a globe inserted by a later + // render never mounted. The mount must live on the element (Alpine x-data). + $component->call('loadData') + ->assertSeeHtml('id="global-analytics-globe" x-ref="canvas"') + ->assertSeeHtml('window.mountTrafficGlobe(canvas'); +});