Back to Course |
Filament 3 From Scratch: Practical Course

Restrict Add/Edit/Delete Actions and Buttons

In this lesson, let's look at simple ways to hide action buttons from the Filament table.


Restrict Create/Delete on Users

Let's imagine we have a User Management section, but we can't create a new user (they register themselves) or delete the existing one (for history archive reasons). The only thing we can do is edit the user's data.

So, I've generated a resource:

php artisan make:filament-resource User

And added a few columns to the form/table:

app/Filament/Resources/UserResource.php:

class UserResource extends Resource
{
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name'),
Forms\Components\TextInput::make('email')
->email(),
]);
}
 
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
Tables\Columns\TextColumn::make('created_at')
->dateTime(),
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
])
->emptyStateActions([
Tables\Actions\CreateAction::make(),
]);
}
 
public static function getPages(): array
{
return [
'index' => Pages\ListUsers::route('/'),
'create' => Pages\CreateUser::route('/create'),
'edit' => Pages\EditUser::route('/{record}/edit'),
];
}
}

Visually it looks like this:

Now, let's remove the ability to Add and Delete users.


Restrict Adding New Records

To hide the Create form and all links to it, we need to make four changes:

Step 1. Resource method getPages(): delete the create page.

return [
'index' => Pages\ListUsers::route('/'),
'create' => Pages\CreateUser::route('/create'),
'edit' => Pages\EditUser::route('/{record}/edit'),
];

Step 2. In the Resource Table, remove the CreateAction::make() in the ->emptyStateActions(). This button is visible if the table has 0 records.

return $table
// ...
->emptyStateActions([
Tables\Actions\CreateAction::make(),
]);

Step 3. File app/Filament/Resources/UserResource/Pages/ListUsers.php: remove the Header Action to hide the button on the top-right.

class ListUsers extends ListRecords
{
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

Step 4. Physically delete the file app/Filament/Resources/UserResource/Pages/CreateUser.php.

Now, the button is gone:

And even if you manually visit the URL /admin/users/create, you will get a "404 Not Found". Great.


Restrict Deleting Records

So, we want to disable the Delete button. But wait, it seems we haven't even shown it on the table, so we don't have to do anything!

Wrong.

There are two places where the users can still be deleted.

Step 1. Remove "Bulk Delete".

If you tick any checkbox in the table and choose "Bulk actions", you will see this:

To disable that, you need to delete the DeleteBulkAction::make(), or even empty the whole array of bulkActions():

return $table
// ...
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
])

Interestingly, if Filament doesn't detect any Bulk Actions, it won't even show the column with checkboxes.

Step 2. Remove "Delete" from the Edit form.

Not many people use this feature, but the Edit form also contains the Delete button.

Filament allows you to easily show/hide it, similarly to other buttons. In the file app/Filament/Resources/UserResource/Pages/EditUser.php, remove it from the array of header actions:

class EditUser extends EditRecord
{
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

Hide Edit Button on Condition

Finally, let's try to hide even the Edit button if the user is not an administrator.

Let's say that in the database, we have a column users.is_admin with values of 1 and 0.

First, the wrong way. We could try to show/hide a button with the condition:

return $table
->actions([
Tables\Actions\EditAction::make()
->visible(auth()->user()->is_admin),
])

Now the button is gone if you're not an admin.

But if you launch the URL /admin/users/1/edit manually... you can still access it!

So, the correct way is to validate the access on the back-end using Laravel Policies, which Filament would automatically detect.

So we delete the ->visible() condition above and instead do this:

php artisan make:policy UserPolicy --model=User

And then we need only one method inside:

app/Policies/UserPolicy.php:

namespace App\Policies;
 
use App\Models\User;
 
class UserPolicy
{
public function update(User $user, User $model): bool
{
return $user->is_admin;
}
}

And that's it. We don't need to change anything in the UserResource class. If the user is not an administrator, the button will be invisible, and the direct URL /admin/users/1/edit will throw an error page of "403 Forbidden".