From 885e03ee068c40f081c3fa6bf75f36f2eb496ebe Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 15 Jan 2025 18:23:09 +0100 Subject: [PATCH] Alert banners (#892) * add alert banner * replace old server conflict banner with alert banner * improve color and icon size * add alert for websocket errors * update file loading error to alert banner * remove old events * add back `console-status` event * move @php block under @isset * remove phpstan ignore so I'm not getting force choked --- app/Filament/Server/Pages/Console.php | 18 ++++++++ .../FileResource/Pages/ListFiles.php | 1 - app/Livewire/AlertBanner.php | 41 +++++++++++++++++++ app/Livewire/ServerConflictBanner.php | 34 --------------- app/Models/File.php | 13 ++++-- app/Providers/AppServiceProvider.php | 4 +- .../alerts/alert-banner-container.blade.php | 11 +++++ .../filament/alerts/alert-banner.blade.php | 40 ++++++++++++++++++ .../components/server-console.blade.php | 19 ++++++--- .../filament/server-conflict-banner.blade.php | 1 - .../livewire/server-conflict-banner.blade.php | 21 ---------- 11 files changed, 133 insertions(+), 70 deletions(-) create mode 100644 app/Livewire/AlertBanner.php delete mode 100644 app/Livewire/ServerConflictBanner.php create mode 100644 resources/views/filament/alerts/alert-banner-container.blade.php create mode 100644 resources/views/filament/alerts/alert-banner.blade.php delete mode 100644 resources/views/filament/server-conflict-banner.blade.php delete mode 100644 resources/views/livewire/server-conflict-banner.blade.php diff --git a/app/Filament/Server/Pages/Console.php b/app/Filament/Server/Pages/Console.php index d6b15bce3..a133afa3d 100644 --- a/app/Filament/Server/Pages/Console.php +++ b/app/Filament/Server/Pages/Console.php @@ -3,11 +3,13 @@ namespace App\Filament\Server\Pages; use App\Enums\ContainerStatus; +use App\Exceptions\Http\Server\ServerStateConflictException; use App\Filament\Server\Widgets\ServerConsole; use App\Filament\Server\Widgets\ServerCpuChart; use App\Filament\Server\Widgets\ServerMemoryChart; // use App\Filament\Server\Widgets\ServerNetworkChart; use App\Filament\Server\Widgets\ServerOverview; +use App\Livewire\AlertBanner; use App\Models\Server; use Filament\Actions\Action; use Filament\Facades\Filament; @@ -25,6 +27,22 @@ class Console extends Page public ContainerStatus $status = ContainerStatus::Offline; + public function mount(): void + { + /** @var Server $server */ + $server = Filament::getTenant(); + + try { + $server->validateCurrentState(); + } catch (ServerStateConflictException $exception) { + AlertBanner::make() + ->warning() + ->title('Warning') + ->body($exception->getMessage()) + ->send(); + } + } + public function getWidgetData(): array { return [ diff --git a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php index 9700af26c..7bafed8ca 100644 --- a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php @@ -96,7 +96,6 @@ class ListFiles extends ListRecords ->sortable(), ]) ->recordUrl(function (File $file) use ($server) { - if ($file->is_directory) { return self::getUrl(['path' => join_paths($this->path, $file->name)]); } diff --git a/app/Livewire/AlertBanner.php b/app/Livewire/AlertBanner.php new file mode 100644 index 000000000..068593a0b --- /dev/null +++ b/app/Livewire/AlertBanner.php @@ -0,0 +1,41 @@ + $this->getTitle(), + 'body' => $this->getBody(), + 'status' => $this->getStatus(), + 'icon' => $this->getIcon(), + ]; + } + + public function send(): static + { + $alerts = session()->get('alert-banners', []); + $alerts[] = $this->toArray(); + + session()->flash('alert-banners', $alerts); + + return $this; + } +} diff --git a/app/Livewire/ServerConflictBanner.php b/app/Livewire/ServerConflictBanner.php deleted file mode 100644 index a67901b71..000000000 --- a/app/Livewire/ServerConflictBanner.php +++ /dev/null @@ -1,34 +0,0 @@ -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/app/Models/File.php b/app/Models/File.php index 9f9f6f2aa..e4f96bef2 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -2,10 +2,10 @@ namespace App\Models; +use App\Livewire\AlertBanner; use App\Repositories\Daemon\DaemonFileRepository; use Carbon\Carbon; use Exception; -use Filament\Notifications\Notification; use Illuminate\Database\Eloquent\Builder; use Sushi\Sushi; @@ -160,9 +160,14 @@ class File extends Model } catch (Exception $exception) { report($exception); - Notification::make() - ->title('Error loading files') - ->body($exception->getMessage()) + $message = str($exception->getMessage()); + if ($message->startsWith('cURL error 7: ')) { + $message = $message->after('cURL error 7: ')->before(' after '); + } + + AlertBanner::make() + ->title('Could not load files') + ->body($message->toString()) ->danger() ->send(); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8e4c456d6..d54a449eb 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -5,7 +5,6 @@ namespace App\Providers; use App\Checks\NodeVersionsCheck; use App\Checks\PanelVersionCheck; use App\Checks\UsedDiskSpaceCheck; -use App\Filament\Server\Pages\Console; use App\Models; use App\Models\ApiKey; use App\Models\Node; @@ -117,8 +116,7 @@ class AppServiceProvider extends ServiceProvider FilamentView::registerRenderHook( PanelsRenderHook::CONTENT_START, - fn () => view('filament.server-conflict-banner'), - scopes: Console::class, + fn () => view('filament.alerts.alert-banner-container'), ); FilamentView::registerRenderHook( diff --git a/resources/views/filament/alerts/alert-banner-container.blade.php b/resources/views/filament/alerts/alert-banner-container.blade.php new file mode 100644 index 000000000..e224a6836 --- /dev/null +++ b/resources/views/filament/alerts/alert-banner-container.blade.php @@ -0,0 +1,11 @@ +@php + $alertBanners = session()->get('alert-banners', []); +@endphp + +@if (isset($alertBanners)) +
+ @foreach ($alertBanners as $alertBanner) + @include('filament.alerts.alert-banner', ['alertBanner' => $alertBanner]) + @endforeach +
+@endif diff --git a/resources/views/filament/alerts/alert-banner.blade.php b/resources/views/filament/alerts/alert-banner.blade.php new file mode 100644 index 000000000..efae7e663 --- /dev/null +++ b/resources/views/filament/alerts/alert-banner.blade.php @@ -0,0 +1,40 @@ +@props(['alertBanner']) + +@isset ($alertBanner) + @php + $status = $alertBanner['status']; + + $title = $alertBanner['title']; + $body = $alertBanner['body']; + + $icon = $alertBanner['icon'] ?? match ($status) { + "success" => "tabler-circle-check", + "warning" => "tabler-exclamation-circle", + "danger" => "tabler-circle-x", + default => "tabler-info-circle", + }; + + $colorClasses = match ($status) { + "success" => "text-success-600 dark:text-success-500", + "warning" => "text-warning-600 dark:text-warning-500", + "danger" => "text-danger-600 dark:text-danger-500", + default => "text-info-600 dark:text-info-500", + }; + @endphp + +
+ @if (filled($icon)) + + @endif + +
+ @if (filled($title)) +

{{str($title)->sanitizeHtml()->toHtmlString()}}

+ @endif + + @if (filled($body)) +

{{str($body)->sanitizeHtml()->toHtmlString()}}

+ @endif +
+
+@endisset diff --git a/resources/views/filament/components/server-console.blade.php b/resources/views/filament/components/server-console.blade.php index 3b8a8058d..a27d63885 100644 --- a/resources/views/filament/components/server-console.blade.php +++ b/resources/views/filament/components/server-console.blade.php @@ -113,6 +113,19 @@ const socket = new WebSocket("{{ $this->getSocket() }}"); let token = '{{ $this->getToken() }}'; + socket.onerror = function(websocketErrorEvent) { + @php + $alerts = session()->get('alert-banners', []); + $alerts[] = [ + 'title' => 'Could not connect to websocket!', + 'body' => 'Check your browser console for more details.', + 'status' => 'danger', + ]; + + session()->flash('alert-banners', $alerts); + @endphp + }; + socket.onmessage = function(websocketMessageEvent) { let { event, args } = JSON.parse(websocketMessageEvent.data); @@ -141,12 +154,6 @@ '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 deleted file mode 100644 index 357b12797..000000000 --- a/resources/views/filament/server-conflict-banner.blade.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/views/livewire/server-conflict-banner.blade.php b/resources/views/livewire/server-conflict-banner.blade.php deleted file mode 100644 index d4bdd1cc9..000000000 --- a/resources/views/livewire/server-conflict-banner.blade.php +++ /dev/null @@ -1,21 +0,0 @@ -@php - $shouldShow = false; - - try { - $server->validateCurrentState(); - } catch (\App\Exceptions\Http\Server\ServerStateConflictException $exception) { - $shouldShow = true; - $message = $exception->getMessage(); - } -@endphp - -
- @if ($shouldShow) -
-
- -

{!! $message !!}

-
-
- @endif -