Refactor admin dashboard to use widgets (#1207)

This commit is contained in:
Boy132 2025-04-04 09:30:00 +02:00 committed by GitHub
parent 484a3b445a
commit c73d0544d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 264 additions and 177 deletions

View File

@ -2,36 +2,13 @@
namespace App\Filament\Admin\Pages;
use App\Filament\Admin\Resources\NodeResource\Pages\CreateNode;
use App\Filament\Admin\Resources\NodeResource\Pages\ListNodes;
use App\Models\Egg;
use App\Models\Node;
use App\Models\Server;
use App\Models\User;
use App\Services\Helpers\SoftwareVersionService;
use Filament\Actions\CreateAction;
use Filament\Pages\Page;
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends Page
class Dashboard extends BaseDashboard
{
protected static ?string $navigationIcon = 'tabler-layout-dashboard';
protected static string $view = 'filament.pages.dashboard';
protected ?string $heading = '';
public function getTitle(): string
{
return trans('admin/dashboard.title');
}
public static function getNavigationLabel(): string
{
return trans('admin/dashboard.title');
}
protected static ?string $slug = '/';
private SoftwareVersionService $softwareVersionService;
public function mount(SoftwareVersionService $softwareVersionService): void
@ -39,51 +16,18 @@ class Dashboard extends Page
$this->softwareVersionService = $softwareVersionService;
}
public function getViewData(): array
public function getColumns(): int
{
return [
'inDevelopment' => config('app.version') === 'canary',
'version' => $this->softwareVersionService->currentPanelVersion(),
'latestVersion' => $this->softwareVersionService->latestPanelVersion(),
'isLatest' => $this->softwareVersionService->isLatestPanel(),
'eggsCount' => Egg::query()->count(),
'nodesList' => ListNodes::getUrl(),
'nodesCount' => Node::query()->count(),
'serversCount' => Server::query()->count(),
'usersCount' => User::query()->count(),
return 1;
}
'devActions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-developers.button_issues'))
->icon('tabler-brand-github')
->url('https://github.com/pelican-dev/panel/issues', true),
],
'updateActions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-update-available.heading'))
->icon('tabler-clipboard-text')
->url('https://pelican.dev/docs/panel/update', true)
->color('warning'),
],
'nodeActions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-first-node.button_label'))
->icon('tabler-server-2')
->url(CreateNode::getUrl()),
],
'supportActions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-support.button_donate'))
->icon('tabler-cash')
->url('https://pelican.dev/donate', true)
->color('success'),
],
'helpActions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-help.button_docs'))
->icon('tabler-speedboat')
->url('https://pelican.dev/docs', true),
],
];
public function getHeading(): string
{
return trans('admin/dashboard.heading');
}
public function getSubheading(): string
{
return trans('admin/dashboard.version', ['version' => $this->softwareVersionService->currentPanelVersion()]);
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Filament\Admin\Widgets;
use Filament\Actions\CreateAction;
use Filament\Widgets\Widget;
class CanaryWidget extends Widget
{
protected static string $view = 'filament.admin.widgets.canary-widget';
protected static bool $isLazy = false;
protected static ?int $sort = 1;
public static function canView(): bool
{
return config('app.version') === 'canary';
}
public function getViewData(): array
{
return [
'actions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-developers.button_issues'))
->icon('tabler-brand-github')
->url('https://github.com/pelican-dev/panel/issues', true),
],
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Filament\Admin\Widgets;
use Filament\Actions\CreateAction;
use Filament\Widgets\Widget;
class HelpWidget extends Widget
{
protected static string $view = 'filament.admin.widgets.help-widget';
protected static bool $isLazy = false;
protected static ?int $sort = 4;
public function getViewData(): array
{
return [
'actions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-help.button_docs'))
->icon('tabler-speedboat')
->url('https://pelican.dev/docs', true),
],
];
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Filament\Admin\Widgets;
use App\Filament\Admin\Resources\NodeResource\Pages\CreateNode;
use App\Models\Node;
use Filament\Actions\CreateAction;
use Filament\Widgets\Widget;
class NoNodesWidget extends Widget
{
protected static string $view = 'filament.admin.widgets.no-nodes-widget';
protected static bool $isLazy = false;
protected static ?int $sort = 2;
public static function canView(): bool
{
return Node::count() <= 0;
}
public function getViewData(): array
{
return [
'actions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-first-node.button_label'))
->icon('tabler-server-2')
->url(CreateNode::getUrl()),
],
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Filament\Admin\Widgets;
use Filament\Actions\CreateAction;
use Filament\Widgets\Widget;
class SupportWidget extends Widget
{
protected static string $view = 'filament.admin.widgets.support-widget';
protected static bool $isLazy = false;
protected static ?int $sort = 3;
public function getViewData(): array
{
return [
'actions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-support.button_donate'))
->icon('tabler-cash')
->url('https://pelican.dev/donate', true)
->color('success'),
],
];
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Filament\Admin\Widgets;
use App\Services\Helpers\SoftwareVersionService;
use Filament\Actions\CreateAction;
use Filament\Widgets\Widget;
class UpdateWidget extends Widget
{
protected static string $view = 'filament.admin.widgets.update-widget';
protected static bool $isLazy = false;
protected static ?int $sort = 0;
private SoftwareVersionService $softwareVersionService;
public function mount(SoftwareVersionService $softwareVersionService): void
{
$this->softwareVersionService = $softwareVersionService;
}
public function getViewData(): array
{
return [
'version' => $this->softwareVersionService->currentPanelVersion(),
'latestVersion' => $this->softwareVersionService->latestPanelVersion(),
'isLatest' => $this->softwareVersionService->isLatestPanel(),
'actions' => [
CreateAction::make()
->label(trans('admin/dashboard.sections.intro-update-available.heading'))
->icon('tabler-clipboard-text')
->url('https://pelican.dev/docs/panel/update', true)
->color('warning'),
],
];
}
}

