From acf43f28267cab6a269272a9a938f49840616dbf Mon Sep 17 00:00:00 2001 From: MartinOscar <40749467+RMartinOscar@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:38:34 +0200 Subject: [PATCH] Ability to create allocations on EditServer page (#494) * Ability to create allocation on edit page + Ability to assign allocation to server on creation * Disable dehydrate for readonly * set these to false --------- Co-authored-by: notCharles --- .../ServerResource/Pages/EditServer.php | 6 +- .../AllocationsRelationManager.php | 88 ++++++++++++++++++- .../UserResource/Pages/EditProfile.php | 2 + .../Allocations/AssignmentService.php | 7 +- 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/app/Filament/Resources/ServerResource/Pages/EditServer.php b/app/Filament/Resources/ServerResource/Pages/EditServer.php index 7c6ee83a9..c229f658c 100644 --- a/app/Filament/Resources/ServerResource/Pages/EditServer.php +++ b/app/Filament/Resources/ServerResource/Pages/EditServer.php @@ -124,7 +124,8 @@ class EditServer extends EditRecord 'md' => 2, 'lg' => 3, ]) - ->readOnly(), + ->readOnly() + ->dehydrated(false), Forms\Components\TextInput::make('uuid_short') ->label('Short UUID') ->hintAction(CopyAction::make()) @@ -134,7 +135,8 @@ class EditServer extends EditRecord 'md' => 2, 'lg' => 3, ]) - ->readOnly(), + ->readOnly() + ->dehydrated(false), Forms\Components\TextInput::make('external_id') ->label('External ID') ->columnSpan([ diff --git a/app/Filament/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index d2615a481..cbac9bf92 100644 --- a/app/Filament/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -4,11 +4,15 @@ namespace App\Filament\Resources\ServerResource\RelationManagers; use App\Models\Allocation; use App\Models\Server; -use Filament\Forms; +use App\Services\Allocations\AssignmentService; +use Filament\Forms\Components\TagsInput; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Set; use Filament\Forms\Form; use Filament\Resources\RelationManagers\RelationManager; use Filament\Tables; use Filament\Tables\Table; +use Illuminate\Support\HtmlString; /** * @method Server getOwnerRecord() @@ -21,7 +25,7 @@ class AllocationsRelationManager extends RelationManager { return $form ->schema([ - Forms\Components\TextInput::make('ip') + TextInput::make('ip') ->required() ->maxLength(255), ]); @@ -62,9 +66,87 @@ class AllocationsRelationManager extends RelationManager ->label(fn (Allocation $allocation) => $allocation->id === $this->getOwnerRecord()->allocation_id ? '' : 'Make Primary'), ]) ->headerActions([ - //TODO Tables\Actions\CreateAction::make()->label('Create Allocation'), + Tables\Actions\CreateAction::make()->label('Create Allocation') + ->createAnother(false) + ->form(fn () => [ + TextInput::make('allocation_ip') + ->datalist($this->getOwnerRecord()->node->ipAddresses()) + ->label('IP Address') + ->inlineLabel() + ->ipv4() + ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->required(), + TextInput::make('allocation_alias') + ->label('Alias') + ->inlineLabel() + ->default(null) + ->helperText('Optional display name to help you remember what these are.') + ->required(false), + TagsInput::make('allocation_ports') + ->placeholder('Examples: 27015, 27017-27019') + ->helperText(new HtmlString(' + These are the ports that users can connect to this Server through. +
+ You would have to port forward these on your home network. + ')) + ->label('Ports') + ->inlineLabel() + ->live() + ->afterStateUpdated(function ($state, Set $set) { + $ports = collect(); + $update = false; + foreach ($state as $portEntry) { + if (!str_contains($portEntry, '-')) { + if (is_numeric($portEntry)) { + $ports->push((int) $portEntry); + + continue; + } + + // Do not add non numerical ports + $update = true; + + continue; + } + + $update = true; + [$start, $end] = explode('-', $portEntry); + if (!is_numeric($start) || !is_numeric($end)) { + continue; + } + + $start = max((int) $start, 0); + $end = min((int) $end, 2 ** 16 - 1); + foreach (range($start, $end) as $i) { + $ports->push($i); + } + } + + $uniquePorts = $ports->unique()->values(); + if ($ports->count() > $uniquePorts->count()) { + $update = true; + $ports = $uniquePorts; + } + + $sortedPorts = $ports->sort()->values(); + if ($sortedPorts->all() !== $ports->all()) { + $update = true; + $ports = $sortedPorts; + } + + $ports = $ports->filter(fn ($port) => $port > 1024 && $port < 65535)->values(); + + if ($update) { + $set('allocation_ports', $ports->all()); + } + }) + ->splitKeys(['Tab', ' ', ',']) + ->required(), + ]) + ->action(fn (array $data) => resolve(AssignmentService::class)->handle($this->getOwnerRecord()->node, $data, $this->getOwnerRecord())), Tables\Actions\AssociateAction::make() ->multiple() + ->associateAnother(false) ->preloadRecordSelect() ->recordSelectOptionsQuery(fn ($query) => $query->whereBelongsTo($this->getOwnerRecord()->node)) ->label('Add Allocation'), diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 7cc2dfde9..d8eb7274f 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -53,6 +53,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ->label(trans('strings.username')) ->disabled() ->readOnly() + ->dehydrated(false) ->maxLength(255) ->unique(ignoreRecord: true) ->autofocus(), @@ -119,6 +120,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile ->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens")) ->rows(10) ->readOnly() + ->dehydrated(false) ->formatStateUsing(fn () => cache()->get("users.{$this->getUser()->id}.2fa.tokens")) ->helperText('These will not be shown again!') ->label('Backup Tokens:'), diff --git a/app/Services/Allocations/AssignmentService.php b/app/Services/Allocations/AssignmentService.php index 3fd0dc27c..33ed4aa74 100644 --- a/app/Services/Allocations/AssignmentService.php +++ b/app/Services/Allocations/AssignmentService.php @@ -5,6 +5,7 @@ namespace App\Services\Allocations; use App\Models\Allocation; use IPTools\Network; use App\Models\Node; +use App\Models\Server; use Illuminate\Database\ConnectionInterface; use App\Exceptions\DisplayException; use App\Exceptions\Service\Allocation\CidrOutOfRangeException; @@ -37,7 +38,7 @@ class AssignmentService * @throws \App\Exceptions\Service\Allocation\PortOutOfRangeException * @throws \App\Exceptions\Service\Allocation\TooManyPortsInRangeException */ - public function handle(Node $node, array $data): array + public function handle(Node $node, array $data, Server $server = null): array { $explode = explode('/', $data['allocation_ip']); if (count($explode) !== 1) { @@ -84,7 +85,7 @@ class AssignmentService 'ip' => $ip->__toString(), 'port' => (int) $unit, 'ip_alias' => array_get($data, 'allocation_alias'), - 'server_id' => null, + 'server_id' => $server->id ?? null, ]; } } else { @@ -97,7 +98,7 @@ class AssignmentService 'ip' => $ip->__toString(), 'port' => (int) $port, 'ip_alias' => array_get($data, 'allocation_alias'), - 'server_id' => null, + 'server_id' => $server->id ?? null, ]; }