diff --git a/app/Filament/Admin/Resources/Nodes/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/Nodes/RelationManagers/AllocationsRelationManager.php index 1c1be7ce0..f7b090298 100644 --- a/app/Filament/Admin/Resources/Nodes/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/Nodes/RelationManagers/AllocationsRelationManager.php @@ -3,7 +3,7 @@ namespace App\Filament\Admin\Resources\Nodes\RelationManagers; use App\Filament\Admin\Resources\Servers\Pages\CreateServer; -use App\Filament\Components\Actions\BulkUpdateAllocationIpAction; +use App\Filament\Components\Actions\UpdateNodeAllocations; use App\Models\Allocation; use App\Models\Node; use App\Services\Allocations\AssignmentService; @@ -81,7 +81,9 @@ class AllocationsRelationManager extends RelationManager ->searchable() ->label(trans('admin/node.table.ip')), ]) - ->headerActions([ + ->toolbarActions([ + DeleteBulkAction::make() + ->authorize(fn () => user()?->can('update', $this->getOwnerRecord())), Action::make('create new allocation') ->label(trans('admin/node.create_allocation')) ->schema(fn () => [ @@ -119,12 +121,9 @@ class AllocationsRelationManager extends RelationManager ->required(), ]) ->action(fn (array $data, AssignmentService $service) => $service->handle($this->getOwnerRecord(), $data)), - ]) - ->groupedBulkActions([ - BulkUpdateAllocationIpAction::make() + UpdateNodeAllocations::make() ->availableIps($this->getOwnerRecord()->ipAddresses()) - ->authorize(fn () => user()?->can('update', $this->getOwnerRecord())), - DeleteBulkAction::make() + ->forNode($this->getOwnerRecord()->id) ->authorize(fn () => user()?->can('update', $this->getOwnerRecord())), ]); } diff --git a/app/Filament/Components/Actions/BulkUpdateAllocationIpAction.php b/app/Filament/Components/Actions/UpdateNodeAllocations.php similarity index 67% rename from app/Filament/Components/Actions/BulkUpdateAllocationIpAction.php rename to app/Filament/Components/Actions/UpdateNodeAllocations.php index b3f604276..8c3aede5f 100644 --- a/app/Filament/Components/Actions/BulkUpdateAllocationIpAction.php +++ b/app/Filament/Components/Actions/UpdateNodeAllocations.php @@ -4,12 +4,12 @@ namespace App\Filament\Components\Actions; use App\Models\Allocation; use Exception; -use Filament\Actions\BulkAction; +use Filament\Actions\Action; use Filament\Forms\Components\Select; use Filament\Notifications\Notification; use Illuminate\Database\Eloquent\Collection; -class BulkUpdateAllocationIpAction extends BulkAction +class UpdateNodeAllocations extends Action { public static function getDefaultName(): ?string { @@ -36,34 +36,32 @@ class BulkUpdateAllocationIpAction extends BulkAction $this->modalSubmitActionLabel(trans('admin/node.update_ip')); - $this->schema(function (Collection $records) { - $currentIps = $records->pluck('ip')->unique()->values()->all(); + $this->schema(function () { + $currentIps = $this->getOldIps(); $availableIps = $this->getAvailableIps(); return [ Select::make('old_ip') ->label(trans('admin/node.old_ip')) - ->options(array_combine($currentIps, $currentIps)) + ->options(array_combine($currentIps, $currentIps) ?: []) ->required() - ->helperText(trans('admin/node.old_ip_help')) ->live(), Select::make('new_ip') ->label(trans('admin/node.new_ip')) - ->options(fn () => array_combine($availableIps, $availableIps)) + ->options(fn () => array_combine($availableIps, $availableIps) ?: []) ->required() - ->helperText(trans('admin/node.new_ip_help')) ->different('old_ip'), ]; }); - $this->action(function (Collection $records, array $data) { - /** @var Collection $records */ + $this->action(function (array $data) { $oldIp = $data['old_ip']; $newIp = $data['new_ip']; + $nodeId = $this->nodeId; - $recordsToUpdate = $records->filter(fn (Allocation $allocation) => $allocation->ip === $oldIp); + $allocations = Allocation::where('node_id', $nodeId)->where('ip', $oldIp)->get(); - if ($recordsToUpdate->count() === 0) { + if ($allocations->count() === 0) { Notification::make() ->title(trans('admin/node.no_allocations_to_update')) ->warning() @@ -75,8 +73,7 @@ class BulkUpdateAllocationIpAction extends BulkAction $updated = 0; $failed = 0; - /** @var Allocation $allocation */ - foreach ($recordsToUpdate as $allocation) { + foreach ($allocations as $allocation) { try { $allocation->update(['ip' => $newIp]); $updated++; @@ -87,19 +84,22 @@ class BulkUpdateAllocationIpAction extends BulkAction } Notification::make() - ->title(trans('admin/node.ip_updated', ['count' => $updated, 'total' => $recordsToUpdate->count()])) + ->title(trans('admin/node.ip_updated', ['count' => $updated, 'total' => $allocations->count()])) ->body($failed > 0 ? trans('admin/node.ip_update_failed', ['count' => $failed]) : null) ->status($failed > 0 ? 'warning' : 'success') ->persistent() ->send(); }); - - $this->deselectRecordsAfterCompletion(); } /** @var string[] */ protected array $availableIps = []; + /** @var string[] */ + protected array $oldIps = []; + + protected ?int $nodeId = null; + /** @param string[] $ips */ public function availableIps(array $ips): static { @@ -108,9 +108,42 @@ class BulkUpdateAllocationIpAction extends BulkAction return $this; } + /** @param string[] $ips */ + public function oldIps(array $ips): static + { + $this->oldIps = $ips; + + return $this; + } + + public function forNode(int $nodeId): static + { + $this->nodeId = $nodeId; + + return $this; + } + /** @return string[] */ protected function getAvailableIps(): array { return $this->availableIps; } + + /** @return string[] */ + protected function getOldIps(): array + { + if (!empty($this->oldIps)) { + return $this->oldIps; + } + + if ($this->nodeId) { + return Allocation::where('node_id', $this->nodeId) + ->pluck('ip') + ->unique() + ->values() + ->all(); + } + + return []; + } } diff --git a/lang/en/admin/node.php b/lang/en/admin/node.php index ad16abe44..b66094bc8 100644 --- a/lang/en/admin/node.php +++ b/lang/en/admin/node.php @@ -122,14 +122,12 @@ return [ 'body' => 'Your Node is not accessible by Cloudflare', ], - 'bulk_update_ip' => 'Bulk Update IP', - 'bulk_update_ip_description' => 'Replace an old IP address with a new one for selected allocations. This is useful when a node\'s IP address changes.', + 'bulk_update_ip' => 'Update IPs', + 'bulk_update_ip_description' => 'Replace an old IP address with a new one for allocations. This is useful when a node\'s IP address changes', 'update_ip' => 'Update IP', 'old_ip' => 'Old IP Address', - 'old_ip_help' => 'Select the IP address you want to replace.', 'new_ip' => 'New IP Address', - 'new_ip_help' => 'Select the new IP address to use.', - 'no_allocations_to_update' => 'No allocations with the selected old IP address were found.', - 'ip_updated' => 'Successfully updated :count of :total allocation(s).', - 'ip_update_failed' => ':count allocation(s) failed to update.', + 'no_allocations_to_update' => 'No allocations with the selected old IP address were found', + 'ip_updated' => 'Successfully updated :count of :total allocation(s)', + 'ip_update_failed' => ':count allocation(s) failed to update', ];