[패널] 대시보드
개요
Filament는 "위젯"으로 구성된 동적 대시보드를 매우 쉽게 구축할 수 있도록 해줍니다.
다음 문서는 이러한 위젯을 사용하여 패널을 통해 대시보드를 조립하는 방법을 설명합니다.
사용 가능한 위젯
Filament에는 다음과 같은 위젯이 기본 제공됩니다:
또한 사용자 정의 위젯을 직접 생성하여 Filament의 기본 제공 위젯과 일관된 디자인을 가질 수 있습니다.
위젯 정렬
각 위젯 클래스에는 페이지 내에서 다른 위젯과의 상대적인 순서를 변경할 수 있는 $sort
속성이 있습니다:
protected static ?int $sort = 2;
위젯 너비 커스터마이징
$columnSpan
속성을 사용하여 위젯의 너비를 커스터마이징할 수 있습니다. 1에서 12 사이의 숫자를 사용하여 위젯이 차지할 열의 개수를 지정하거나, full
을 사용하여 페이지 전체 너비를 차지하게 할 수 있습니다:
protected int | string | array $columnSpan = 'full';
반응형 위젯 너비
브라우저의 반응형 브레이크포인트에 따라 위젯의 너비를 변경하고 싶을 수 있습니다. 각 브레이크포인트에서 위젯이 차지해야 할 열의 개수를 포함하는 배열을 사용하여 이를 할 수 있습니다:
protected int | string | array $columnSpan = [
'md' => 2,
'xl' => 3,
];
이는 반응형 위젯 그리드를 사용할 때 특히 유용합니다.
위젯 그리드 커스터마이징
위젯을 표시하는 데 사용되는 그리드 열의 개수를 변경할 수 있습니다.
먼저, 기본 대시보드 페이지를 교체해야 합니다.
이제 새 app/Filament/Pages/Dashboard.php
파일에서, getColumns()
메서드를 오버라이드하여 사용할 그리드 열의 개수를 반환할 수 있습니다:
public function getColumns(): int | string | array
{
return 2;
}
반응형 위젯 그리드
브라우저의 반응형 브레이크포인트에 따라 위젯 그리드 열의 개수를 변경하고 싶을 수 있습니다. 각 브레이크포인트에서 사용해야 할 열의 개수를 포함하는 배열을 사용하여 이를 할 수 있습니다:
public function getColumns(): int | string | array
{
return [
'md' => 4,
'xl' => 5,
];
}
이는 반응형 위젯 너비와 잘 어울립니다.
조건부로 위젯 숨기기
위젯에서 static canView()
메서드를 오버라이드하여 조건부로 위젯을 숨길 수 있습니다:
public static function canView(): bool
{
return auth()->user()->isAdmin();
}
테이블 위젯
대시보드에 테이블을 쉽게 추가할 수 있습니다. 다음 명령어로 위젯을 생성하세요:
php artisan make:filament-widget LatestOrders --table
이제 위젯 파일을 편집하여 테이블을 커스터마이징할 수 있습니다.
사용자 정의 위젯
BlogPostsOverview
위젯을 만들기 시작하려면:
php artisan make:filament-widget BlogPostsOverview
이 명령은 Filament 디렉터리의 /Widgets
디렉터리에 위젯 클래스와, Filament 뷰 디렉터리의 /widgets
디렉터리에 뷰 파일 두 개를 생성합니다.
위젯 데이터 필터링
대시보드에 폼을 추가하여 사용자가 모든 위젯에 표시되는 데이터를 필터링할 수 있습니다. 필터가 업데이트되면, 위젯이 새로운 데이터로 다시 로드됩니다.
먼저, 기본 대시보드 페이지를 교체해야 합니다.
이제 새 app/Filament/Pages/Dashboard.php
파일에서 HasFiltersForm
트레이트를 추가하고, filtersForm()
메서드를 추가하여 폼 컴포넌트를 반환할 수 있습니다:
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Form;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
class Dashboard extends BaseDashboard
{
use HasFiltersForm;
public function filtersForm(Form $form): Form
{
return $form
->schema([
Section::make()
->schema([
DatePicker::make('startDate'),
DatePicker::make('endDate'),
// ...
])
->columns(3),
]);
}
}
필터에서 데이터를 필요로 하는 위젯 클래스에서는 InteractsWithPageFilters
트레이트를 추가해야 하며, 이를 통해 $this->filters
속성을 사용하여 필터 폼의 원시 데이터에 접근할 수 있습니다:
use App\Models\BlogPost;
use Carbon\CarbonImmutable;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Illuminate\Database\Eloquent\Builder;
class BlogPostsOverview extends StatsOverviewWidget
{
use InteractsWithPageFilters;
public function getStats(): array
{
$startDate = $this->filters['startDate'] ?? null;
$endDate = $this->filters['endDate'] ?? null;
return [
StatsOverviewWidget\Stat::make(
label: 'Total posts',
value: BlogPost::query()
->when($startDate, fn (Builder $query) => $query->whereDate('created_at', '>=', $startDate))
->when($endDate, fn (Builder $query) => $query->whereDate('created_at', '<=', $endDate))
->count(),
),
// ...
];
}
}
$this->filters
배열은 항상 현재 폼 데이터를 반영합니다. 이 데이터는 실시간으로 제공되며 데이터베이스 쿼리 이외의 용도로 사용되지 않으므로 검증되지 않는다는 점에 유의하세요. 데이터를 사용하기 전에 유효한지 반드시 확인해야 합니다. 이 예시에서는 쿼리에서 사용하기 전에 시작 날짜가 설정되어 있는지 확인합니다.
액션 모달을 사용한 위젯 데이터 필터링
또는, 필터 폼 대신 액션 모달을 사용할 수 있으며, 이는 페이지 헤더의 버튼을 클릭하여 열 수 있습니다. 이 접근 방식의 장점은 다음과 같습니다:
- 필터 폼이 항상 보이지 않으므로, 위젯을 위해 페이지의 전체 높이를 사용할 수 있습니다.
- 사용자가 "적용" 버튼을 클릭할 때까지 필터가 위젯을 업데이트하지 않으므로, 위젯이 비싼 리소스를 사용할 경우 성능이 향상될 수 있습니다.
- 필터 폼에 대해 검증을 수행할 수 있으므로, 위젯은 데이터가 유효하다는 사실에 의존할 수 있습니다. 사용자가 폼을 제출할 수 없으며, 모달을 취소하면 사용자의 변경 사항이 폐기됩니다.
필터 폼 대신 액션 모달을 사용하려면, HasFiltersForm
대신 HasFiltersAction
트레이트를 사용하세요. 그런 다음, getHeaderActions()
에서 FilterAction
클래스를 액션으로 등록하세요:
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Form;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Actions\FilterAction;
use Filament\Pages\Dashboard\Concerns\HasFiltersAction;
class Dashboard extends BaseDashboard
{
use HasFiltersAction;
protected function getHeaderActions(): array
{
return [
FilterAction::make()
->form([
DatePicker::make('startDate'),
DatePicker::make('endDate'),
// ...
]),
];
}
}
필터 액션에서 데이터를 처리하는 방법은 필터 헤더 폼에서 데이터를 처리하는 방법과 동일하지만, 데이터가 위젯에 전달되기 전에 검증된다는 점이 다릅니다. InteractsWithPageFilters
트레이트는 여전히 적용됩니다.
사용자의 세션에 위젯 필터 유지
기본적으로, 대시보드에 적용된 필터는 페이지를 새로고침해도 사용자의 세션에 유지됩니다. 이를 비활성화하려면, 대시보드 페이지 클래스에서 $persistsFiltersInSession
속성을 오버라이드하세요:
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
class Dashboard extends BaseDashboard
{
use HasFiltersForm;
protected bool $persistsFiltersInSession = false;
}
또는, 대시보드 페이지 클래스에서 persistsFiltersInSession()
메서드를 오버라이드하세요:
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
class Dashboard extends BaseDashboard
{
use HasFiltersForm;
public function persistsFiltersInSession(): bool
{
return false;
}
}
기본 위젯 비활성화
기본적으로, 대시보드에는 두 개의 위젯이 표시됩니다. 이 위젯들은 설정의 widgets()
배열을 업데이트하여 비활성화할 수 있습니다:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->widgets([]);
}
대시보드 페이지 커스터마이징
예를 들어, 위젯 열의 개수 변경 등 대시보드 클래스를 커스터마이징하고 싶다면, app/Filament/Pages/Dashboard.php
에 새 파일을 생성하세요:
<?php
namespace App\Filament\Pages;
class Dashboard extends \Filament\Pages\Dashboard
{
// ...
}
마지막으로, 설정 파일에서 기존 Dashboard
클래스를 제거하세요:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->pages([]);
}
여러 대시보드 생성
여러 개의 대시보드를 생성하려면, 위에서 설명한 과정을 반복하면 됩니다. Dashboard
클래스를 확장하는 새 페이지를 생성하면 필요한 만큼 대시보드를 만들 수 있습니다.
추가 대시보드의 URL 경로도 정의해야 하며, 그렇지 않으면 기본적으로 /
에 위치하게 됩니다:
protected static string $routePath = 'finance';
또한 $title
속성을 오버라이드하여 대시보드의 제목을 커스터마이징할 수 있습니다:
protected static ?string $title = 'Finance dashboard';
사용자에게 표시되는 기본 대시보드는 (정의된 네비게이션 정렬 순서에 따라) canAccess()
메서드로 제어되는, 사용자가 접근할 수 있는 첫 번째 대시보드입니다.
대시보드의 기본 정렬 순서는 -2
입니다. 사용자 정의 대시보드의 정렬 순서는 $navigationSort
로 제어할 수 있습니다:
protected static ?int $navigationSort = 15;