Skip to content

Commit 2fa84f9

Browse files
scott graysonscott grayson
authored andcommitted
feat: implement proper edit form restrictions and move functionality
- Remove type and parent_id from edit form completely - Type is now completely immutable after creation - Add dedicated 'Move' action for changing parent folder - Move action available in both table actions and edit page header - Move action prevents moving items into themselves or descendants - Edit form now only allows changing the name field - Clean separation of concerns: edit for name, move for location
1 parent d061f8b commit 2fa84f9

File tree

2 files changed

+69
-10
lines changed

2 files changed

+69
-10
lines changed

src/Resources/LibraryItemResource.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Filament\Actions\ViewAction;
1212
use Filament\Actions\BulkActionGroup;
1313
use Filament\Actions\DeleteBulkAction;
14+
use Filament\Actions\Action;
15+
use Filament\Forms\Components\Select;
1416
use Tapp\FilamentLibrary\Models\LibraryItem;
1517

1618
class LibraryItemResource extends Resource
@@ -126,11 +128,40 @@ public static function table(Table $table): Table
126128
])
127129
->actions([
128130
ViewAction::make()
129-
->url(fn (LibraryItem $record): string =>
130-
$record->type === 'folder'
131+
->url(fn (LibraryItem $record): string =>
132+
$record->type === 'folder'
131133
? static::getUrl('index', ['parent' => $record->id])
132134
: static::getUrl('view', ['record' => $record])
133135
),
136+
Action::make('move')
137+
->label('Move')
138+
->icon('heroicon-o-arrow-right-circle')
139+
->color('warning')
140+
->form([
141+
Select::make('parent_id')
142+
->label('Move to folder')
143+
->options(function (LibraryItem $record) {
144+
$currentId = $record->id;
145+
146+
return LibraryItem::where('type', 'folder')
147+
->where('id', '!=', $currentId)
148+
->where(function ($query) use ($currentId) {
149+
// Prevent moving into self or descendants
150+
$query->whereNull('parent_id')
151+
->orWhere('parent_id', '!=', $currentId);
152+
})
153+
->pluck('name', 'id')
154+
->prepend('Root (No parent)', null);
155+
})
156+
->searchable()
157+
->preload()
158+
->default(fn (LibraryItem $record) => $record->parent_id),
159+
])
160+
->action(function (LibraryItem $record, array $data): void {
161+
$record->update([
162+
'parent_id' => $data['parent_id'],
163+
]);
164+
}),
134165
EditAction::make(),
135166
DeleteAction::make(),
136167
])

src/Resources/Pages/EditLibraryItem.php

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use Filament\Resources\Pages\EditRecord;
66
use Tapp\FilamentLibrary\Resources\LibraryItemResource;
77
use Filament\Actions\DeleteAction;
8+
use Filament\Actions\Action;
9+
use Filament\Forms\Components\Select;
10+
use Tapp\FilamentLibrary\Models\LibraryItem;
811

912
class EditLibraryItem extends EditRecord
1013
{
@@ -13,13 +16,45 @@ class EditLibraryItem extends EditRecord
1316
protected function getHeaderActions(): array
1417
{
1518
return [
19+
Action::make('move')
20+
->label('Move')
21+
->icon('heroicon-o-arrow-right-circle')
22+
->color('warning')
23+
->form([
24+
Select::make('parent_id')
25+
->label('Move to folder')
26+
->options(function () {
27+
$currentId = $this->getRecord()->id;
28+
29+
return LibraryItem::where('type', 'folder')
30+
->where('id', '!=', $currentId)
31+
->where(function ($query) use ($currentId) {
32+
// Prevent moving into self or descendants
33+
$query->whereNull('parent_id')
34+
->orWhere('parent_id', '!=', $currentId);
35+
})
36+
->pluck('name', 'id')
37+
->prepend('Root (No parent)', null);
38+
})
39+
->searchable()
40+
->preload()
41+
->default($this->getRecord()->parent_id),
42+
])
43+
->action(function (array $data): void {
44+
$this->getRecord()->update([
45+
'parent_id' => $data['parent_id'],
46+
]);
47+
48+
$this->redirect(static::getResource()::getUrl('index', $data['parent_id'] ? ['parent' => $data['parent_id']] : []));
49+
}),
1650
DeleteAction::make(),
1751
];
1852
}
1953

2054
protected function mutateFormDataBeforeFill(array $data): array
2155
{
22-
// Remove fields that shouldn't be editable, but preserve type
56+
// Remove fields that shouldn't be editable
57+
unset($data['type']);
2358
unset($data['parent_id']);
2459
unset($data['created_by']);
2560

@@ -38,11 +73,4 @@ protected function getForms(): array
3873
];
3974
}
4075

41-
protected function mutateFormDataBeforeSave(array $data): array
42-
{
43-
// Preserve the original type - don't let it be changed
44-
$data['type'] = $this->getRecord()->type;
45-
46-
return $data;
47-
}
4876
}

0 commit comments

Comments
 (0)