Skip to content

Commit 72efd02

Browse files
committed
Fix filament forms.
1 parent 7df9097 commit 72efd02

11 files changed

Lines changed: 129 additions & 38 deletions

File tree

app/Filament/Resources/PostResource.php

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@
1212
use Filament\Forms\Components\Select;
1313
use Filament\Forms\Components\Textarea;
1414
use Filament\Forms\Components\TextInput;
15-
use Filament\Forms\Components\Toggle;
1615
use Filament\Forms\Form;
1716
use Filament\Resources\Resource;
1817
use Filament\Tables\Actions\BulkActionGroup;
1918
use Filament\Tables\Actions\DeleteBulkAction;
2019
use Filament\Tables\Actions\EditAction;
2120
use Filament\Tables\Columns\TextColumn;
21+
use Filament\Tables\Columns\IconColumn;
2222
use Filament\Tables\Table;
23+
use Filament\Tables\Filters\Filter;
24+
use Filament\Tables\Filters\SelectFilter;
25+
use Illuminate\Database\Eloquent\Builder;
2326

2427
final class PostResource extends Resource
2528
{
@@ -37,53 +40,70 @@ public static function form(Form $form): Form
3740
->maxLength(self::INPUT_MAX_LENGTH),
3841
TextInput::make('slug')
3942
->required()
40-
->maxLength(self::INPUT_MAX_LENGTH),
41-
TextInput::make('legacy_id')
42-
->numeric(),
43+
->maxLength(self::INPUT_MAX_LENGTH)
44+
->unique(Post::class, 'slug', ignoreRecord: true),
4345
Textarea::make('body')
4446
->required()
4547
->columnSpanFull(),
4648
Textarea::make('more_inside')
4749
->columnSpanFull(),
48-
TextInput::make('state')
49-
->required()
50-
->maxLength(self::INPUT_MAX_LENGTH),
5150
Select::make('subsite_id')
5251
->relationship('subsite', 'name')
5352
->required(),
5453
Select::make('user_id')
5554
->relationship('user', 'name')
55+
->searchable()
56+
->preload()
5657
->required(),
57-
TextInput::make('uuid')
58-
->label('UUID')
59-
->maxLength(36),
6058
DateTimePicker::make('published_at'),
61-
Toggle::make('is_published')
62-
->required(),
63-
Toggle::make('is_current')
64-
->required(),
65-
TextInput::make('publisher_type')
66-
->maxLength(self::INPUT_MAX_LENGTH),
67-
TextInput::make('publisher_id')
68-
->numeric(),
6959
]);
7060
}
7161

