diff --git a/app/Filament/Resources/ServerResource.php b/app/Filament/Resources/ServerResource.php index 3cc51a32a..1d20bfd4f 100644 --- a/app/Filament/Resources/ServerResource.php +++ b/app/Filament/Resources/ServerResource.php @@ -445,6 +445,66 @@ class ServerResource extends Resource ]) ->required(), ]), + + Forms\Components\Textarea::make('startup') + ->hintIcon('tabler-code') + ->label('Startup Command') + ->required() + ->live() + ->rows(function ($state) { + return str($state)->explode("\n")->reduce( + fn (int $carry, $line) => $carry + floor(strlen($line) / 125), + 0 + ); + }) + ->columnSpanFull(), + + Forms\Components\KeyValue::make('environment') + ->default([]) + ->columnSpanFull(), + + Forms\Components\Section::make('Egg Variables') + ->icon('tabler-eggs') + ->iconColor('primary') + ->collapsible() + ->collapsed() + ->schema([ + Forms\Components\Placeholder::make('Select an egg first to show its variables!') + ->hidden(fn (Forms\Get $get) => !empty($get('server_variables'))), + + Forms\Components\Repeater::make('server_variables') + ->relationship('serverVariables') + ->grid(2) + ->reorderable(false) + ->addable(false) + ->deletable(false) + ->default([]) + ->hidden(fn ($state) => empty($state)) + ->schema([ + Forms\Components\TextInput::make('variable_value') + ->rules([ + fn (Forms\Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) { + $validator = Validator::make(['validatorkey' => $value], [ + 'validatorkey' => $get('rules'), + ]); + + if ($validator->fails()) { + $message = str($validator->errors()->first())->replace('validatorkey', $get('name')); + + $fail($message); + } + }, + ]) + ->label(fn (Forms\Get $get) => $get('name')) + ->hint(fn (Forms\Get $get) => $get('rules')) + ->prefix(fn (Forms\Get $get) => '{{' . $get('env_variable') . '}}') + ->helperText(fn (Forms\Get $get) => empty($get('description')) ? '—' : $get('description')) + ->maxLength(191), + + Forms\Components\Hidden::make('variable_id')->default(0), + ]) + ->columnSpanFull(), + ]), ]); } diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php index f6655ae98..86072742d 100644 --- a/app/Filament/Resources/UserResource.php +++ b/app/Filament/Resources/UserResource.php @@ -3,8 +3,10 @@ namespace App\Filament\Resources; use App\Filament\Resources\UserResource\Pages; +use App\Filament\Resources\UserResource\RelationManagers; use App\Models\User; use Filament\Forms; +use Filament\Forms\Components\Section; use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; @@ -23,54 +25,56 @@ class UserResource extends Resource { return $form ->schema([ - Forms\Components\TextInput::make('username')->required()->maxLength(191), - Forms\Components\TextInput::make('email')->email()->required()->maxLength(191), + Section::make()->schema([ + Forms\Components\TextInput::make('username')->required()->maxLength(191), + Forms\Components\TextInput::make('email')->email()->required()->maxLength(191), - Forms\Components\TextInput::make('name_first') - ->maxLength(191) - ->hidden(fn (string $operation): bool => $operation === 'create') - ->label('First Name'), - Forms\Components\TextInput::make('name_last') - ->maxLength(191) - ->hidden(fn (string $operation): bool => $operation === 'create') - ->label('Last Name'), + Forms\Components\TextInput::make('name_first') + ->maxLength(191) + ->hidden(fn (string $operation): bool => $operation === 'create') + ->label('First Name'), + Forms\Components\TextInput::make('name_last') + ->maxLength(191) + ->hidden(fn (string $operation): bool => $operation === 'create') + ->label('Last Name'), - Forms\Components\TextInput::make('password') - ->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) - ->dehydrated(fn (?string $state): bool => filled($state)) - ->required(fn (string $operation): bool => $operation === 'create') - ->password(), + Forms\Components\TextInput::make('password') + ->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) + ->dehydrated(fn (?string $state): bool => filled($state)) + ->required(fn (string $operation): bool => $operation === 'create') + ->password(), - Forms\Components\ToggleButtons::make('root_admin') - ->label('Administrator (Root)') - ->options([ - false => 'No', - true => 'Admin', - ]) - ->colors([ - false => 'primary', - true => 'danger', - ]) - ->disableOptionWhen(function (string $operation, $value, User $user) { - if ($operation !== 'edit' || $value) { - return false; - } + Forms\Components\ToggleButtons::make('root_admin') + ->label('Administrator (Root)') + ->options([ + false => 'No', + true => 'Admin', + ]) + ->colors([ + false => 'primary', + true => 'danger', + ]) + ->disableOptionWhen(function (string $operation, $value, User $user) { + if ($operation !== 'edit' || $value) { + return false; + } - return $user->isLastRootAdmin(); - }) - ->hint(fn (User $user) => $user->isLastRootAdmin() ? 'This is the last root administrator!' : '') - ->helperText(fn (User $user) => $user->isLastRootAdmin() ? 'You must have at least one root administrator in your system.' : '') - ->hintColor('warning') - ->inline() - ->required() - ->default(false), + return $user->isLastRootAdmin(); + }) + ->hint(fn (User $user) => $user->isLastRootAdmin() ? 'This is the last root administrator!' : '') + ->helperText(fn (User $user) => $user->isLastRootAdmin() ? 'You must have at least one root administrator in your system.' : '') + ->hintColor('warning') + ->inline() + ->required() + ->default(false), - Forms\Components\Hidden::make('skipValidation')->default(true), - Forms\Components\Select::make('language') - ->required() - ->hidden() - ->default('en') - ->options(fn (User $user) => $user->getAvailableLanguages()), + Forms\Components\Hidden::make('skipValidation')->default(true), + Forms\Components\Select::make('language') + ->required() + ->hidden() + ->default('en') + ->options(fn (User $user) => $user->getAvailableLanguages()), + ])->columns(2), ]); } @@ -130,7 +134,7 @@ class UserResource extends Resource public static function getRelations(): array { return [ - // + RelationManagers\ServersRelationManager::class, ]; } diff --git a/app/Filament/Resources/UserResource/RelationManagers/ServersRelationManager.php b/app/Filament/Resources/UserResource/RelationManagers/ServersRelationManager.php new file mode 100644 index 000000000..f79878065 --- /dev/null +++ b/app/Filament/Resources/UserResource/RelationManagers/ServersRelationManager.php @@ -0,0 +1,55 @@ +searchable(false) + ->columns([ + Tables\Columns\TextColumn::make('uuid') + ->hidden() + ->label('UUID') + ->searchable(), + Tables\Columns\TextColumn::make('name') + ->icon('tabler-brand-docker') + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('node.name') + ->icon('tabler-server-2') + ->url(fn (Server $server): string => route('filament.admin.resources.nodes.edit', ['record' => $server->node])) + ->sortable(), + Tables\Columns\TextColumn::make('egg.name') + ->icon('tabler-egg') + ->url(fn (Server $server): string => route('filament.admin.resources.eggs.edit', ['record' => $server->egg])) + ->sortable(), + Tables\Columns\SelectColumn::make('allocation.id') + ->label('Primary Allocation') + ->options(fn ($state, Server $server) => [$server->allocation->id => $server->allocation->address]) + ->selectablePlaceholder(false) + ->sortable(), + Tables\Columns\TextColumn::make('image')->hidden(), + Tables\Columns\TextColumn::make('databases_count') + ->counts('databases') + ->label('Databases') + ->icon('tabler-database') + ->numeric() + ->sortable(), + Tables\Columns\TextColumn::make('backups_count') + ->counts('backups') + ->label('Backups') + ->icon('tabler-file-download') + ->numeric() + ->sortable(), + ]); + } +}