diff --git a/app/Filament/Resources/ServerResource.php b/app/Filament/Resources/ServerResource.php index 1bc68bfda..cecc729bc 100644 --- a/app/Filament/Resources/ServerResource.php +++ b/app/Filament/Resources/ServerResource.php @@ -4,9 +4,11 @@ namespace App\Filament\Resources; use App\Filament\Resources\ServerResource\Pages; use App\Filament\Resources\ServerResource\RelationManagers; +use App\Models\Allocation; use App\Models\Egg; use App\Models\Node; use App\Models\Server; +use App\Services\Allocations\AssignmentService; use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\Resource; @@ -14,6 +16,7 @@ use Filament\Tables; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Support\HtmlString; class ServerResource extends Resource { @@ -26,82 +29,247 @@ class ServerResource extends Resource public static function form(Form $form): Form { return $form - ->columns(4) + ->columns(6) ->schema([ - Forms\Components\TextInput::make('external_id')->maxLength(191)->hidden(), + Forms\Components\TextInput::make('external_id') + ->maxLength(191) + ->hidden(), + Forms\Components\TextInput::make('name') - ->columnSpanFull() + ->label('Display Name') + ->columnSpan(4) ->required() ->maxLength(191), + + Forms\Components\Select::make('owner_id') + ->default(auth()->user()->id) + ->label('Owner') + ->columnSpan(2) + ->relationship('user', 'username') + ->searchable() + ->preload() + ->required(), + Forms\Components\Select::make('node_id') + ->columnSpan(2) + ->live() ->relationship('node', 'name') ->searchable() ->preload() ->required(), - Forms\Components\Select::make('egg_id') - ->relationship('egg', 'name') - ->searchable() - ->preload() - ->live() - ->required(), - Forms\Components\Select::make('owner_id') - ->relationship('user', 'username') - ->searchable() - ->preload() - ->default(auth()->user()->id) - ->required(), + Forms\Components\Select::make('allocation_id') - ->relationship('allocation', 'address') - ->searchable() + ->label('Primary Allocation') + ->columnSpan(3) + ->disabled(fn (Forms\Get $get) => $get('node_id') === null) + ->searchable(['ip', 'port', 'ip_alias']) + ->getOptionLabelFromRecordUsing(fn (Allocation $allocation) => + "$allocation->ip:$allocation->port" . + ($allocation->ip_alias ? " ($allocation->ip_alias)" : '') + ) + ->placeholder(function (Forms\Get $get) { + $node = Node::find($get('node_id')); + + if ($node?->allocations) { + return 'Select an Allocation'; + } + + return 'Create a New Allocation'; + }) + ->relationship( + 'allocation', + 'ip', + fn (Builder $query, Forms\Get $get) => $query->where('node_id', $get('node_id')), + ) + ->createOptionForm([ + Forms\Components\TextInput::make('allocation_ip') + ->label('IP Address') + ->required(), + Forms\Components\TextInput::make('allocation_alias') + ->label('Alias') + ->required(false), + Forms\Components\TagsInput::make('allocation_ports') + ->placeholder('Examples: 27015, 27017-27019') + ->label('Ports') + ->required(), + ]) + ->createOptionUsing(function (array $data, Forms\Get $get): int { + return collect( + resolve(AssignmentService::class)->handle(Node::find($get('node_id')), $data) + )->first(); + }) ->required(), + Forms\Components\Textarea::make('description') ->hidden() ->default('') ->required() ->columnSpanFull(), - Forms\Components\Toggle::make('skip_scripts') - ->required(), - Forms\Components\TextInput::make('memory') - ->required() - ->numeric(), - Forms\Components\TextInput::make('swap') - ->required() - ->numeric(), - Forms\Components\TextInput::make('disk') - ->required() - ->numeric(), - Forms\Components\TextInput::make('io') - ->default(500) - ->required() - ->numeric(), - Forms\Components\TextInput::make('cpu') - ->required() - ->numeric(), - Forms\Components\TextInput::make('threads') - ->maxLength(191), - Forms\Components\TextInput::make('oom_disabled') - ->required() - ->numeric() - ->default(0), - Forms\Components\Select::make('startup') - ->required() - ->columnSpanFull(), + Forms\Components\Select::make('egg_id') + ->columnSpan(2) + ->relationship('egg', 'name') + ->searchable() + ->preload() + ->live() + ->afterStateUpdated(fn ($state, Forms\Set $set) => $set('startup', Egg::find($state)->startup)) + ->required(), + + Forms\Components\ToggleButtons::make('skip_scripts') + ->label('Run Egg Install Script?') + ->default(false) + ->options([ + false => 'Yes', + true => 'Skip', + ]) + ->colors([ + false => 'primary', + true => 'danger', + ]) + ->inline() + ->required(), Forms\Components\Select::make('image') ->options(fn (Forms\Get $get) => array_flip(Egg::find($get('egg_id'))->docker_images ?? [])) ->selectablePlaceholder(false) ->required(), - Forms\Components\TextInput::make('allocation_limit') - ->numeric(), - Forms\Components\TextInput::make('database_limit') - ->numeric() - ->default(0), - Forms\Components\TextInput::make('backup_limit') + Forms\Components\TextInput::make('image') + ->label('Docker Image') + ->placeholder('Or enter a custom Image...') + ->columnSpan(2) + ->required(), + + Forms\Components\Fieldset::make('Application Feature Limits') + ->inlineLabel() + ->hiddenOn('create') + ->columns(3) + ->schema([ + Forms\Components\TextInput::make('allocation_limit') + ->required() + ->numeric() + ->default(0), + Forms\Components\TextInput::make('database_limit') + ->required() + ->numeric() + ->default(0), + Forms\Components\TextInput::make('backup_limit') + ->required() + ->numeric() + ->default(0), + ]), + + Forms\Components\Fieldset::make('Resource Management') + // ->inlineLabel() + ->hiddenOn('create') + ->columns(3) + ->schema([ + Forms\Components\TextInput::make('memory') + ->default(0) + ->label('Allocated Memory') + ->suffix('MB') + ->required() + ->numeric(), + + Forms\Components\TextInput::make('swap') + ->default(0) + ->label('Swap Memory') + ->suffix('MB') + ->helperText('0 disables swap and -1 allows unlimited swap') + ->minValue(-1) + ->required() + ->numeric(), + + Forms\Components\TextInput::make('disk') + ->default(0) + ->label('Disk Space Limit') + ->suffix('MB') + ->required() + ->numeric(), + + + Forms\Components\TextInput::make('cpu') + ->default(0) + ->label('CPU Limit') + ->suffix('%') + ->required() + ->numeric(), + + Forms\Components\TextInput::make('threads') + ->hint('Advanced') + ->hintColor('danger') + ->helperText('Examples: 0, 0-1,3, or 0,1,3,4') + ->label('CPU Pinning') + ->suffixIcon('tabler-cpu') + ->maxLength(191), + + Forms\Components\TextInput::make('io') + ->helperText('The IO performance relative to other running containers') + ->label('Block IO Proportion') + ->required() + ->minValue(10) + ->maxValue(1000) + ->step(10) + ->default(500) + ->numeric(), + + Forms\Components\ToggleButtons::make('oom_disabled') + ->label('OOM Killer') + ->inline() + ->default(false) + ->options([ + false => 'Disabled', + true => 'Enabled', + ]) + ->colors([ + false => 'success', + true => 'danger', + ]) + ->required(), + ]), + + Forms\Components\Textarea::make('startup') + ->label('Startup Command') ->required() - ->numeric() - ->default(0), + ->rows(1) + ->columnSpanFull(), + + + Forms\Components\Repeater::make('s') + ->reorderable(false) + ->addable(false) + ->deletable(false) + ->label('Egg Variables') + ->columnSpanFull() + ->grid(2) + ->default(function (Forms\Get $get) { + $variables = Egg::find($get('egg_id'))->variables ?? []; + $serverVariables = collect(); + foreach ($variables as $variable) { + $serverVariables->add($variable->toArray()); + } + + return $serverVariables->all(); + }) + // ->relationship('serverVariables') + // ->default([1, 2, 3]) + ->name('name') + // ->itemLabel(fn (array $state) => 'asdf') + ->schema([ + Forms\Components\TextInput::make('value') + ->label(fn (Forms\Get $get) => $get('name')) + ->helperText(fn (Forms\Get $get) => new HtmlString(" + {$get('description')}
+ Access in Startup: {{{$get('env_variable')}}}
+ Validation Rules: {$get('rules')} + ")) + // ->inlineLabel() + ->maxLength(191), +// Forms\Components\Textarea::make('description')->columnSpanFull(), +// Forms\Components\TextInput::make('env_variable')->maxLength(191), +// Forms\Components\TextInput::make('default_value')->maxLength(191), +// Forms\Components\Textarea::make('rules')->rows(3)->columnSpanFull()->required(), + ]) ]); }