From dbcef807aebe92fca511172033a0ccdf198d06cb Mon Sep 17 00:00:00 2001 From: Aditya Tripathi Date: Wed, 16 Sep 2026 07:54:34 +0000 Subject: [PATCH] feat(metrics): add reachable /metrics fleet page skeleton --- app/Livewire/Fleet/Metrics.php | 57 +++++++++++++++++++ resources/views/components/navbar.blade.php | 8 +++ .../fleet/metrics-placeholder.blade.php | 3 + .../views/livewire/fleet/metrics.blade.php | 14 +++++ routes/web.php | 2 + .../Livewire/Fleet/MetricsPageTest.php | 33 +++++++++++ 6 files changed, 117 insertions(+) create mode 100644 app/Livewire/Fleet/Metrics.php create mode 100644 resources/views/livewire/fleet/metrics-placeholder.blade.php create mode 100644 resources/views/livewire/fleet/metrics.blade.php create mode 100644 tests/Feature/Livewire/Fleet/MetricsPageTest.php diff --git a/app/Livewire/Fleet/Metrics.php b/app/Livewire/Fleet/Metrics.php new file mode 100644 index 0000000000..8cbefffd00 --- /dev/null +++ b/app/Livewire/Fleet/Metrics.php @@ -0,0 +1,57 @@ + uuid => name */ + public array $serverOptions = []; + + #[Url(as: 'range')] + public string $range = '24h'; + + #[Url(as: 'server')] + public string $serverUuid = ''; + + public bool $live = false; + + public function mount(): void + { + $allServers = Server::ownedByCurrentTeamCached(); + + $this->servers = $allServers + ->filter(fn (Server $server) => $server->isMetricsEnabled()) + ->values(); + + $this->serverOptions = $this->servers + ->mapWithKeys(fn (Server $server) => [$server->uuid => $server->name]) + ->all(); + + if ($this->serverUuid !== '' && ! array_key_exists($this->serverUuid, $this->serverOptions)) { + $this->serverUuid = ''; + } + } + + public function placeholder(): View + { + return view('livewire.fleet.metrics-placeholder'); + } + + public function render(): View + { + return view('livewire.fleet.metrics'); + } +} diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index 251628c496..0722bdd076 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -95,6 +95,14 @@ Analytics +
  • + + + Metrics + +
  • @can('canAccessTerminal')
  • + + diff --git a/resources/views/livewire/fleet/metrics.blade.php b/resources/views/livewire/fleet/metrics.blade.php new file mode 100644 index 0000000000..69255b779a --- /dev/null +++ b/resources/views/livewire/fleet/metrics.blade.php @@ -0,0 +1,14 @@ +
    +
    +

    Metrics

    +

    Resource usage across your servers.

    +
    + + @if ($servers->isEmpty()) + + + + + + @endif +
    diff --git a/routes/web.php b/routes/web.php index 2a0b66a2ac..0a42e7386d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,7 @@ use App\Livewire\Destination\Index as DestinationIndex; use App\Livewire\Destination\Resources as DestinationResources; use App\Livewire\Destination\Show as DestinationShow; use App\Livewire\Dev\LivewireRequestFailurePreview; +use App\Livewire\Fleet\Metrics as FleetMetrics; use App\Livewire\ForcePasswordReset; use App\Livewire\Notifications\Discord as NotificationDiscord; use App\Livewire\Notifications\Email as NotificationEmail; @@ -161,6 +162,7 @@ Route::middleware(['auth', 'verified'])->group(function () { Route::get('/', Dashboard::class)->name('dashboard'); Route::get('/analytics', Analytics::class)->name('analytics'); + Route::get('/metrics', FleetMetrics::class)->name('metrics'); Route::get('/admin', AdminIndex::class)->name('admin.index'); Route::get('/onboarding', BoardingIndex::class)->name('onboarding'); diff --git a/tests/Feature/Livewire/Fleet/MetricsPageTest.php b/tests/Feature/Livewire/Fleet/MetricsPageTest.php new file mode 100644 index 0000000000..ad44bf6d72 --- /dev/null +++ b/tests/Feature/Livewire/Fleet/MetricsPageTest.php @@ -0,0 +1,33 @@ + InstanceSettings::query()->create(['id' => 0])); + $user = User::factory()->create(); + $team = Team::factory()->create(); + $user->teams()->attach($team, ['role' => 'owner']); + $this->actingAs($user); + session(['currentTeam' => $team]); + $this->team = $team; +}); + +it('renders the metrics page with an empty state when no server has metrics enabled', function () { + $component = loadLazy(Livewire::test(Metrics::class)); + + $component + ->assertOk() + ->assertSee('Metrics') + ->assertSee('Enable metrics on a server'); +}); + +it('registers the metrics route', function () { + expect(route('metrics'))->toEndWith('/metrics'); +});