62+
public static function getEloquentQuery(): Builder
63+
{
64+
return Post::current();
65+
}
66+
7267
public static function table(Table $table): Table
7368
{
7469
return $table
7570
->columns([
7671
TextColumn::make('title')
77-
->searchable(),
72+
->searchable()
73+
->sortable()
74+
->limit(50),
75+
TextColumn::make('slug')
76+
->searchable()
77+
->toggleable(isToggledHiddenByDefault: true),
78+
IconColumn::make('is_published')
79+
->boolean()
80+
->label('Published')
81+
->sortable(),
7882
TextColumn::make('subsite.name')
79-
->numeric()
83+
->label('Subsite')
8084
->sortable(),
8185
TextColumn::make('user.name')
82-
->numeric()
86+
->label('Author')
87+
->searchable()
8388
->sortable(),
89+
TextColumn::make('published_at')
90+
->dateTime()
91+
->sortable()
92+
->toggleable(),
93+
TextColumn::make('created_at')
94+
->dateTime()
95+
->sortable()
96+
->toggleable(isToggledHiddenByDefault: true),
8497
])
8598
->filters([
86-
//
99+
Filter::make('hide_drafts')
100+
->label('Hide drafts')
101+
->baseQuery(fn(Builder $query): Builder => $query->withoutDrafts())
102+
->default(false),
103+
SelectFilter::make('subsite_id')
104+
->relationship('subsite', 'name')
105+
->searchable()
106+
->preload(),
87107
])
88108
->actions([
89109
EditAction::make(),

app/Filament/Resources/PostResource/Pages/EditPost.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace App\Filament\Resources\PostResource\Pages;
66

77
use App\Filament\Resources\PostResource;
8+
use App\Models\Post;
9+
use Filament\Actions\Action;
810
use Filament\Actions\DeleteAction;
911
use Filament\Resources\Pages\EditRecord;
1012

@@ -16,6 +18,27 @@ protected function getHeaderActions(): array
1618
{
1719
return [
1820
DeleteAction::make(),
21+
Action::make('publish')
22+
->label('Publish')
23+
->visible(fn(Post $record) => $record->is_published === false)
24+
->action(function (Post $record) {
25+
$record->setLive();
26+
$record->save();
27+
})
28+
->after(function () {
29+
$this->refreshFormData(['is_published', 'published_at']);
30+
}),
31+
Action::make('unpublish')
32+
->label('Unpublish')
33+
->visible(fn(Post $record) => $record->is_published === true)
34+
->action(function (Post $record) {
35+
$record->is_published = false;
36+
$record->save();
37+
})
38+
->after(function () {
39+
$this->refreshFormData(['is_published', 'published_at']);
40+
}),
41+
1942
];
2043
}
2144
}

app/Filament/Resources/SnippetResource.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use App\Filament\Resources\SnippetsResource\Pages\ListSnippets;
1010
use App\Models\Snippet;
1111
use Filament\Forms\Form;
12+
use Filament\Forms\Components\RichEditor;
13+
use Filament\Forms\Components\TextInput;
1214
use Filament\Resources\Resource;
1315
use Filament\Tables\Actions\BulkActionGroup;
1416
use Filament\Tables\Actions\DeleteBulkAction;
@@ -21,11 +23,18 @@ final class SnippetResource extends Resource
2123
protected static ?string $model = Snippet::class;
2224
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
2325

26+
public const int INPUT_MAX_LENGTH = 255;
27+
2428
public static function form(Form $form): Form
2529
{
2630
return $form
2731
->schema([
28-
//
32+
TextInput::make('title')
33+
->required()
34+
->maxLength(self::INPUT_MAX_LENGTH),
35+
RichEditor::make('body')
36+
->required()
37+
->columnSpanFull(),
2938
]);
3039
}
3140

app/Filament/Resources/SnippetsResource/Pages/EditSnippets.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use App\Filament\Resources\SnippetResource;
88
use Filament\Resources\Pages\EditRecord;
9-
use Filament\Tables\Actions\DeleteAction;
9+
use Filament\Actions\DeleteAction;
1010

1111
final class EditSnippets extends EditRecord
1212
{

app/Livewire/Contact/ContactMessageForm.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
<?php
2-
31
declare(strict_types=1);
42

53
namespace App\Livewire\Contact;

app/Models/Comment.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,17 @@ public function scopeSearch(Builder $query, string $keyword): Builder
8585

8686
// Relationships
8787

88-
public function bookmarks(): int
88+
public function bookmarkCount(): int
8989
{
9090
return Bookmark::count($this);
9191
}
9292

93-
public function favorites(): int
93+
public function favoriteCount(): int
9494
{
9595
return Favorite::count($this);
9696
}
9797

98-
public function flags(): int
98+
public function flagCount(): int
9999
{
100100
return Flag::count($this);
101101
}

app/Models/Post.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace App\Models;
66

7+
use App\Enums\PostStateEnum;
78
use App\Presenters\PostPresenter;
89
use Coderflex\LaravelPresenter\Concerns\CanPresent;
910
use Coderflex\LaravelPresenter\Concerns\UsesPresenters;
@@ -71,7 +72,10 @@ final class Post extends BaseModel implements CanPresent, HasMedia
7172
'user_id',
7273
'published_at',
7374
'is_published',
74-
'state',
75+
'slug',
76+
'is_current',
77+
'publisher_type',
78+
'publisher_id',
7579
];
7680

7781
protected static array $marks = [
@@ -84,6 +88,10 @@ final class Post extends BaseModel implements CanPresent, HasMedia
8488
'default' => PostPresenter::class,
8589
];
8690

91+
protected $attributes = [
92+
'state' => PostStateEnum::Draft->value,
93+
];
94+
8795
public function toSearchableArray(): array
8896
{
8997
return array_merge($this->toArray(), [
@@ -135,17 +143,17 @@ public function comments(): HasMany
135143
return $this->hasMany(Comment::class);
136144
}
137145

138-
public function bookmarks(): int
146+
public function bookmarkCount(): int
139147
{
140148
return Bookmark::count($this);
141149
}
142150

143-
public function favorites(): int
151+
public function favoriteCount(): int
144152
{
145153
return Favorite::count($this);
146154
}
147155

148-
public function flags(): int
156+
public function flagCount(): int
149157
{
150158
return Flag::count($this);
151159
}

app/Policies/PostPolicy.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace App\Policies;
66

7+
use App\Enums\RoleNameEnum;
78
use App\Models\User;
89
use App\Models\Post;
910
use Illuminate\Auth\Access\HandlesAuthorization;
@@ -19,7 +20,7 @@ public function viewAny(): bool
1920

2021
public function view(User $user, Post $post): bool
2122
{
22-
if ($user->hasRole(['admin']) || $post->user_id === $user->id) {
23+
if ($user->hasRole([RoleNameEnum::MODERATOR->value]) || $post->user_id === $user->id) {
2324
return true;
2425
}
2526

@@ -34,7 +35,7 @@ public function create(User $user): bool
3435

3536
public function update(User $user, Post $post): bool
3637
{
37-
if ($user->hasRole(['admin']) || $post->user_id === $user->id) {
38+
if ($user->hasRole([RoleNameEnum::MODERATOR->value]) || $post->user_id === $user->id) {
3839
return true;
3940
}
4041

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\DB;
8+
use Illuminate\Support\Facades\Schema;
9+
10+
return new class extends Migration {
11+
public function up(): void
12+
{
13+
Schema::table('posts', function (Blueprint $table) {
14+
// Drop the existing unique constraint on slug
15+
$table->dropUnique(['slug']);
16+
});
17+
18+
// Uses IF(is_published = 1, 1, NULL) so only published records enforce uniqueness.
19+
DB::statement('CREATE UNIQUE INDEX posts_slug_published_unique ON posts (slug, (IF(is_published = 1, 1, NULL)))');
20+
}
21+
22+
public function down(): void
23+
{
24+
// Drop the functional unique index
25+
DB::statement('DROP INDEX posts_slug_published_unique ON posts');
26+
27+
Schema::table('posts', function (Blueprint $table) {
28+
// Restore the original unique constraint
29+
$table->unique('slug');
30+
});
31+
}
32+
};

resources/views/livewire/posts/post-comments-component.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
@include('comments.partials.comment-footer', [
88
'comment' => $comment,
9-
'favoritesCount' => $comment->favorites()->count(),
10-
'flagsCount' => $comment->flags()->count(),
9+
'favoritesCount' => $comment->favoriteCount(),
10+
'flagsCount' => $comment->flagCount(),
1111
'flagReasons' => $flagReasons,
1212
])
1313
</article>

0 commit comments

Comments
 (0)