Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як зробити спільні фільтри для всіх віджетів дашборда Filament?

Коли на дашборді кілька віджетів, зручно мати один набір фільтрів (період, регіон, менеджер), що діє на всі одразу.

1. Власна сторінка дашборда з формою фільтрів:

namespace App\Filament\Pages;

use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class Dashboard extends BaseDashboard
{
    use HasFiltersForm;

    public function filtersForm(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make()
                    ->schema([
                        DatePicker::make('startDate'),
                        DatePicker::make('endDate'),
                        Select::make('region')->options(Region::class),
                    ])
                    ->columns(3)
                    ->columnSpanFull(),
            ]);
    }
}

Стандартний дашборд треба замінити цим класом (прибрати Dashboard::class зі сторінок панелі чи вимкнути автовиявлення стандартного).

2. Віджети читають фільтри через трейт:

use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class SalesOverview extends StatsOverviewWidget
{
    use InteractsWithPageFilters;

    protected function getStats(): array
    {
        $query = Order::query()
            ->when($this->pageFilters['startDate'] ?? null, fn ($q, $date) => $q->whereDate('created_at', '>=', $date))
            ->when($this->pageFilters['endDate'] ?? null, fn ($q, $date) => $q->whereDate('created_at', '<=', $date))
            ->when($this->pageFilters['region'] ?? null, fn ($q, $region) => $q->where('region', $region));

        return [
            Stat::make('Замовлень', $query->count()),
            Stat::make('Виручка', Number::currency((clone $query)->sum('total'), 'UAH', 'uk')),
        ];
    }
}

Коли фільтри змінюються, віджети перезавантажуються з новими значеннями.

Варіанти:

  • фільтри можна винести в модальне вікно за кнопкою (HasFiltersAction) - дашборд лишається компактним;
  • $this->pageFilters можна зберігати в сесії, щоб вибраний період не скидався при поверненні.

Пастки:

  • $pageFilters - сирі дані з браузера. Перевіряйте й приводьте їх (дати, значення зі списку), а не підставляйте в whereRaw;
  • повторне використання запиту - count() і sum() на тому самому білдері працюють, але при модифікаціях краще clone, щоб умови не накопичувалися;
  • кожна зміна фільтра перераховує всі віджети - для важких метрик потрібне кешування з ключем від фільтрів.

Докладніше в документації: Фільтрування даних віджетів

Схожі питання