View File

@ -60,6 +60,7 @@ class AdminPanelProvider extends PanelProvider
->sidebarCollapsibleOnDesktop()
->discoverResources(in: app_path('Filament/Admin/Resources'), for: 'App\\Filament\\Admin\\Resources')
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
->discoverWidgets(in: app_path('Filament/Admin/Widgets'), for: 'App\\Filament\\Admin\\Widgets')
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,

View File

@ -1,10 +1,7 @@
<?php
return [
'title' => 'Dashboard',
'overview' => 'Overview',
'heading' => 'Welcome to Pelican!',
'expand_sections' => 'You can expand the following sections:',
'version' => 'Version: :version',
'advanced' => 'Advanced',
'server' => 'Server',

View File

@ -0,0 +1,19 @@
<x-filament-widgets::widget>
<x-filament::section
icon="tabler-code"
icon-color="primary"
id="intro-developers"
collapsible
persist-collapsed
collapsed
:header-actions="$actions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-developers.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-developers.content') }}</p>
<p><br /></p>
<p>{{ trans('admin/dashboard.sections.intro-developers.extra_note') }}</p>
</x-filament::section>
</x-filament-widgets::widget>

View File

@ -0,0 +1,14 @@
<x-filament-widgets::widget>
<x-filament::section
icon="tabler-question-mark"
icon-color="info"
id="intro-help"
collapsible
persist-collapsed
:header-actions="$actions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-help.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-help.content') }}</p>
</x-filament::section>
</x-filament-widgets::widget>

View File

@ -0,0 +1,14 @@
<x-filament-widgets::widget>
<x-filament::section
icon="tabler-server-2"
icon-color="primary"
id="intro-first-node"
collapsible
persist-collapsed
:header-actions="$actions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-first-node.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-first-node.content') }}</p>
</x-filament::section>
</x-filament-widgets::widget>

View File

@ -0,0 +1,18 @@
<x-filament-widgets::widget>
<x-filament::section
icon="tabler-heart-filled"
icon-color="danger"
id="intro-support"
collapsible
persist-collapsed
:header-actions="$actions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-support.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-support.content') }}</p>
<p><br /></p>
<p>{{ trans('admin/dashboard.sections.intro-support.extra_note') }}</p>
</x-filament::section>
</x-filament-widgets::widget>

View File

@ -0,0 +1,25 @@
<x-filament-widgets::widget>
@if (!$isLatest)
<x-filament::section
icon="tabler-info-circle"
icon-color="warning"
id="intro-update-available"
:header-actions="$actions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-update-available.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-update-available.content', ['latestVersion' => $latestVersion]) }}</p>
</x-filament::section>
@else
<x-filament::section
icon="tabler-checkbox"
icon-color="success"
id="intro-no-update"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-no-update.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-no-update.content', ['version' => $version]) }}</p>
</x-filament::section>
@endif
</x-filament-widgets::widget>

View File

@ -1,105 +0,0 @@
<x-filament-panels::page>
<x-filament-panels::header
:actions="$this->getCachedHeaderActions()"
:breadcrumbs="filament()->hasBreadcrumbs() ? $this->getBreadcrumbs() : []"
:heading=" trans('admin/dashboard.heading')"
:subheading="trans('admin/dashboard.version', ['version' => $version])"
></x-filament-panels::header>
<p>{{ trans('admin/dashboard.expand_sections') }}</p>
@if (!$isLatest)
<x-filament::section
icon="tabler-info-circle"
icon-color="warning"
id="intro-update-available"
:header-actions="$updateActions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-update-available.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-update-available.content', ['latestVersion' => $latestVersion]) }}</p>
</x-filament::section>
@else
<x-filament::section
icon="tabler-checkbox"
icon-color="success"
id="intro-no-update"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-no-update.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-no-update.content', ['version' => $version]) }}</p>
</x-filament::section>
@endif
@if ($inDevelopment)
<x-filament::section
icon="tabler-code"
icon-color="primary"
id="intro-developers"
collapsible
persist-collapsed
collapsed
:header-actions="$devActions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-developers.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-developers.content') }}</p>
<p><br /></p>
<p>{{ trans('admin/dashboard.sections.intro-developers.extra_note') }}</p>
</x-filament::section>
@endif
{{-- No Nodes Created --}}
@if ($nodesCount <= 0)
<x-filament::section
icon="tabler-server-2"
icon-color="primary"
id="intro-first-node"
collapsible
persist-collapsed
:header-actions="$nodeActions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-first-node.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-first-node.content') }}</p>
</x-filament::section>
@endif
{{-- No Nodes Active --}}
<x-filament::section
icon="tabler-heart-filled"
icon-color="danger"
id="intro-support"
collapsible
persist-collapsed
:header-actions="$supportActions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-support.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-support.content') }}</p>
<p><br /></p>
<p>{{ trans('admin/dashboard.sections.intro-support.extra_note') }}</p>
</x-filament::section>
<x-filament::section
icon="tabler-question-mark"
icon-color="info"
id="intro-help"
collapsible
persist-collapsed
:header-actions="$helpActions"
>
<x-slot name="heading">{{ trans('admin/dashboard.sections.intro-help.heading') }}</x-slot>
<p>{{ trans('admin/dashboard.sections.intro-help.content') }}</p>
</x-filament::section>
</x-filament-panels::page>