mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 22:14:45 +02:00
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
This commit is contained in:
parent
7c6b3a03db
commit
885e03ee06
@ -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 [
|
||||
|
@ -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)]);
|
||||
}
|
||||
|
41
app/Livewire/AlertBanner.php
Normal file
41
app/Livewire/AlertBanner.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Filament\Notifications\Concerns;
|
||||
use Filament\Support\Concerns\EvaluatesClosures;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
final class AlertBanner implements Arrayable
|
||||
{
|
||||
use Concerns\HasBody;
|
||||
use Concerns\HasIcon;
|
||||
use Concerns\HasStatus;
|
||||
use Concerns\HasTitle;
|
||||
use EvaluatesClosures;
|
||||
|
||||
public static function make(): static
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'title' => $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;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Server;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Component;
|
||||
|
||||
class ServerConflictBanner extends Component
|
||||
{
|
||||
public ?Server $server = null;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
$this->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');
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
|
@ -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(
|
||||
|
@ -0,0 +1,11 @@
|
||||
@php
|
||||
$alertBanners = session()->get('alert-banners', []);
|
||||
@endphp
|
||||
|
||||
@if (isset($alertBanners))
|
||||
<div class="flex flex-col gap-4 p-3 mt-3 mb-3">
|
||||
@foreach ($alertBanners as $alertBanner)
|
||||
@include('filament.alerts.alert-banner', ['alertBanner' => $alertBanner])
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
40
resources/views/filament/alerts/alert-banner.blade.php
Normal file
40
resources/views/filament/alerts/alert-banner.blade.php
Normal file
@ -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
|
||||
|
||||
<div class="{{$colorClasses}} flex p-4 rounded-xl shadow-lg bg-white dark:bg-gray-900 ring-1 ring-gray-950/5 dark:ring-white/10">
|
||||
@if (filled($icon))
|
||||
<x-filament::icon :icon="$icon" class="h-8 w-8 mr-2" color="{{$status}}" />
|
||||
@endif
|
||||
|
||||
<div class="flex flex-col flex-grow">
|
||||
@if (filled($title))
|
||||
<p class="font-bold">{{str($title)->sanitizeHtml()->toHtmlString()}}</p>
|
||||
@endif
|
||||
|
||||
@if (filled($body))
|
||||
<p class="font-normal">{{str($body)->sanitizeHtml()->toHtmlString()}}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endisset
|
@ -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() }}';
|
||||
|
@ -1 +0,0 @@
|
||||
<livewire:server-conflict-banner />
|
@ -1,21 +0,0 @@
|
||||
@php
|
||||
$shouldShow = false;
|
||||
|
||||
try {
|
||||
$server->validateCurrentState();
|
||||
} catch (\App\Exceptions\Http\Server\ServerStateConflictException $exception) {
|
||||
$shouldShow = true;
|
||||
$message = $exception->getMessage();
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div id="server-conflict-banner">
|
||||
@if ($shouldShow)
|
||||
<div class="mt-2 p-2 rounded-lg text-white" style="background-color: #D97706;">
|
||||
<div class="flex items-center">
|
||||
<x-filament::icon icon="tabler-alert-triangle" class="h-6 w-6 mr-2 text-gray-500 dark:text-gray-400 text-white" />
|
||||
<p>{!! $message !!}</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user