mirror of
https://github.com/pelican-dev/panel.git
synced 2026-05-04 18:00:48 +03:00
Add traits for customizing tabs (#2101)
This commit is contained in:
9
app/Enums/TabPosition.php
Normal file
9
app/Enums/TabPosition.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum TabPosition: string
|
||||
{
|
||||
case Before = 'before';
|
||||
case After = 'after';
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use App\Notifications\MailTested;
|
||||
use App\Traits\EnvironmentWriterTrait;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use BackedEnum;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
@@ -53,6 +54,7 @@ class Settings extends Page implements HasSchemas
|
||||
CanCustomizeHeaderActions::getHeaderActions insteadof InteractsWithHeaderActions;
|
||||
}
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
use EnvironmentWriterTrait;
|
||||
use InteractsWithForms;
|
||||
|
||||
@@ -96,11 +98,7 @@ class Settings extends Page implements HasSchemas
|
||||
return trans('admin/setting.title');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Component>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
/** @return array<Component> */
|
||||
protected function getFormSchema(): array
|
||||
{
|
||||
return [
|
||||
@@ -108,7 +106,18 @@ class Settings extends Page implements HasSchemas
|
||||
->columns()
|
||||
->persistTabInQueryString()
|
||||
->disabled(fn () => !user()?->can('update settings'))
|
||||
->tabs([
|
||||
->tabs($this->getTabs()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tab[]
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('general')
|
||||
->label(trans('admin/setting.navigation.general'))
|
||||
->icon('tabler-home')
|
||||
@@ -135,7 +144,6 @@ class Settings extends Page implements HasSchemas
|
||||
->label(trans('admin/setting.navigation.misc'))
|
||||
->icon('tabler-tool')
|
||||
->schema($this->miscSettings()),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Filament\Components\Forms\Fields\MonacoEditor;
|
||||
use App\Models\EggVariable;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use Exception;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ActionGroup;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
@@ -37,6 +37,7 @@ class CreateEgg extends CreateRecord
|
||||
{
|
||||
use CanCustomizeHeaderActions;
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
|
||||
protected static string $resource = EggResource::class;
|
||||
|
||||
@@ -57,14 +58,21 @@ class CreateEgg extends CreateRecord
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Tabs::make()->tabs([
|
||||
Tabs::make()
|
||||
->tabs($this->getTabs())
|
||||
->columnSpanFull()
|
||||
->persistTabInQueryString(),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('configuration')
|
||||
->label(trans('admin/egg.tabs.configuration'))
|
||||
->columns(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 4])
|
||||
@@ -131,7 +139,6 @@ class CreateEgg extends CreateRecord
|
||||
->valuePlaceholder('ghcr.io/pelican-eggs/yolks:java_21')
|
||||
->helperText(trans('admin/egg.docker_help')),
|
||||
]),
|
||||
|
||||
Tab::make('process_management')
|
||||
->label(trans('admin/egg.tabs.process_management'))
|
||||
->columns()
|
||||
@@ -275,9 +282,7 @@ class CreateEgg extends CreateRecord
|
||||
->columnSpanFull()
|
||||
->lazy(),
|
||||
]),
|
||||
|
||||
])->columnSpanFull()->persistTabInQueryString(),
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleRecordCreation(array $data): Model
|
||||
|
||||
@@ -12,6 +12,7 @@ use App\Models\Egg;
|
||||
use App\Models\EggVariable;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ActionGroup;
|
||||
@@ -47,17 +48,25 @@ class EditEgg extends EditRecord
|
||||
{
|
||||
use CanCustomizeHeaderActions;
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
|
||||
protected static string $resource = EggResource::class;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Tabs::make()->tabs([
|
||||
Tabs::make()
|
||||
->tabs($this->getTabs())
|
||||
->columnSpanFull()
|
||||
->persistTabInQueryString(),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('configuration')
|
||||
->label(trans('admin/egg.tabs.configuration'))
|
||||
->columns(['default' => 2, 'sm' => 2, 'md' => 4, 'lg' => 6])
|
||||
@@ -430,8 +439,7 @@ class EditEgg extends EditRecord
|
||||
->language(EditorLanguages::shell)
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
])->columnSpanFull()->persistTabInQueryString(),
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/** @return array<Action|ActionGroup> */
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Services\Nodes\NodeAutoDeployService;
|
||||
use App\Services\Nodes\NodeUpdateService;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\DeleteAction;
|
||||
@@ -42,12 +43,12 @@ use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Phiki\Grammar\Grammar;
|
||||
use Throwable;
|
||||
|
||||
class EditNode extends EditRecord
|
||||
{
|
||||
use CanCustomizeHeaderActions;
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
|
||||
protected static string $resource = NodeResource::class;
|
||||
|
||||
@@ -61,9 +62,6 @@ class EditNode extends EditRecord
|
||||
$this->nodeUpdateService = $nodeUpdateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
@@ -76,7 +74,14 @@ class EditNode extends EditRecord
|
||||
])
|
||||
->persistTabInQueryString()
|
||||
->columnSpanFull()
|
||||
->tabs([
|
||||
->tabs($this->getTabs()),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('overview')
|
||||
->label(trans('admin/node.tabs.overview'))
|
||||
->icon('tabler-chart-area-line-filled')
|
||||
@@ -772,8 +777,7 @@ class EditNode extends EditRecord
|
||||
->rows(35)
|
||||
->visible(fn (Get $get) => ($get('pulled') ?? false) || ($get('uploaded') ?? false)),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeFill(array $data): array
|
||||
|
||||
@@ -16,7 +16,6 @@ use App\Models\Egg;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use App\Repositories\Daemon\DaemonServerRepository;
|
||||
use App\Services\Backups\DeleteBackupService;
|
||||
use App\Services\Eggs\EggChangerService;
|
||||
use App\Services\Servers\RandomWordService;
|
||||
use App\Services\Servers\ReinstallServerService;
|
||||
@@ -26,6 +25,7 @@ use App\Services\Servers\ToggleInstallService;
|
||||
use App\Services\Servers\TransferServerService;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ActionGroup;
|
||||
@@ -70,6 +70,7 @@ class EditServer extends EditRecord
|
||||
{
|
||||
use CanCustomizeHeaderActions;
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
|
||||
protected static string $resource = ServerResource::class;
|
||||
|
||||
@@ -80,10 +81,6 @@ class EditServer extends EditRecord
|
||||
$this->daemonServerRepository = $daemonServerRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RandomException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
@@ -97,7 +94,18 @@ class EditServer extends EditRecord
|
||||
'lg' => 6,
|
||||
])
|
||||
->columnSpanFull()
|
||||
->tabs([
|
||||
->tabs($this->getTabs()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tab[]
|
||||
*
|
||||
* @throws RandomException
|
||||
*/
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('information')
|
||||
->label(trans('admin/server.tabs.information'))
|
||||
->icon('tabler-info-circle')
|
||||
@@ -966,7 +974,7 @@ class EditServer extends EditRecord
|
||||
->disabled(fn (Server $server) => user()?->accessibleNodes()->count() <= 1 || $server->isInConflictState())
|
||||
->modalHeading(trans('admin/server.transfer'))
|
||||
->schema($this->transferServer())
|
||||
->action(function (TransferServerService $transfer, DeleteBackupService $deleteBackup, Server $server, $data) {
|
||||
->action(function (TransferServerService $transfer, Server $server, $data) {
|
||||
try {
|
||||
$selectedBackupUuids = Arr::get($data, 'backups', []);
|
||||
$transfer->handle($server, Arr::get($data, 'node_id'), Arr::get($data, 'allocation_id'), Arr::get($data, 'allocation_additional', []), $selectedBackupUuids);
|
||||
@@ -1029,8 +1037,7 @@ class EditServer extends EditRecord
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/** @return Component[]
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\UserSSHKey;
|
||||
use App\Services\Helpers\LanguageService;
|
||||
use App\Traits\Filament\CanCustomizePages;
|
||||
use App\Traits\Filament\CanCustomizeRelations;
|
||||
use App\Traits\Filament\CanCustomizeStaticTabs;
|
||||
use App\Traits\Filament\CanModifyForm;
|
||||
use App\Traits\Filament\CanModifyTable;
|
||||
use DateTimeZone;
|
||||
@@ -59,6 +60,7 @@ class UserResource extends Resource
|
||||
{
|
||||
use CanCustomizePages;
|
||||
use CanCustomizeRelations;
|
||||
use CanCustomizeStaticTabs;
|
||||
use CanModifyForm;
|
||||
use CanModifyTable;
|
||||
|
||||
@@ -146,7 +148,15 @@ class UserResource extends Resource
|
||||
->columns(['default' => 1, 'lg' => 3, 'md' => 2])
|
||||
->components([
|
||||
Tabs::make()
|
||||
->schema([
|
||||
->schema(static::getTabs())
|
||||
->columnSpanFull(),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected static function getDefaultTabs(): array
|
||||
{
|
||||
return [
|
||||
Tab::make('account')
|
||||
->label(trans('profile.tabs.account'))
|
||||
->icon('tabler-user-cog')
|
||||
@@ -332,7 +342,7 @@ class UserResource extends Resource
|
||||
Tab::make('roles')
|
||||
->label(trans('admin/user.roles'))
|
||||
->icon('tabler-users-group')
|
||||
->components([
|
||||
->schema([
|
||||
CheckboxList::make('roles')
|
||||
->hidden(fn (?User $user) => $user && $user->isRootAdmin())
|
||||
->relationship('roles', 'name', fn (Builder $query) => $query->whereNot('id', Role::getRootAdmin()->id))
|
||||
@@ -470,8 +480,7 @@ class UserResource extends Resource
|
||||
->state(fn (ActivityLog $log) => new HtmlString($log->htmlable())),
|
||||
]),
|
||||
]),
|
||||
])->columnSpanFull(),
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/** @return class-string<RelationManager>[] */
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Services\Ssh\KeyCreationService;
|
||||
use App\Services\Users\UserUpdateService;
|
||||
use App\Traits\Filament\CanCustomizeHeaderActions;
|
||||
use App\Traits\Filament\CanCustomizeHeaderWidgets;
|
||||
use App\Traits\Filament\CanCustomizeTabs;
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
@@ -56,6 +57,7 @@ class EditProfile extends BaseEditProfile
|
||||
{
|
||||
use CanCustomizeHeaderActions;
|
||||
use CanCustomizeHeaderWidgets;
|
||||
use CanCustomizeTabs;
|
||||
|
||||
protected OAuthService $oauthService;
|
||||
|
||||
@@ -82,12 +84,24 @@ class EditProfile extends BaseEditProfile
|
||||
*/
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
$oauthSchemas = $this->oauthService->getEnabled();
|
||||
|
||||
return $schema
|
||||
->components([
|
||||
Tabs::make()->persistTabInQueryString()
|
||||
->schema([
|
||||
Tabs::make()
|
||||
->persistTabInQueryString()
|
||||
->tabs($this->getTabs()),
|
||||
])
|
||||
->operation('edit')
|
||||
->model($this->getUser())
|
||||
->statePath('data')
|
||||
->inlineLabel(!static::isSimple());
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
$oauthSchemas = $this->oauthService->getEnabled();
|
||||
|
||||
return [
|
||||
Tab::make('account')
|
||||
->label(trans('profile.tabs.account'))
|
||||
->icon('tabler-user-cog')
|
||||
@@ -540,12 +554,7 @@ class EditProfile extends BaseEditProfile
|
||||
->default(30),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
->operation('edit')
|
||||
->model($this->getUser())
|
||||
->statePath('data')
|
||||
->inlineLabel(!static::isSimple());
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFormActions(): array
|
||||
|
||||
33
app/Traits/Filament/CanCustomizeStaticTabs.php
Normal file
33
app/Traits/Filament/CanCustomizeStaticTabs.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits\Filament;
|
||||
|
||||
use App\Enums\TabPosition;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
trait CanCustomizeStaticTabs
|
||||
{
|
||||
/** @var array<string, Tab[]> */
|
||||
protected static array $customTabs = [];
|
||||
|
||||
public static function registerCustomTabs(TabPosition $position, Tab ...$customTabs): void
|
||||
{
|
||||
static::$customTabs[$position->value] = array_merge(static::$customTabs[$position->value] ?? [], $customTabs);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected static function getDefaultTabs(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected static function getTabs(): array
|
||||
{
|
||||
return array_merge(
|
||||
static::$customTabs[TabPosition::Before->value] ?? [],
|
||||
static::getDefaultTabs(),
|
||||
static::$customTabs[TabPosition::After->value] ?? []
|
||||
);
|
||||
}
|
||||
}
|
||||
33
app/Traits/Filament/CanCustomizeTabs.php
Normal file
33
app/Traits/Filament/CanCustomizeTabs.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits\Filament;
|
||||
|
||||
use App\Enums\TabPosition;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
trait CanCustomizeTabs
|
||||
{
|
||||
/** @var array<string, Tab[]> */
|
||||
protected static array $customTabs = [];
|
||||
|
||||
public static function registerCustomTabs(TabPosition $position, Tab ...$customTabs): void
|
||||
{
|
||||
static::$customTabs[$position->value] = array_merge(static::$customTabs[$position->value] ?? [], $customTabs);
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getDefaultTabs(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @return Tab[] */
|
||||
protected function getTabs(): array
|
||||
{
|
||||
return array_merge(
|
||||
static::$customTabs[TabPosition::Before->value] ?? [],
|
||||
$this->getDefaultTabs(),
|
||||
static::$customTabs[TabPosition::After->value] ?? []
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user