From a761a48d403d0f4df3e3317314be0abd62ef66d6 Mon Sep 17 00:00:00 2001 From: joakotorgaa <113573012+ByCoquito@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:19:26 -0300 Subject: [PATCH 1/2] Add allocation port visibility option --- .../AllocationsRelationManager.php | 5 ++ .../Resources/Servers/Pages/ListServers.php | 4 +- .../Allocations/AllocationResource.php | 9 ++-- .../Server/Widgets/ServerOverview.php | 2 +- .../Servers/NetworkAllocationController.php | 9 ++-- app/Models/Allocation.php | 15 ++++++ .../Api/Application/AllocationTransformer.php | 1 + .../Api/Client/AllocationTransformer.php | 1 + ...038_add_show_port_to_allocations_table.php | 22 +++++++++ lang/en/admin/server.php | 1 + .../server-entry-placeholder.blade.php | 2 +- .../views/livewire/server-entry.blade.php | 2 +- .../Allocation/DeleteAllocationTest.php | 8 +++- .../NetworkAllocationControllerTest.php | 12 +++++ tests/Unit/Models/AllocationTest.php | 46 +++++++++++++++++++ 15 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 database/migrations/2026_08_10_144038_add_show_port_to_allocations_table.php create mode 100644 tests/Unit/Models/AllocationTest.php diff --git a/app/Filament/Admin/Resources/Servers/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/Servers/RelationManagers/AllocationsRelationManager.php index d10a2925db..22d574b299 100644 --- a/app/Filament/Admin/Resources/Servers/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/Servers/RelationManagers/AllocationsRelationManager.php @@ -23,6 +23,7 @@ use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextInputColumn; +use Filament\Tables\Columns\ToggleColumn; use Filament\Tables\Table; /** @@ -51,6 +52,8 @@ public function table(Table $table): Table ->label(trans('admin/server.port')) ->searchable() ->sortable(), + ToggleColumn::make('show_port') + ->label(trans('admin/server.show_port')), TextInputColumn::make('ip_alias') ->label(trans('admin/server.alias')) ->placeholder(trans('admin/server.no_alias')) @@ -105,6 +108,7 @@ public function table(Table $table): Table $allocation->update([ 'notes' => null, 'is_locked' => false, + 'show_port' => true, ]); if (!$this->getOwnerRecord()->allocation_id) { @@ -118,6 +122,7 @@ public function table(Table $table): Table Allocation::whereNull('server_id')->update([ 'notes' => null, 'is_locked' => false, + 'show_port' => true, ]); if (!$this->getOwnerRecord()->allocation_id) { diff --git a/app/Filament/App/Resources/Servers/Pages/ListServers.php b/app/Filament/App/Resources/Servers/Pages/ListServers.php index 69a25a1233..10b6270041 100644 --- a/app/Filament/App/Resources/Servers/Pages/ListServers.php +++ b/app/Filament/App/Resources/Servers/Pages/ListServers.php @@ -83,12 +83,12 @@ protected function tableColumns(): array ->grow() ->searchable() ->sortable(), - TextColumn::make('allocation.address') + TextColumn::make('allocation.display_address') ->label('') ->badge() ->visibleFrom('md') ->copyable() - ->state(fn (Server $server) => $server->allocation->address ?? 'None'), + ->state(fn (Server $server) => $server->allocation->display_address ?? 'None'), ProgressBarColumn::make('cpuUsage') ->label('') ->warningThresholdPercent(static::WARNING_THRESHOLD) diff --git a/app/Filament/Server/Resources/Allocations/AllocationResource.php b/app/Filament/Server/Resources/Allocations/AllocationResource.php index 5ce49991f0..4480b1a1d5 100644 --- a/app/Filament/Server/Resources/Allocations/AllocationResource.php +++ b/app/Filament/Server/Resources/Allocations/AllocationResource.php @@ -54,7 +54,9 @@ public static function defaultTable(Table $table): Table TextColumn::make('alias') ->hidden(), TextColumn::make('port') - ->label(trans('server/network.port')), + ->label(trans('server/network.port')) + ->state(fn (Allocation $allocation) => $allocation->show_port ? $allocation->port : null) + ->placeholder('—'), TextInputColumn::make('notes') ->label(trans('server/network.notes')) ->visibleFrom('sm') @@ -88,12 +90,13 @@ public static function defaultTable(Table $table): Table Allocation::where('id', $allocation->id)->update([ 'notes' => null, 'is_locked' => false, + 'show_port' => true, 'server_id' => null, ]); Activity::event('server:allocation.delete') ->subject($allocation) - ->property('allocation', $allocation->address) + ->property('allocation', $allocation->display_address) ->log(); }) ->after(fn (Allocation $allocation) => $allocation->id === $server->allocation_id && $server->update(['allocation_id' => $server->allocations()->first()?->id])), @@ -116,7 +119,7 @@ public static function defaultTable(Table $table): Table Activity::event('server:allocation.create') ->subject($allocation) - ->property('allocation', $allocation->address) + ->property('allocation', $allocation->display_address) ->log(); }), ]); diff --git a/app/Filament/Server/Widgets/ServerOverview.php b/app/Filament/Server/Widgets/ServerOverview.php index 3bbffac6dd..6952d4bf03 100644 --- a/app/Filament/Server/Widgets/ServerOverview.php +++ b/app/Filament/Server/Widgets/ServerOverview.php @@ -20,7 +20,7 @@ protected function getStats(): array SmallStatBlock::make(trans('server/console.labels.name'), $this->server->name) ->copyable(), SmallStatBlock::make(trans('server/console.labels.status'), $this->status()), - SmallStatBlock::make(trans('server/console.labels.address'), $this->server?->allocation->address ?? 'None') + SmallStatBlock::make(trans('server/console.labels.address'), $this->server?->allocation->display_address ?? 'None') ->copyable(), SmallStatBlock::make(trans('server/console.labels.cpu'), $this->cpuUsage()), SmallStatBlock::make(trans('server/console.labels.memory'), $this->memoryUsage()), diff --git a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php index 8f43e0028a..f7a16bd28f 100644 --- a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php +++ b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php @@ -63,7 +63,7 @@ public function update(UpdateAllocationRequest $request, Server $server, Allocat if ($original !== $allocation->notes) { Activity::event('server:allocation.notes') ->subject($allocation) - ->property(['allocation' => $allocation->address, 'old' => $original, 'new' => $allocation->notes]) + ->property(['allocation' => $allocation->display_address, 'old' => $original, 'new' => $allocation->notes]) ->log(); } @@ -88,7 +88,7 @@ public function setPrimary(SetPrimaryAllocationRequest $request, Server $server, Activity::event('server:allocation.primary') ->subject($allocation) - ->property('allocation', $allocation->address) + ->property('allocation', $allocation->display_address) ->log(); return $this->fractal->item($allocation) @@ -114,7 +114,7 @@ public function store(NewAllocationRequest $request, Server $server): array $allocation = $this->assignableAllocationService->handle($server); - $log->subject($allocation)->property('allocation', $allocation->address); + $log->subject($allocation)->property('allocation', $allocation->display_address); return $allocation; }); @@ -139,12 +139,13 @@ public function delete(DeleteAllocationRequest $request, Server $server, Allocat Allocation::query()->where('id', $allocation->id)->update([ 'notes' => null, + 'show_port' => true, 'server_id' => null, ]); Activity::event('server:allocation.delete') ->subject($allocation) - ->property('allocation', $allocation->address) + ->property('allocation', $allocation->display_address) ->log(); return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); diff --git a/app/Models/Allocation.php b/app/Models/Allocation.php index 986fade4a7..00e848c0a0 100644 --- a/app/Models/Allocation.php +++ b/app/Models/Allocation.php @@ -24,8 +24,10 @@ * @property string|null $ip_alias * @property string|null $notes * @property bool $is_locked + * @property bool $show_port * @property-read string $address * @property-read string $alias + * @property-read string $display_address * @property-read bool $has_alias * @property-read Node $node * @property-read Server|null $server @@ -43,6 +45,7 @@ * @method static Builder|Allocation whereNotes($value) * @method static Builder|Allocation wherePort($value) * @method static Builder|Allocation whereServerId($value) + * @method static Builder|Allocation whereShowPort($value) * @method static Builder|Allocation whereUpdatedAt($value) */ class Allocation extends Model @@ -58,6 +61,7 @@ class Allocation extends Model protected $attributes = [ 'is_locked' => false, + 'show_port' => true, ]; /** @@ -74,6 +78,7 @@ class Allocation extends Model 'server_id' => ['nullable', 'exists:servers,id'], 'notes' => ['nullable', 'string', 'max:256'], 'is_locked' => ['boolean'], + 'show_port' => ['boolean'], ]; protected static function booted(): void @@ -81,6 +86,7 @@ protected static function booted(): void static::updating(function (self $allocation) { if (is_null($allocation->server_id)) { $allocation->is_locked = false; + $allocation->show_port = true; } }); @@ -96,6 +102,7 @@ protected function casts(): array 'port' => 'integer', 'server_id' => 'integer', 'is_locked' => 'bool', + 'show_port' => 'bool', ]; } @@ -123,6 +130,14 @@ protected function address(): Attribute ); } + /** @return Attribute */ + protected function displayAddress(): Attribute + { + return Attribute::make( + get: fn () => $this->show_port ? $this->address : $this->alias, + ); + } + /** * Gets information for the server associated with this allocation. */ diff --git a/app/Transformers/Api/Application/AllocationTransformer.php b/app/Transformers/Api/Application/AllocationTransformer.php index d4deaaced5..68cd1ba3b8 100644 --- a/app/Transformers/Api/Application/AllocationTransformer.php +++ b/app/Transformers/Api/Application/AllocationTransformer.php @@ -33,6 +33,7 @@ public function transform($allocation): array 'ip' => $allocation->ip, 'alias' => $allocation->ip_alias, 'port' => $allocation->port, + 'show_port' => $allocation->show_port, 'notes' => $allocation->notes, 'assigned' => !is_null($allocation->server_id), ]; diff --git a/app/Transformers/Api/Client/AllocationTransformer.php b/app/Transformers/Api/Client/AllocationTransformer.php index 553412ec1d..58db21ba91 100644 --- a/app/Transformers/Api/Client/AllocationTransformer.php +++ b/app/Transformers/Api/Client/AllocationTransformer.php @@ -24,6 +24,7 @@ public function transform($model): array 'ip' => $model->ip, 'ip_alias' => $model->ip_alias, 'port' => $model->port, + 'show_port' => $model->show_port, 'notes' => $model->notes, 'is_default' => $model->server->allocation_id === $model->id, ]; diff --git a/database/migrations/2026_08_10_144038_add_show_port_to_allocations_table.php b/database/migrations/2026_08_10_144038_add_show_port_to_allocations_table.php new file mode 100644 index 0000000000..8e07148348 --- /dev/null +++ b/database/migrations/2026_08_10_144038_add_show_port_to_allocations_table.php @@ -0,0 +1,22 @@ +boolean('show_port')->default(true)->after('port'); + }); + } + + public function down(): void + { + Schema::table('allocations', function (Blueprint $table) { + $table->dropColumn('show_port'); + }); + } +}; diff --git a/lang/en/admin/server.php b/lang/en/admin/server.php index a3e34b417f..d29df107b4 100644 --- a/lang/en/admin/server.php +++ b/lang/en/admin/server.php @@ -13,6 +13,7 @@ 'ip_address_helper' => 'Usually your machine\'s public IP unless you are port forwarding.', 'port' => 'Port', 'ports' => 'Ports', + 'show_port' => 'Show port', 'alias' => 'Alias', 'alias_helper' => 'Optional display name to help you remember what these are.', 'no_alias' => 'No Alias', diff --git a/resources/views/livewire/server-entry-placeholder.blade.php b/resources/views/livewire/server-entry-placeholder.blade.php index 92bcc4ce21..5f7339b9ec 100644 --- a/resources/views/livewire/server-entry-placeholder.blade.php +++ b/resources/views/livewire/server-entry-placeholder.blade.php @@ -100,7 +100,7 @@ diff --git a/resources/views/livewire/server-entry.blade.php b/resources/views/livewire/server-entry.blade.php index 43c0729301..5aa4998dc8 100644 --- a/resources/views/livewire/server-entry.blade.php +++ b/resources/views/livewire/server-entry.blade.php @@ -130,7 +130,7 @@ class="relative cursor-pointer" diff --git a/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php b/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php index 4dd0e38e6e..65246c8080 100644 --- a/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php +++ b/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php @@ -27,11 +27,17 @@ public function test_allocation_can_be_deleted_from_server(array $permission): v 'server_id' => $server->id, 'node_id' => $server->node_id, 'notes' => 'hodor', + 'show_port' => false, ]); $this->actingAs($user)->deleteJson($this->link($allocation))->assertStatus(Response::HTTP_NO_CONTENT); - $this->assertDatabaseHas('allocations', ['id' => $allocation->id, 'server_id' => null, 'notes' => null]); + $this->assertDatabaseHas('allocations', [ + 'id' => $allocation->id, + 'server_id' => null, + 'notes' => null, + 'show_port' => true, + ]); } /** diff --git a/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php b/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php index 09499041a5..dd707ec46b 100644 --- a/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php +++ b/tests/Integration/Api/Client/Server/NetworkAllocationControllerTest.php @@ -27,6 +27,18 @@ public function test_server_allocations_are_returned(): void $this->assertJsonTransformedWith($response->json('data.0.attributes'), $server->allocation); } + public function test_port_visibility_preference_is_returned(): void + { + [$user, $server] = $this->generateTestAccount(); + $server->allocation->update(['show_port' => false]); + + $this->actingAs($user) + ->getJson($this->link($server, '/network/allocations')) + ->assertOk() + ->assertJsonPath('data.0.attributes.port', $server->allocation->port) + ->assertJsonPath('data.0.attributes.show_port', false); + } + /** * Test that allocations cannot be returned without the required user permissions. */ diff --git a/tests/Unit/Models/AllocationTest.php b/tests/Unit/Models/AllocationTest.php new file mode 100644 index 0000000000..0f9dbb1e5f --- /dev/null +++ b/tests/Unit/Models/AllocationTest.php @@ -0,0 +1,46 @@ + $ip, + 'ip_alias' => $alias, + 'port' => 25565, + 'show_port' => $showPort, + ]); + + $this->assertSame($expected, $allocation->display_address); + } + + public function test_port_is_shown_by_default(): void + { + $allocation = new Allocation([ + 'ip' => '192.0.2.1', + 'port' => 25565, + ]); + + $this->assertTrue($allocation->show_port); + $this->assertSame('192.0.2.1:25565', $allocation->display_address); + } + + public static function displayAddressDataProvider(): array + { + return [ + 'IPv4 with port' => ['192.0.2.1', null, true, '192.0.2.1:25565'], + 'IPv4 without port' => ['192.0.2.1', null, false, '192.0.2.1'], + 'IPv6 with port' => ['2001:db8::1', null, true, '[2001:db8::1]:25565'], + 'IPv6 without port' => ['2001:db8::1', null, false, '2001:db8::1'], + 'alias with port' => ['192.0.2.1', 'play.example.com', true, 'play.example.com:25565'], + 'alias without port' => ['192.0.2.1', 'play.example.com', false, 'play.example.com'], + ]; + } +} From 3432d9d4b3eb8ff53528fe0c7972ea74596f5468 Mon Sep 17 00:00:00 2001 From: joakotorgaa <113573012+ByCoquito@users.noreply.github.com> Date: Wed, 12 Aug 2026 13:19:26 -0300 Subject: [PATCH 2/2] Address allocation visibility review feedback --- .../Client/Servers/NetworkAllocationController.php | 1 + app/Models/Allocation.php | 2 +- .../Server/Allocation/DeleteAllocationTest.php | 2 ++ tests/Unit/Models/AllocationTest.php | 12 ++++++++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php index f7a16bd28f..4ff2b1f311 100644 --- a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php +++ b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php @@ -138,6 +138,7 @@ public function delete(DeleteAllocationRequest $request, Server $server, Allocat throw_if(empty($server->allocation_limit), new DisplayException('You cannot delete allocations for this server: no allocation limit is set.')); Allocation::query()->where('id', $allocation->id)->update([ + 'is_locked' => false, 'notes' => null, 'show_port' => true, 'server_id' => null, diff --git a/app/Models/Allocation.php b/app/Models/Allocation.php index 00e848c0a0..389b0137c5 100644 --- a/app/Models/Allocation.php +++ b/app/Models/Allocation.php @@ -134,7 +134,7 @@ protected function address(): Attribute protected function displayAddress(): Attribute { return Attribute::make( - get: fn () => $this->show_port ? $this->address : $this->alias, + get: fn () => $this->show_port ? $this->address : ($this->ip_alias ?? $this->ip), ); } diff --git a/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php b/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php index 65246c8080..271d30ad48 100644 --- a/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php +++ b/tests/Integration/Api/Client/Server/Allocation/DeleteAllocationTest.php @@ -26,6 +26,7 @@ public function test_allocation_can_be_deleted_from_server(array $permission): v $allocation = Allocation::factory()->create([ 'server_id' => $server->id, 'node_id' => $server->node_id, + 'is_locked' => true, 'notes' => 'hodor', 'show_port' => false, ]); @@ -34,6 +35,7 @@ public function test_allocation_can_be_deleted_from_server(array $permission): v $this->assertDatabaseHas('allocations', [ 'id' => $allocation->id, + 'is_locked' => false, 'server_id' => null, 'notes' => null, 'show_port' => true, diff --git a/tests/Unit/Models/AllocationTest.php b/tests/Unit/Models/AllocationTest.php index 0f9dbb1e5f..5480106005 100644 --- a/tests/Unit/Models/AllocationTest.php +++ b/tests/Unit/Models/AllocationTest.php @@ -32,6 +32,18 @@ public function test_port_is_shown_by_default(): void $this->assertSame('192.0.2.1:25565', $allocation->display_address); } + public function test_hidden_port_falls_back_to_ip_when_alias_is_missing(): void + { + $allocation = new Allocation([ + 'ip' => '192.0.2.1', + 'ip_alias' => null, + 'port' => 25565, + 'show_port' => false, + ]); + + $this->assertSame('192.0.2.1', $allocation->display_address); + } + public static function displayAddressDataProvider(): array { return [