diff --git a/app/Enums/ContainerStatus.php b/app/Enums/ContainerStatus.php index d78004652..621b7d738 100644 --- a/app/Enums/ContainerStatus.php +++ b/app/Enums/ContainerStatus.php @@ -52,4 +52,35 @@ enum ContainerStatus: string self::Offline => 'gray', }; } + + public function isStartingOrStopping(): bool + { + return in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting]); + } + + public function isStartable(): bool + { + return !in_array($this, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting]); + } + + public function isRestartable(): bool + { + if ($this->isStartable()) { + return true; + } + + return !in_array($this, [ContainerStatus::Offline]); + } + + public function isStoppable(): bool + { + return !in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline]); + } + + public function isKillable(): bool + { + // [ContainerStatus::Restarting, ContainerStatus::Removing, ContainerStatus::Dead, ContainerStatus::Created] + + return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Running, ContainerStatus::Exited]); + } } diff --git a/app/Filament/Server/Pages/Console.php b/app/Filament/Server/Pages/Console.php index 4ae888c9b..b067cfc1c 100644 --- a/app/Filament/Server/Pages/Console.php +++ b/app/Filament/Server/Pages/Console.php @@ -23,7 +23,7 @@ class Console extends Page protected static string $view = 'filament.server.pages.console'; - public ContainerStatus $status = ContainerStatus::Missing; + public ContainerStatus $status = ContainerStatus::Offline; public function getWidgetData(): array { @@ -54,10 +54,12 @@ class Console extends Page return 3; } - #[On('powerChanged')] - public function powerChanged(string $state): void + #[On('console-status')] + public function receivedConsoleUpdate(?string $state = null): void { - $this->status = ContainerStatus::from($state); + if ($state) { + $this->status = ContainerStatus::from($state); + } $this->cachedHeaderActions = []; @@ -74,18 +76,18 @@ class Console extends Page ->color('primary') ->size(ActionSize::ExtraLarge) ->action(fn () => $this->dispatch('setServerState', state: 'start')) - ->disabled(fn () => $server->isInConflictState() || in_array($this->status, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting])), + ->disabled(fn () => $server->isInConflictState() || !$this->status->isStartable()), Action::make('restart') ->color('gray') ->size(ActionSize::ExtraLarge) ->action(fn () => $this->dispatch('setServerState', state: 'restart')) - ->disabled(fn () => $server->isInConflictState() || $this->status !== ContainerStatus::Running), + ->disabled(fn () => $server->isInConflictState() || !$this->status->isRestartable()), Action::make('stop') ->color('danger') ->size(ActionSize::ExtraLarge) ->action(fn () => $this->dispatch('setServerState', state: 'stop')) - ->hidden(fn () => in_array($this->status, [ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Starting])) - ->disabled(fn () => $server->isInConflictState() || in_array($this->status, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline])), + ->hidden(fn () => $this->status->isStartingOrStopping() || $this->status->isKillable()) + ->disabled(fn () => $server->isInConflictState() || !$this->status->isStoppable()), Action::make('kill') ->color('danger') ->requiresConfirmation() @@ -94,8 +96,7 @@ class Console extends Page ->modalSubmitActionLabel('Kill Server') ->size(ActionSize::ExtraLarge) ->action(fn () => $this->dispatch('setServerState', state: 'kill')) - ->hidden(fn () => $server->isInConflictState() || in_array($this->status, [ContainerStatus::Running, ContainerStatus::Restarting, ContainerStatus::Offline, ContainerStatus::Removing, ContainerStatus::Dead, ContainerStatus::Exited, ContainerStatus::Created])) - ->disabled(fn () => $server->isInConflictState() || $this->status === ContainerStatus::Offline), + ->hidden(fn () => $server->isInConflictState() || !$this->status->isKillable()), ]; } } diff --git a/app/Filament/Server/Widgets/ServerConsole.php b/app/Filament/Server/Widgets/ServerConsole.php index 786a5aa5a..851b4b3a3 100644 --- a/app/Filament/Server/Widgets/ServerConsole.php +++ b/app/Filament/Server/Widgets/ServerConsole.php @@ -88,7 +88,7 @@ class ServerConsole extends Widget } } - #[On('storeStats')] + #[On('store-stats')] public function storeStats(string $data): void { $data = json_decode($data); diff --git a/app/Livewire/ServerConflictBanner.php b/app/Livewire/ServerConflictBanner.php new file mode 100644 index 000000000..a67901b71 --- /dev/null +++ b/app/Livewire/ServerConflictBanner.php @@ -0,0 +1,34 @@ +server = $server; + } + + #[On('console-install-completed')] + #[On('console-install-started')] + #[On('console-status')] + public function refresh(?string $state = null): void + { + $this->server->fresh(); + } + + public function render(): View + { + return view('livewire.server-conflict-banner'); + } +} diff --git a/resources/views/filament/components/server-console.blade.php b/resources/views/filament/components/server-console.blade.php index 6d3c99f09..726ba3971 100644 --- a/resources/views/filament/components/server-console.blade.php +++ b/resources/views/filament/components/server-console.blade.php @@ -126,7 +126,7 @@ case 'status': handlePowerChangeEvent(args[0]); - $wire.dispatch('powerChanged', {state: args[0]}) + $wire.dispatch('console-status', {state: args[0]}) break; case 'transfer status': handleTransferStatus(args[0]); @@ -135,7 +135,7 @@ handleDaemonErrorOutput(args[0]); break; case 'stats': - $wire.dispatchSelf('storeStats', { data: args[0] }); + $wire.dispatchSelf('store-stats', { data: args[0] }); break; case 'auth success': socket.send(JSON.stringify({ @@ -143,6 +143,12 @@ 'args': [null] })); break; + case 'install started': + $wire.dispatch('console-install-started'); + break; + case 'install completed': + $wire.dispatch('console-install-completed'); + break; case 'token expiring': case 'token expired': token = '{{ $this->getToken() }}'; diff --git a/resources/views/filament/server-conflict-banner.blade.php b/resources/views/filament/server-conflict-banner.blade.php index 9bbe493e1..357b12797 100644 --- a/resources/views/filament/server-conflict-banner.blade.php +++ b/resources/views/filament/server-conflict-banner.blade.php @@ -1,19 +1 @@ -@php - $shouldShow = false; - - try { - \Filament\Facades\Filament::getTenant()->validateCurrentState(); - } catch (\App\Exceptions\Http\Server\ServerStateConflictException $exception) { - $shouldShow = true; - $message = $exception->getMessage(); - } -@endphp - -@if ($shouldShow) -
-
- -

{!! $message !!}

-
-
-@endif \ No newline at end of file + diff --git a/resources/views/livewire/server-conflict-banner.blade.php b/resources/views/livewire/server-conflict-banner.blade.php new file mode 100644 index 000000000..d4bdd1cc9 --- /dev/null +++ b/resources/views/livewire/server-conflict-banner.blade.php @@ -0,0 +1,21 @@ +@php + $shouldShow = false; + + try { + $server->validateCurrentState(); + } catch (\App\Exceptions\Http\Server\ServerStateConflictException $exception) { + $shouldShow = true; + $message = $exception->getMessage(); + } +@endphp + +
+ @if ($shouldShow) +
+
+ +

{!! $message !!}

+
+
+ @endif +