Skip to content

Commit b369e9e

Browse files
committed
feat: [LAR-69] update DiscussionResource
1 parent 5ea1c0c commit b369e9e

File tree

3 files changed

+97
-68
lines changed

3 files changed

+97
-68
lines changed

app/Filament/Resources/DiscussionResource.php

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use App\Models\Discussion;
99
use Filament\Resources\Resource;
1010
use Filament\Tables;
11-
use Filament\Tables\Columns\TextColumn;
1211
use Filament\Tables\Filters\Filter;
1312
use Filament\Tables\Table;
1413
use Illuminate\Database\Eloquent\Builder;
@@ -28,37 +27,41 @@ public static function table(Table $table): Table
2827
{
2928
return $table
3029
->columns([
31-
TextColumn::make('title')
30+
Tables\Columns\TextColumn::make('title')
3231
->label('Titre')
33-
->sortable(),
34-
TextColumn::make('locked')
32+
->limit(50)
33+
->sortable()
34+
->searchable(),
35+
Tables\Columns\TextColumn::make('user.name')
36+
->label('Auteur')
37+
->sortable()
38+
->searchable(),
39+
Tables\Columns\TextColumn::make('count_all_replies_with_child')
40+
->label('Commentaires'),
41+
Tables\Columns\IconColumn::make('locked')
3542
->label('Vérrouillé')
36-
->getStateUsing(fn ($record) => ($record->locked) ? 'Oui' : 'Non')
37-
->colors([
38-
'success' => 'Oui',
39-
'danger' => 'Non',
40-
])
41-
->badge(),
42-
TextColumn::make('is_pinned')
43-
->label('Epinglé')
44-
->getStateUsing(fn ($record) => ($record->is_pinned) ? 'Oui' : 'Non')
45-
->colors([
46-
'success' => 'Oui',
47-
'danger' => 'Non',
48-
])
49-
->badge(),
50-
TextColumn::make('created_at')
51-
->label('Date de création')
52-
->dateTime(),
53-
TextColumn::make('user.name')
54-
->label('Auteur'),
43+
->boolean()
44+
->trueIcon('untitledui-lock-04')
45+
->trueColor('warning')
46+
->falseIcon('untitledui-lock-unlocked-04')
47+
->falseColor('gray'),
48+
Tables\Columns\TextColumn::make('created_at')
49+
->label('Date')
50+
->date(),
5551
])
5652
->filters([
5753
Filter::make('is_pinned')->query(fn (Builder $query) => $query->where('is_pinned', true))->label('Epinglé'),
5854
Filter::make('is_locked')->query(fn (Builder $query) => $query->where('locked', true))->label('Vérrouillé'),
5955
])
6056
->actions([
61-
Tables\Actions\DeleteAction::make(),
57+
Tables\Actions\Action::make('show')
58+
->icon('untitledui-eye')
59+
->iconButton()
60+
->color('gray')
61+
->url(fn (Discussion $record) => route('discussions.show', $record))
62+
->openUrlInNewTab(),
63+
Tables\Actions\DeleteAction::make()
64+
->iconButton(),
6265
])
6366
->bulkActions([
6467
Tables\Actions\BulkActionGroup::make([
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Models\Builders;
6+
7+
use App\Models\Discussion;
8+
use Illuminate\Database\Eloquent\Builder;
9+
10+
/**
11+
* @template TModelClass of Discussion
12+
*/
13+
final class DiscussionQueryBuilder extends Builder
14+
{
15+
public function pinned(): self
16+
{
17+
return $this->where('is_pinned', true);
18+
}
19+
20+
public function notPinned(): self
21+
{
22+
return $this->where('is_pinned', false);
23+
}
24+
25+
public function recent(): self
26+
{
27+
return $this->orderBy('is_pinned', 'desc')
28+
->orderBy('created_at', 'desc');
29+
}
30+
31+
public function popular(): self
32+
{
33+
return $this->withCount('reactions')
34+
->orderBy('reactions_count', 'desc');
35+
}
36+
37+
public function active(): self
38+
{
39+
return $this->withCount(['replies' => function ($query): void {
40+
$query->where('created_at', '>=', now()->subWeek());
41+
}])
42+
->orderBy('replies_count', 'desc');
43+
}
44+
45+
public function noComments(): self
46+
{
47+
return $this->whereDoesntHave('replies')
48+
->orderByDesc('created_at');
49+
}
50+
}

app/Models/Discussion.php

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Contracts\ReactableInterface;
88
use App\Contracts\ReplyInterface;
99
use App\Contracts\SubscribeInterface;
10+
use App\Models\Builders\DiscussionQueryBuilder;
1011
use App\Traits\HasAuthor;
1112
use App\Traits\HasReplies;
1213
use App\Traits\HasSlug;
@@ -18,6 +19,7 @@
1819
use CyrildeWit\EloquentViewable\Contracts\Viewable;
1920
use CyrildeWit\EloquentViewable\InteractsWithViews;
2021
use Illuminate\Database\Eloquent\Builder;
22+
use Illuminate\Database\Eloquent\Casts\Attribute;
2123
use Illuminate\Database\Eloquent\Factories\HasFactory;
2224
use Illuminate\Database\Eloquent\Model;
2325
use Illuminate\Support\Str;
@@ -30,6 +32,7 @@
3032
* @property bool $locked
3133
* @property bool $is_pinned
3234
* @property int $user_id
35+
* @property-read int $count_all_replies_with_child
3336
* @property Carbon $created_at
3437
* @property Carbon $updated_at
3538
* @property User $user
@@ -66,6 +69,11 @@ final class Discussion extends Model implements ReactableInterface, ReplyInterfa
6669

6770
protected bool $removeViewsOnDelete = true;
6871

72+
public function newEloquentBuilder($query): DiscussionQueryBuilder
73+
{
74+
return new DiscussionQueryBuilder($query);
75+
}
76+
6977
public function getRouteKeyName(): string
7078
{
7179
return 'slug';
@@ -83,7 +91,7 @@ public function replyAbleSubject(): string
8391

8492
public function getPathUrl(): string
8593
{
86-
return "/discussions/{$this->slug()}";
94+
return route('discussions.show', $this);
8795
}
8896

8997
public function excerpt(int $limit = 110): string
@@ -101,52 +109,20 @@ public function isLocked(): bool
101109
return $this->locked;
102110
}
103111

104-
public function getCountAllRepliesWithChildAttribute(): int
112+
public function countAllRepliesWithChild(): Attribute
105113
{
106-
$count = $this->replies->count();
107-
108-
foreach ($this->replies()->withCount('allChildReplies')->get() as $reply) {
109-
/** @var Reply $reply */
110-
$count += $reply->all_child_replies_count;
111-
}
112-
113-
return $count;
114-
}
114+
return Attribute::make(
115+
get: function () {
116+
$count = $this->replies->count();
115117

116-
public function scopePinned(Builder $query): Builder
117-
{
118-
return $query->where('is_pinned', true);
119-
}
120-
121-
public function scopeNotPinned(Builder $query): Builder
122-
{
123-
return $query->where('is_pinned', false);
124-
}
118+
foreach ($this->replies()->withCount('allChildReplies')->get() as $reply) {
119+
/** @var Reply $reply */
120+
$count += $reply->all_child_replies_count;
121+
}
125122

126-
public function scopeRecent(Builder $query): Builder
127-
{
128-
return $query->orderBy('is_pinned', 'desc')
129-
->orderBy('created_at', 'desc');
130-
}
131-
132-
public function scopePopular(Builder $query): Builder
133-
{
134-
return $query->withCount('reactions')
135-
->orderBy('reactions_count', 'desc');
136-
}
137-
138-
public function scopeActive(Builder $query): Builder
139-
{
140-
return $query->withCount(['replies' => function ($query): void {
141-
$query->where('created_at', '>=', now()->subWeek());
142-
}])
143-
->orderBy('replies_count', 'desc');
144-
}
145-
146-
public function scopeNoComments(Builder $query): Builder
147-
{
148-
return $query->whereDoesntHave('replies')
149-
->orderByDesc('created_at');
123+
return $count;
124+
}
125+
);
150126
}
151127

152128
public function lockedDiscussion(): void

0 commit comments

Comments
 (0)