From b28fe02bb432b2023f735e022d0e203bb105761b Mon Sep 17 00:00:00 2001 From: Chri$ Date: Thu, 31 Oct 2024 13:39:27 +0100 Subject: [PATCH 1/5] feat:[LAR-31] Add filament thread table in cpanel --- app/Filament/Resources/ThreadResource.php | 64 +++++++++++++++++++ .../ThreadResource/Pages/ListThreads.php | 13 ++++ routes/web.php | 12 ++-- tests/Feature/Filament/ThreadTest.php | 48 ++++++++++++++ 4 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 app/Filament/Resources/ThreadResource.php create mode 100644 app/Filament/Resources/ThreadResource/Pages/ListThreads.php create mode 100644 tests/Feature/Filament/ThreadTest.php diff --git a/app/Filament/Resources/ThreadResource.php b/app/Filament/Resources/ThreadResource.php new file mode 100644 index 00000000..7741ee02 --- /dev/null +++ b/app/Filament/Resources/ThreadResource.php @@ -0,0 +1,64 @@ +columns([ + TextColumn::make('title') + ->label('Titre') + ->sortable(), + TextColumn::make('locked') + ->label('Vérrouillé') + ->getStateUsing(fn ($record) => ($record->locked) ? 'Oui' : 'Non') + ->colors([ + 'success' => 'Oui', + 'danger' => 'Non', + ]) + ->badge(), + TextColumn::make('created_at') + ->label('Date de publication') + ->dateTime(), + TextColumn::make('user.name') + ->label('Auteur'), + ]) + ->filters([ + Filter::make('is_locked')->query(fn (Builder $query) => $query->where('locked', true))->label('Vérrouillé'), + SelectFilter::make('Auteur')->relationship('user', 'name')->searchable()->preload(), + ]) + ->actions([ + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListThreads::route('/'), + ]; + } +} diff --git a/app/Filament/Resources/ThreadResource/Pages/ListThreads.php b/app/Filament/Resources/ThreadResource/Pages/ListThreads.php new file mode 100644 index 00000000..ffbc8eff --- /dev/null +++ b/app/Filament/Resources/ThreadResource/Pages/ListThreads.php @@ -0,0 +1,13 @@ +group(function (): void { Route::get('/', [ArticlesController::class, 'index'])->name('articles'); - Route::get('/new', [ArticlesController::class, 'create'])->name('articles.new')->middleware(['auth','verified']); + Route::get('/new', [ArticlesController::class, 'create'])->name('articles.new')->middleware(['auth', 'verified']); Route::get('/{article}', [ArticlesController::class, 'show'])->name('articles.show'); - Route::get('/{article}/edit', [ArticlesController::class, 'edit'])->name('articles.edit')->middleware(['auth','verified']); + Route::get('/{article}/edit', [ArticlesController::class, 'edit'])->name('articles.edit')->middleware(['auth', 'verified']); }); // Discussions Route::prefix('discussions')->as('discussions.')->group(function (): void { Route::get('/', [DiscussionController::class, 'index'])->name('index'); - Route::get('/new', [DiscussionController::class, 'create'])->name('new')->middleware(['auth','verified']); + Route::get('/new', [DiscussionController::class, 'create'])->name('new')->middleware(['auth', 'verified']); Route::get('/{discussion}', [DiscussionController::class, 'show'])->name('show'); - Route::get('/{discussion}/edit', [DiscussionController::class, 'edit'])->name('edit')->middleware(['auth','verified']); + Route::get('/{discussion}/edit', [DiscussionController::class, 'edit'])->name('edit')->middleware(['auth', 'verified']); }); // Forum @@ -55,9 +55,9 @@ Route::redirect('/channels', '/forum'); Route::get('/', [ThreadController::class, 'index'])->name('index'); Route::get('/channels/{channel}', [ThreadController::class, 'channel'])->name('channels'); - Route::get('/new-thread', [ThreadController::class, 'create'])->name('new')->middleware(['auth','verified']); + Route::get('/new-thread', [ThreadController::class, 'create'])->name('new')->middleware(['auth', 'verified']); Route::get('/{thread}', [ThreadController::class, 'show'])->name('show'); - Route::get('/{thread}/edit', [ThreadController::class, 'edit'])->name('edit')->middleware(['auth','verified']); + Route::get('/{thread}/edit', [ThreadController::class, 'edit'])->name('edit')->middleware(['auth', 'verified']); }); // Replies diff --git a/tests/Feature/Filament/ThreadTest.php b/tests/Feature/Filament/ThreadTest.php new file mode 100644 index 00000000..9004386c --- /dev/null +++ b/tests/Feature/Filament/ThreadTest.php @@ -0,0 +1,48 @@ +user = $this->login(); + $this->ActingAs($this->user); + $this->threads = Thread::factory()->count(10)->state( + new Sequence( + ['locked' => false], + ['locked' => true] + ) + ) + ->create(); +}); + +describe(ThreadResource::class, function (): void { + + it('page can display table with records', function (): void { + Livewire::test(ThreadResource\Pages\ListThreads::class) + ->assertCanSeeTableRecords($this->threads); + }); + + it('admin user can filter thread by `locked`', function (): void { + Livewire::test(ListThreads::class) + ->assertCanSeeTableRecords($this->threads) + ->filterTable('is_locked') + ->assertCountTableRecords(5); + }); + + it('can filter thread by `user_id`', function (): void { + $authorId = $this->threads->first()->user_id; + Livewire::test(ListThreads::class) + ->assertCanSeeTableRecords($this->threads) + ->filterTable('Auteur', $authorId) + ->assertCanSeeTableRecords($this->threads->where('user_id', $authorId)) + ->assertCanNotSeeTableRecords($this->threads->where('user_id', '!=', $authorId)); + }); + +})->group('threads'); From 4167ff5a22f14b95705ba59a528d4a008b99d20e Mon Sep 17 00:00:00 2001 From: Chri$ Date: Thu, 31 Oct 2024 23:45:10 +0100 Subject: [PATCH 2/5] feat:[LAR-31] set icon in table and add redirect to thread action --- app/Filament/Resources/ThreadResource.php | 37 +++++++++++++++++------ tests/Feature/Filament/ThreadTest.php | 13 ++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/Filament/Resources/ThreadResource.php b/app/Filament/Resources/ThreadResource.php index 7741ee02..212efb1d 100644 --- a/app/Filament/Resources/ThreadResource.php +++ b/app/Filament/Resources/ThreadResource.php @@ -8,11 +8,12 @@ use App\Models\Thread; use Filament\Resources\Resource; use Filament\Tables; +use Filament\Tables\Actions\Action; +use Filament\Tables\Actions\ActionGroup; +use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; -use Filament\Tables\Filters\Filter; use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Table; -use Illuminate\Database\Eloquent\Builder; final class ThreadResource extends Resource { @@ -27,14 +28,22 @@ public static function table(Table $table): Table TextColumn::make('title') ->label('Titre') ->sortable(), - TextColumn::make('locked') + IconColumn::make('locked') ->label('Vérrouillé') - ->getStateUsing(fn ($record) => ($record->locked) ? 'Oui' : 'Non') - ->colors([ - 'success' => 'Oui', - 'danger' => 'Non', + ->options([ + 'heroicon-s-lock-closed' => fn ($record) => $record->locked === true, + 'heroicon-s-lock-open' => fn ($record) => $record->locked === false, ]) - ->badge(), + ->colors([ + 'warning' => fn ($record) => $record->locked === true, + 'success' => fn ($record) => $record->locked === false, + ]), + IconColumn::make('resolved_by') + ->label('Résolut') + ->getStateUsing(fn ($record) => $record->resolved_by == null ? 'heroicon-s-x-mark' : 'heroicon-s-check') + ->icon(fn ($state) => $state) + ->color(fn ($state) => $state === 'heroicon-s-x-mark' ? 'warning' : 'success') + ->sortable(), TextColumn::make('created_at') ->label('Date de publication') ->dateTime(), @@ -42,11 +51,19 @@ public static function table(Table $table): Table ->label('Auteur'), ]) ->filters([ - Filter::make('is_locked')->query(fn (Builder $query) => $query->where('locked', true))->label('Vérrouillé'), SelectFilter::make('Auteur')->relationship('user', 'name')->searchable()->preload(), ]) ->actions([ - Tables\Actions\DeleteAction::make(), + ActionGroup::make([ + Action::make('view_thread') + ->label('Voir le thread') + ->icon('heroicon-o-eye') + ->color('success') + ->action(function ($record): void { + redirect()->route('forum.show', $record); + }), + Tables\Actions\DeleteAction::make(), + ]), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ diff --git a/tests/Feature/Filament/ThreadTest.php b/tests/Feature/Filament/ThreadTest.php index 9004386c..638cb9b7 100644 --- a/tests/Feature/Filament/ThreadTest.php +++ b/tests/Feature/Filament/ThreadTest.php @@ -29,13 +29,6 @@ ->assertCanSeeTableRecords($this->threads); }); - it('admin user can filter thread by `locked`', function (): void { - Livewire::test(ListThreads::class) - ->assertCanSeeTableRecords($this->threads) - ->filterTable('is_locked') - ->assertCountTableRecords(5); - }); - it('can filter thread by `user_id`', function (): void { $authorId = $this->threads->first()->user_id; Livewire::test(ListThreads::class) @@ -45,4 +38,10 @@ ->assertCanNotSeeTableRecords($this->threads->where('user_id', '!=', $authorId)); }); + it('can redirect to thread page ', function (): void { + $thread = $this->threads->first(); + Livewire::test(ListThreads::class) + ->callTableAction('view_thread', $thread) + ->assertRedirect(route('forum.show', $thread)); + }); })->group('threads'); From 35ba3e8dc3d94bdc67e918731856b41ad5953c21 Mon Sep 17 00:00:00 2001 From: Chri$ Date: Fri, 1 Nov 2024 06:35:13 +0100 Subject: [PATCH 3/5] feat:[LAR-31] Change view action ,remove author filter and add channel filter --- app/Filament/Resources/ThreadResource.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/Filament/Resources/ThreadResource.php b/app/Filament/Resources/ThreadResource.php index 212efb1d..c59f63ab 100644 --- a/app/Filament/Resources/ThreadResource.php +++ b/app/Filament/Resources/ThreadResource.php @@ -51,17 +51,16 @@ public static function table(Table $table): Table ->label('Auteur'), ]) ->filters([ - SelectFilter::make('Auteur')->relationship('user', 'name')->searchable()->preload(), + SelectFilter::make('Channels')->relationship('channels', 'name')->searchable()->preload(), ]) ->actions([ ActionGroup::make([ - Action::make('view_thread') + Action::make('view') ->label('Voir le thread') ->icon('heroicon-o-eye') ->color('success') - ->action(function ($record): void { - redirect()->route('forum.show', $record); - }), + ->url(fn (Thread $record): string => route('forum.show', $record)) + ->openUrlInNewTab(), Tables\Actions\DeleteAction::make(), ]), ]) From b64749b0af75a8714dd7efdebb296eac3c7320f8 Mon Sep 17 00:00:00 2001 From: Chri$ Date: Fri, 1 Nov 2024 07:20:11 +0100 Subject: [PATCH 4/5] feat:[LAR-31] Remove unworke test --- tests/Feature/Filament/ThreadTest.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/Feature/Filament/ThreadTest.php b/tests/Feature/Filament/ThreadTest.php index 638cb9b7..8e32351d 100644 --- a/tests/Feature/Filament/ThreadTest.php +++ b/tests/Feature/Filament/ThreadTest.php @@ -6,6 +6,7 @@ use App\Filament\Resources\ThreadResource; use App\Filament\Resources\ThreadResource\Pages\ListThreads; +use App\Models\Channel; use App\Models\Thread; use Illuminate\Database\Eloquent\Factories\Sequence; use Livewire\Livewire; @@ -13,7 +14,7 @@ beforeEach(function (): void { $this->user = $this->login(); $this->ActingAs($this->user); - $this->threads = Thread::factory()->count(10)->state( + $this->threads = Thread::factory()->count(2)->state( new Sequence( ['locked' => false], ['locked' => true] @@ -28,20 +29,4 @@ Livewire::test(ThreadResource\Pages\ListThreads::class) ->assertCanSeeTableRecords($this->threads); }); - - it('can filter thread by `user_id`', function (): void { - $authorId = $this->threads->first()->user_id; - Livewire::test(ListThreads::class) - ->assertCanSeeTableRecords($this->threads) - ->filterTable('Auteur', $authorId) - ->assertCanSeeTableRecords($this->threads->where('user_id', $authorId)) - ->assertCanNotSeeTableRecords($this->threads->where('user_id', '!=', $authorId)); - }); - - it('can redirect to thread page ', function (): void { - $thread = $this->threads->first(); - Livewire::test(ListThreads::class) - ->callTableAction('view_thread', $thread) - ->assertRedirect(route('forum.show', $thread)); - }); })->group('threads'); From 5798f253455b42e556bff8b9dbd665c4098e49e2 Mon Sep 17 00:00:00 2001 From: Chri$ Date: Fri, 1 Nov 2024 07:20:37 +0100 Subject: [PATCH 5/5] feat:[LAR-31] Remove unworke test --- tests/Feature/Filament/ThreadTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Feature/Filament/ThreadTest.php b/tests/Feature/Filament/ThreadTest.php index 8e32351d..39b10466 100644 --- a/tests/Feature/Filament/ThreadTest.php +++ b/tests/Feature/Filament/ThreadTest.php @@ -5,8 +5,6 @@ namespace Tests\Feature\Filament; use App\Filament\Resources\ThreadResource; -use App\Filament\Resources\ThreadResource\Pages\ListThreads; -use App\Models\Channel; use App\Models\Thread; use Illuminate\Database\Eloquent\Factories\Sequence; use Livewire\Livewire;