Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Record Switcher Laravel Package

howdu/filament-record-switcher

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require howdu/filament-record-switcher
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Howdu\FilamentRecordSwitcher\FilamentRecordSwitcherServiceProvider"
    
  2. Enable for a Resource Add the trait to your Filament resource class:

    use Howdu\FilamentRecordSwitcher\Concerns\HasRecordSwitcher;
    
    class PostResource extends Resource
    {
        use HasRecordSwitcher;
        // ...
    }
    
  3. First Use Case

    • Navigate to any record in your resource.
    • Click the page title (now a dropdown button).
    • Search or browse records to quickly switch between them.

Implementation Patterns

Core Workflow

  1. Resource Integration

    • Apply HasRecordSwitcher to any Filament resource.
    • Customize via $recordSwitcher property in the resource class:
      protected static ?string $recordSwitcher = 'custom'; // or 'default'
      
  2. Search & Navigation

    • Default Behavior: Dropdown shows all records with search/filtering.
    • Customization: Override getRecordSwitcherQuery() to modify the query:
      public function getRecordSwitcherQuery(): Builder
      {
          return parent::getRecordSwitcherQuery()
              ->where('is_active', true);
      }
      
  3. Styling & UX

    • Use $recordSwitcherIcon to change the dropdown icon:
      protected static string $recordSwitcherIcon = 'heroicon-o-chevron-down';
      
    • Disable for specific records via canAccessRecordSwitcher():
      public static function canAccessRecordSwitcher(): bool
      {
          return auth()->user()->can('switch_records');
      }
      
  4. Multi-Resource Projects

    • Group resources by namespace or prefix in the dropdown using $recordSwitcherGroup:
      protected static ?string $recordSwitcherGroup = 'Admin';
      

Advanced Patterns

  • Dynamic Permissions: Use canAccessRecordSwitcher() to gate access per record/user.
  • Custom Actions: Extend the dropdown with custom actions via getRecordSwitcherActions():
    public function getRecordSwitcherActions(): array
    {
        return [
            Action::make('archive')
                ->label('Archive Record')
                ->action(fn (Record $record) => $record->update(['is_active' => false])),
        ];
    }
    
  • Lazy Loading: For large datasets, implement pagination in getRecordSwitcherQuery():
    return parent::getRecordSwitcherQuery()->paginate(20);
    

Gotchas and Tips

Common Pitfalls

  1. Query Performance

    • Issue: Slow dropdown rendering with large datasets.
    • Fix: Add ->select('id', 'title', 'slug') to limit columns or use ->with(['relationship']) sparingly.
    • Tip: Cache the query results if the dataset rarely changes:
      return Cache::remember("record-switcher-{$this->getModel()}", now()->addHours(1), fn() => parent::getRecordSwitcherQuery());
      
  2. Permission Conflicts

    • Issue: Dropdown shows records the user can’t access.
    • Fix: Override canAccessRecordSwitcher() or filter the query:
      public function getRecordSwitcherQuery(): Builder
      {
          return parent::getRecordSwitcherQuery()->whereIn('id', fn($q) => $q->select('id')->from('posts')->where('user_id', auth()->id()));
      }
      
  3. Styling Overrides

    • Issue: Dropdown styles clash with custom Filament themes.
    • Fix: Use the $recordSwitcherClass property to add custom classes:
      protected static string $recordSwitcherClass = 'filament-record-switcher-custom';
      
    • Tip: Inspect the generated HTML (via browser dev tools) to target specific elements.
  4. Relationships & Eager Loading

    • Issue: N+1 queries when loading related data.
    • Fix: Eager load relationships in getRecordSwitcherQuery():
      return parent::getRecordSwitcherQuery()->with(['author', 'category']);
      
    • Warning: Avoid over-eager-loading to keep the dropdown performant.

Debugging Tips

  • Log Queries: Temporarily add ->toSql() to getRecordSwitcherQuery() to debug:
    \Log::info($this->getRecordSwitcherQuery()->toSql());
    
  • Check Permissions: Use dd($this->canAccessRecordSwitcher()) to verify access logic.
  • Clear Cache: If changes don’t reflect, run:
    php artisan optimize:clear
    

Extension Points

  1. Custom Dropdown Content

    • Override getRecordSwitcherDropdownItems() to replace the default list:
      public function getRecordSwitcherDropdownItems(): array
      {
          return [
              DropdownItem::make('Custom Item')
                  ->url(fn () => route('custom.path'))
                  ->icon('heroicon-o-external-link'),
          ];
      }
      
  2. Event Listeners

    • Listen for record-switcher.before-switch to intercept navigation:
      event(new RecordSwitcherEvent($record));
      
    • Publish the config to access event names:
      php artisan vendor:publish --tag=filament-record-switcher-config
      
  3. Testing

    • Test dropdown interactions with:
      $this->getFilament()->actingAs($user)
          ->get($resource->getUrl())
          ->assertSeeInDropdown($record->title);
      
    • Use assertSoftDeletes() for soft-deleted records if applicable.

Pro Tips

  • Combine with Filament Actions: Add a "Quick Edit" action to the dropdown:
    public function getRecordSwitcherActions(): array
    {
        return [
            Action::make('edit')
                ->label('Quick Edit')
                ->icon('heroicon-o-pencil')
                ->url(fn (Record $record) => $this->getUrl('edit', ['record' => $record])),
        ];
    }
    
  • Localization: Translate labels via Filament’s translation system:
    protected static ?string $recordSwitcherLabel = __('filament-record-switcher::labels.switch_record');
    
  • Dark Mode: Ensure icons/styles work in dark mode by testing with Filament’s dark mode toggle.

```markdown
### Config Quirks
- **Default vs. Custom**: The `default` switcher uses Filament’s global search styling, while `custom` provides a blank slate for styling.
- **Grouping**: Groups are alphabetically sorted by default. Override `getRecordSwitcherGroupSort()` to customize:
  ```php
  public static function getRecordSwitcherGroupSort(): array
  {
      return ['Admin', 'Content', 'Settings'];
  }
  • Empty State: Customize the "no results" message via:
    protected static ?string $recordSwitcherEmptyState = __('No records found.');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle