feat(proxy): show sidebar warning icon when proxy is not running

Add a proxyNotRunning flag to the server sidebar state. The Proxy menu
item's warning icon now also appears when a proxy is configured but its
status is not "running". The navbar sends the flag in the
proxy-configuration-state-changed event, so the icon updates live.

Add tests for the dispatched flag and the sidebar bindings.
This commit is contained in:
Andras Bacsai
2026-09-26 00:17:55 +02:00
parent 6daea93df4
commit 0db2eae8de
4 changed files with 28 additions and 1 deletions
+1
View File
@@ -258,6 +258,7 @@ class Navbar extends Component
'proxy-configuration-state-changed',
pending: $this->server->hasPendingProxyConfiguration(),
traefikOutdated: $this->server->hasCurrentTraefikOutdatedInfo(),
proxyNotRunning: $this->server->proxySet() && ($this->server->proxy->status ?? 'unknown') !== 'running',
);
}
@@ -3,6 +3,7 @@
@php
$serverRouteParameters = ['server_uuid' => $server->uuid];
$sentinelStatus = $server->sentinelStatus();
$proxyNotRunning = $server->proxySet() && ($server->proxy->status ?? 'unknown') !== 'running';
$sentinelStatusStartedAt = $server->sentinel_waiting_since ?? \Illuminate\Support\Carbon::parse($server->sentinel_updated_at);
$sentinelTimeoutSeconds = $server->sentinel_waiting_since !== null
? $server->firstSentinelReportTimeoutSeconds()
@@ -199,6 +200,7 @@
x-data="{
proxyConfigurationPending: @js($server->hasPendingProxyConfiguration()),
traefikOutdated: @js($server->hasCurrentTraefikOutdatedInfo()),
proxyNotRunning: @js($proxyNotRunning),
sentinelOutOfSync: @js($server->isSentinelEnabled() && $sentinelStatus === 'out_of_sync'),
sentinelExpiryTimer: null,
scheduleSentinelExpiry(delay) {
@@ -212,6 +214,7 @@
@proxy-configuration-state-changed.window="
proxyConfigurationPending = $event.detail.pending;
traefikOutdated = $event.detail.traefikOutdated;
proxyNotRunning = $event.detail.proxyNotRunning;
"
@sentinel-status-changed.window="
sentinelOutOfSync = $event.detail.outOfSync;
@@ -247,7 +250,7 @@
<span class="menu-item-label">{{ $menuItem['label'] }}</span>
@if ($menuItem['tracks_proxy_configuration'] ?? false)
<x-reicon name="alert-triangle" x-cloak
x-show="proxyConfigurationPending || traefikOutdated"
x-show="proxyConfigurationPending || traefikOutdated || proxyNotRunning"
class="ml-auto size-3.5 shrink-0 text-orange-500 dark:text-warning" />
@elseif ($menuItem['tracks_sentinel_status'] ?? false)
<x-reicon name="alert-triangle" x-cloak x-show="sentinelOutOfSync"
+20
View File
@@ -135,6 +135,26 @@ test('running proxy hides pending configuration warning when saved settings matc
->assertSee('Your configuration changed, please restart the proxy.');
});
test('navbar tells the sidebar when the proxy is not running', function () {
[$user, $team, $server] = setupProxyUser('admin');
makeServerProxyRunning($server);
$this->actingAs($user);
session(['currentTeam' => $team]);
$component = Livewire::test('server.navbar', ['server' => $server->fresh()]);
$component->call('showNotification')
->assertDispatched('proxy-configuration-state-changed', proxyNotRunning: false);
$server->refresh();
$server->proxy->status = 'exited';
$server->save();
$component->call('showNotification')
->assertDispatched('proxy-configuration-state-changed', proxyNotRunning: true);
});
test('admin can stop a proxy while it is starting', function () {
[$user, $team, $server] = setupProxyUser('admin');
+3
View File
@@ -62,6 +62,9 @@ it('shows a warning icon when a server menu item requires attention', function (
->toContain('proxyConfigurationPending: @js($server->hasPendingProxyConfiguration()),')
->toContain('traefikOutdated: @js($server->hasCurrentTraefikOutdatedInfo())')
->toContain('@proxy-configuration-state-changed.window')
->toContain('proxyNotRunning: @js($proxyNotRunning)')
->toContain('proxyNotRunning = $event.detail.proxyNotRunning')
->toContain('x-show="proxyConfigurationPending || traefikOutdated || proxyNotRunning"')
->toContain('@sentinel-status-changed.window')
->toContain('sentinelOutOfSync = $event.detail.outOfSync')
->toContain('scheduleSentinelExpiry($event.detail.expiresInMilliseconds)')