diff --git a/app/Filament/Resources/Monitors/MonitorResource.php b/app/Filament/Resources/Monitors/MonitorResource.php index bdf032c..99d44f4 100644 --- a/app/Filament/Resources/Monitors/MonitorResource.php +++ b/app/Filament/Resources/Monitors/MonitorResource.php @@ -414,6 +414,18 @@ public static function table(Table $table): Table ->selectable(false) ->paginated([50, 100, 250]) ->defaultPaginationPageOption(50) + ->searchable() + ->searchPlaceholder('Search all monitors') + ->searchUsing(function (Builder $query, string $search): void { + $like = '%'.$search.'%'; + + $query->where(function (Builder $query) use ($like): void { + $query->where('name', 'like', $like) + ->orWhere('target', 'like', $like) + ->orWhere('description', 'like', $like) + ->orWhere('tags', 'like', $like); + }); + }) ->filters([ SelectFilter::make('status') ->options(MonitorStatus::class) diff --git a/app/Filament/Tables/Columns/MonitorCardColumn.php b/app/Filament/Tables/Columns/MonitorCardColumn.php index 95b0e90..515d96f 100644 --- a/app/Filament/Tables/Columns/MonitorCardColumn.php +++ b/app/Filament/Tables/Columns/MonitorCardColumn.php @@ -5,7 +5,6 @@ namespace App\Filament\Tables\Columns; use Filament\Tables\Columns\Column; -use Illuminate\Database\Eloquent\Builder; final class MonitorCardColumn extends Column { @@ -15,17 +14,6 @@ protected function setUp(): void { parent::setUp(); - $this->label('Monitor') - ->searchable(query: function (Builder $query, string $search): Builder { - $like = '%'.$search.'%'; - - return $query->where(function (Builder $query) use ($like): void { - $query->where('name', 'like', $like) - ->orWhere('target', 'like', $like) - ->orWhere('description', 'like', $like) - ->orWhere('tags', 'like', $like); - }); - }) - ->sortable(); + $this->label('Monitor')->sortable(); } } diff --git a/tests/Feature/Filament/MonitorResourceTest.php b/tests/Feature/Filament/MonitorResourceTest.php index ce702dd..a1ee722 100644 --- a/tests/Feature/Filament/MonitorResourceTest.php +++ b/tests/Feature/Filament/MonitorResourceTest.php @@ -81,6 +81,56 @@ ->and($table->getDefaultGroup())->toBeNull(); }); +it('searches monitors across all pages by name, target, description, and tags', function () { + $user = User::factory()->create(); + + Monitor::factory()->count(50)->sequence(fn ($sequence) => [ + 'name' => sprintf('AAA Page One %03d', $sequence->index), + ])->create(); + + $hidden = Monitor::factory()->create([ + 'name' => 'ZZZ Cross Page Monitor', + 'target' => 'https://unique-cross-page.example/health', + 'description' => 'findme-by-description-across-pages', + 'tags' => ['cross-page-search'], + ]); + + Livewire::actingAs($user) + ->test(ListMonitors::class) + ->loadTable() + ->assertCanNotSeeTableRecords([$hidden]) + ->searchTable('ZZZ Cross Page Monitor') + ->assertCanSeeTableRecords([$hidden]); + + Livewire::actingAs($user) + ->test(ListMonitors::class) + ->loadTable() + ->searchTable('unique-cross-page') + ->assertCanSeeTableRecords([$hidden]); + + Livewire::actingAs($user) + ->test(ListMonitors::class) + ->loadTable() + ->searchTable('findme-by-description-across-pages') + ->assertCanSeeTableRecords([$hidden]); + + Livewire::actingAs($user) + ->test(ListMonitors::class) + ->loadTable() + ->searchTable('cross-page-search') + ->assertCanSeeTableRecords([$hidden]); + + $firstPageMonitor = Monitor::query()->orderBy('name')->first(); + + Livewire::actingAs($user) + ->test(ListMonitors::class) + ->loadTable() + ->call('gotoPage', 2) + ->assertCanNotSeeTableRecords([$firstPageMonitor]) + ->searchTable($firstPageMonitor->name) + ->assertCanSeeTableRecords([$firstPageMonitor]); +}); + it('lazy-loads widgets and defers table records', function () { $user = User::factory()->create();