How to Hide Panel Icons Based on User Roles and Order Panels

I'm working on a Laravel Filament project with multiple panels, and I need to customize the visibility of these panels based on user roles. Specifically, I want to:

Hide panel icons if a user’s role doesn’t have access to that panel.
Maintain a specific order for the panel display.(admin, doctorants,.)
Here’s my current setup:

I'm using the bezhansalleh/filament-shield package for role management.
Each user can have access to multiple panels, and I store panel access information in a panel_accesses table, which associates roles with panel IDs.

class User extends Authenticatable implements FilamentUser
{
    use HasRoles; // from spatie/laravel-permission

    public function canAccessPanel(Panel $panel): bool
    {
        if ($this->hasRole('super_admin')) {
            return true;
        }

        foreach ($this->roles as $role) {
            if (PanelAccess::where('role_id', $role->id)
                ->where('panel_id', $panel->getId())
                ->exists()) {
                return true;
            }
        }

        return false;
    }
}


PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
    $panelSwitch->modalHeading('Available Panels')
        ->iconSize(16)
        ->modalWidth('sm')
        ->labels([
            'admin' => 'Home',
            'service_commun' => "Service Commun",
            'notifications' => "Notifications",
            'laboratoires' => "Laboratoires",
            'doctorants' => "Doctorants",
        ])
        ->icons([
            'admin' => 'heroicon-o-home',
            'service_commun' => 'heroicon-o-queue-list',
            'notifications' => 'heroicon-o-bell-alert',
            'laboratoires' => 'heroicon-o-beaker',
            'doctorants' => 'heroicon-o-academic-cap',
        ], $asImage = false);
});

Could anyone please provide guidance or examples on how to achieve this? Any help would be greatly appreciated!
Solution
Finally: ),
The solution was to use the excludes() method,
https://filamentphp.com/plugins/bezhansalleh-panel-switch#panel-exclusion
AppServiceProvider:

use BezhanSalleh\PanelSwitch\PanelSwitch;
....
use App\Models\PanelAccess;
use Filament\Facades\Filament;

 PanelSwitch::configureUsing(function (PanelSwitch $panelSwitch) {
   $panelSwitch->excludes(function () {
                $user = auth()->user();

                if ($user && $user->isAdmin()) {
                    return [];
                }

                $panels = Filament::getPanels();
                $excludedPanels = [];

                foreach ($panels as $panel) {
                    if (!$user->hasPanelAccess($panel->getId())) {
                        $excludedPanels[] = $panel->getId();
                    }
                }
                return $excludedPanels;
            });
//...
 });


User:
   public function hasPanelAccess($panelId)
    {
        if ($this->hasRole('super_admin')) {
            return true;
        }

        foreach ($this->roles as $role) {
            if (PanelAccess::where('role_id', $role->id)
                ->whereJsonContains('panel_id', $panelId)
                ->exists()) {
                return true;
            }
        }

        return false;
    }


PanelAccess
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Models\Role;

class PanelAccess extends Model
{
    protected $fillable = ['role_id', 'panel_id'];
    protected $casts = [
        'panel_id' => 'array',
    ];
    public function role()
    {
        return $this->belongsTo(Role::class);
    }

}


Thank you! 🙏 :fi:
Filament
Easily switch between panels in Filament.
Was this page helpful?