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 <charles@pelican.dev>
This commit is contained in:
MartinOscar 2024-07-20 17:38:34 +02:00 committed by GitHub
parent dfba8e3993
commit acf43f2826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 95 additions and 8 deletions

View File

@ -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([

View File

@ -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.
<br />
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'),

View File

@ -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:'),

View File

@ -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,
];
}