【Laravel11 + filament3】Panel Builder テュートリアル実践記録

Laravel

Laravel用の管理画面コンポーネント集 filament3 のPanel Builderテュートリアルを実践した際の記録です。

Getting started - Panel Builder - Filament

公式ドキュメントが英語なので、ほぼほぼ自動翻訳の貼り付けになっています。

部分的に解説を入れたり、わかりやすく小分けにしたりしています。

けっこう長いです。

前提条件

  • Laravel11 + filament3 環境構築済
  • Ubuntu22.x(WSL2)で作業をしています。
  • Composer2インストール済

filament3 環境構築は次の記事をご覧ください。

この記事で出来ること

DEMOプロジェクトとして獣医用の管理システム例を構築します。

  • オーナー/患者(ペット)/治療管理画面(CRUD処理用フォームと表)設置
  • 検索機能、フィルタ機能、ソート機能設置
  • ダッシュボードに概要ウィジェット設置
  • ダッシュボードに患者数グラフウィジェット設置

モデル作成

このプロジェクトには、所有者、患者、治療という 3 つのモデルとマイグレーションが必要です。これらを作成するには、次のartisanコマンドを使用します。

php artisan make:model Owner -m
php artisan make:model Patient -m
php artisan make:model Treatment -m

マイグレーションファイル編集

各ファイル内の up() メソッドを編集します。

▼「database/migrations/***_create_owners_table.php」

    public function up(): void
    {
        Schema::create('owners', function (Blueprint $table) {
            $table->id();
            $table->string('email');
            $table->string('name');
            $table->string('phone');        
            $table->timestamps();
        });
    }

▼「database/migrations/***_create_patients_table.php」

    public function up(): void
    {
        Schema::create('patients', function (Blueprint $table) {
            $table->id();
            $table->date('date_of_birth');
            $table->string('name');
            $table->foreignId('owner_id')->constrained('owners')->cascadeOnDelete();
            $table->string('type');        
            $table->timestamps();
        });
    }

▼「database/migrations/***_create_treatments_table.php」

    public function up(): void
    {
        Schema::create('treatments', function (Blueprint $table) {
            $table->id();
            $table->string('description');
            $table->text('notes')->nullable();
            $table->foreignId('patient_id')->constrained('patients')->cascadeOnDelete();
            $table->unsignedInteger('price')->nullable();        
            $table->timestamps();
        });
    }

マイグレーション実行

次のコマンドでマイグレーションを実行します。

php artisan migrate

全モデルのガード解除

このガイドでは簡潔にするために、Laravel の一括割り当て保護を無効にします。 Filament は有効なデータのみをモデルに保存するため、モデルの保護を安全に解除できます。すべての Laravel モデルを一度に保護解除するには、app/Providers/AppServiceProvider.php の boot() メソッドに Model::unguard() を追加します。

▼「app/Providers/AppServiceProvider.php」

宣言部に追記

use Illuminate\Database\Eloquent\Model;

boot() メソッドを編集

    public function boot(): void
    {
        Model::unguard();
    }

モデル間のリレーション設定

リレーション設定のために各モデルを編集します。

▼「app/Models/Owner.php」

宣言部に追記

use Illuminate\Database\Eloquent\Relations\HasMany;

patients() メソッド追記

    public function patients(): HasMany
    {
        return $this->hasMany(Patient::class);
    }

▼「app/Models/Patients.php」

宣言部に追記

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

owner() メソッドと treatments() メソッドを追記

    public function owner(): BelongsTo
    {
        return $this->belongsTo(Owner::class);
    }
 
    public function treatments(): HasMany
    {
        return $this->hasMany(Treatment::class);
    }

▼「app/Models/Treatment.php」

宣言部に追記

use Illuminate\Database\Eloquent\Relations\BelongsTo;

patient() メソッドを追記

    public function patient(): BelongsTo
    {
        return $this->belongsTo(Patient::class);
    }

resourceの導入

Filament では、resourceは Eloquent モデルの CRUD インターフェイスを構築するために使用される静的クラスです。ここでは、管理者が表とフォームを使用してパネルのデータを操作する方法について説明します。

患者 (ペット) はこのシステムの中核となるエンティティであるため、患者を作成、表示、更新、削除するためのページを構築できる患者resourceを作成することから始めましょう。

次のartisanコマンドを使用して、患者モデルの新しいfilament resourceを作成します。

php artisan make:filament-resource Patient

これにより、app/Filament/Resources ディレクトリにいくつかのファイルが作成されます。

.
+-- PatientResource.php
+-- PatientResource
|   +-- Pages
|   |   +-- CreatePatient.php
|   |   +-- EditPatient.php
|   |   +-- ListPatients.php

ブラウザで /admin/patient にアクセスし、ナビゲーションに「Patients」という新しいリンクを確認します。リンクをクリックすると、空のテーブルが表示されます。新しい患者を作成するフォームを追加しましょう。

この時点でナビゲーション(メニュー)に「Patient」が追加されています。

「Patient」画面へ移動すると空の表のページが表示されます。

resourceフォームの設定

PatientResource.php ファイルを開くと、空の schema([…]) 配列を含む form() メソッドがあります。このスキーマにフォーム フィールドを追加すると、新しい患者の作成と編集に使用できるフォームが構築されます。

「名前」のText入力

Filament には、さまざまなフォーム フィールドがバンドルされています。単純なテキスト入力フィールドから始めましょう。

▼「app/Filament/PatientResource.php」

form() メソッド内の schema() メソッド内に追記

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('name'),
            ]);
    }

/admin/patients/create にアクセスし (または「新しい患者」ボタンをクリックし)、患者名のフォーム フィールドが追加されていることを確認します。

このフィールドはデータベースで必須であり、最大長は 255 文字であるため、名前フィールドに 2 つの入力規則を追加しましょう。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
            ]);
    }

名前なしで新しい患者を作成するフォームを送信しようとすると、名前フィールドが必須であることを通知するメッセージが表示されることを確認します。

「タイプ」選択

患者の種類として 2 番目のフィールドを追加しましょう。猫、犬、ウサギのいずれかを選択します。選択できるオプションのセットが固定されているため、選択フィールドは適切に機能します。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ]),
            ]);
    }

Select フィールドの options() メソッドは、ユーザーが選択できるオプションの配列を受け入れます。配列のキーはデータベースと一致する必要があり、値はフォームのラベルとして使用されます。必要なだけこの配列に動物を追加してください。

このフィールドはデータベースでも必須であるため、required() 検証ルールを追加しましょう。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ])
                    ->required(),
            ]);
    }

「生年月日」ピッカー

検証とともに date_of_birth 列の日付ピッカー フィールドを追加しましょう (生年月日は必須であり、日付は現在の日以降である必要があります)。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ])
                    ->required(),
                // 日付ピッカー
                Forms\Components\DatePicker::make('date_of_birth')
                    ->required()        // 入力必須
                    ->maxDate(now()),   // 最大日付:現在
            ]);
    }

「オーナー」選択

新しい患者を作成するときにオーナーも追加する必要があります。 Patient モデルに BelongsTo リレーションを追加したため (関連する Owner モデルに関連付けた)、select フィールドから relationship() メソッドを使用して、選択する所有者のリストをロードできます。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ])
                    ->required(),
                // 日付ピッカー
                Forms\Components\DatePicker::make('date_of_birth')
                    ->required()        // 入力必須
                    ->maxDate(now()),   // 最大日付:現在
                // Select:リレーション
                Forms\Components\Select::make('owner_id')
                    // モデル:Patient::owner() / ラベル:name
                    ->relationship('owner', 'name')
                    ->required(),   // 入力必須
            ]);
    }

relationship() メソッドの最初の引数は、モデル内のリレーションを定義する関数の名前 (選択オプションをロードするために Filament によって使用されます)、この場合は owner です。 2 番目の引数は、関連テーブルから使用するカラム名です (この場合は name)。

また、owner フィールドを必須にし、searchable() と preload() を最初の 50 人のオーナーを検索可能なリストに追加しましょう (リストが長い場合)。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ])
                    ->required(),
                // 日付ピッカー
                Forms\Components\DatePicker::make('date_of_birth')
                    ->required()        // 入力必須
                    ->maxDate(now()),   // 最大日付:現在
                // Select:リレーション
                Forms\Components\Select::make('owner_id')
                    // モデル:Patient::owner() / ラベル:name
                    ->relationship('owner', 'name')
                    ->searchable()  // 検索対象に設定
                    ->preload()     // 事前に取得50件
                    ->required(),   // 入力必須
            ]);
    }

ページを離れずに新規オーナーを作成する

現在、データベースにはオーナーがいません。個別の Filament オーナーresourceを作成する代わりに、モーダル フォーム (選択の横にある + ボタンとしてアクセス可能) を介してオーナーを追加する簡単な方法をユーザーに提供しましょう。 createOptionForm() メソッドを使用して、オーナーの名前、電子メール アドレス、電話番号の TextInput フィールドを含むモーダル フォームを埋め込みます。

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Text入力
                Forms\Components\TextInput::make('name')
                    ->required()        // 入力必須
                    ->maxLength(255),   // 最長255文字
                // Select
                Forms\Components\Select::make('type')
                    ->options([         // 選択肢
                        'cat' => 'Cat',         // ねこ
                        'dog' => 'Dog',         // いぬ
                        'rabbit' => 'Rabbit',   // うさぎ
                    ])
                    ->required(),
                // 日付ピッカー
                Forms\Components\DatePicker::make('date_of_birth')
                    ->required()        // 入力必須
                    ->maxDate(now()),   // 最大日付:現在
                // Select:リレーション
                Forms\Components\Select::make('owner_id')
                    // モデル:Patient::owner() / ラベル:name
                    ->relationship('owner', 'name')
                    ->searchable()  // 検索対象に設定
                    ->preload()     // 事前に取得50件
                    // オーナー新規追加用のモーダルフォーム
                    ->createOptionForm([
                        Forms\Components\TextInput::make('name')
                            ->label('名前')             // ラベル
                            ->required()
                            ->maxLength(255),
                        Forms\Components\TextInput::make('email')
                            ->label('メールアドレス')   // ラベル
                            ->email()                  // email形式チェック
                            ->required()
                            ->maxLength(255),
                        Forms\Components\TextInput::make('phone')
                            ->label('電話番号')        // ラベル
                            ->tel()                   // 電話番号形式チェック
                            ->required(),
                    ])
                    ->required(),   // 入力必須
            ]);
    }

この例では、TextInput のいくつかの新しいメソッドが使用されています。

🔵 label() は、各フィールドの自動生成されたラベルをオーバーライドします。この場合、電子メール ラベルを電子メール アドレス、電話ラベルを電話番号にします。
🔵 email() は、有効な電子メール アドレスのみをフィールドに入力できるようにします。モバイルデバイスのキーボードレイアウトも変更されます。
🔵 tel() は、有効な電話番号のみをフィールドに入力できるようにします。モバイルデバイスのキーボードレイアウトも変更されます。

これでフォームが機能するはずです。新しい患者とその所有者を作成してみてください。作成すると、編集ページにリダイレクトされ、詳細を更新できます。

▼このようなフォームが表示されます。

※日付入力欄右側の「+」クリックで日付ピッカー出現

▼オーナー選択欄右側の「+」をクリックすると

 モーダルフォーム出現

▼モーダルフォームでオーナーの新規登録が可能

▼モーダルフォームで登録したオーナーが選択適用される

▼「作成」ボタン押下で登録&編集画面へ遷移

患者一覧表の設定

/admin/patients ページに再度アクセスします。患者を作成した場合は、テーブルに 1 つの空の行が表示され、編集ボタンが表示されます。実際の患者データを表示できるように、テーブルにいくつかの列を追加しましょう。

PatientResource.php ファイルを開きます。空の columns([…]) 配列を持つ table() メソッドが表示されるはずです。この配列を使用して、患者テーブルに列を追加できます。

Textカラムの追加

Filament には、さまざまなテーブルカラムがバンドルされています。患者一覧表のすべてのフィールドに単純なテキストカラムを使用してみましょう。

▼「app/Filament/Resouces/PatientResource.php」

 の table() メソッド内の columns() メソッドを編集。

            // 患者一覧表の表示列定義
            ->columns([
                Tables\Columns\TextColumn::make('name'),
                Tables\Columns\TextColumn::make('type'),
                Tables\Columns\TextColumn::make('date_of_birth'),
                Tables\Columns\TextColumn::make('owner.name'),
            ])

Filament はドット表記を使用して関連データを積極的に読み込みます。情報量の少ない ID 番号の代わりに、所有者名のリストを表示するために、テーブル内で owner.name を使用しました。所有者の電子メール アドレスと電話番号の列を追加することもできます。

列を検索可能にする

テーブル内で患者を直接検索できる機能は、獣医療が成長するにつれて役立つでしょう。 searchable() メソッドを列に連鎖させることで、列を検索可能にできます。患者名と飼い主名を検索できるようにしましょう。

            // 患者一覧表の表示列定義
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable(),
                Tables\Columns\TextColumn::make('type'),
                Tables\Columns\TextColumn::make('date_of_birth'),
                Tables\Columns\TextColumn::make('owner.name')
                    ->searchable(),
            ])

ページをリロードし、検索基準を使用してテーブル エントリをフィルタリングするテーブル上の新しい検索入力フィールドを確認します。

▼検索窓が設置されています。

▼リアルタイム検索になっています。

カラムをソート可能にする

患者テーブルを年齢でソートできるようにするには、sortable() メソッドを date_of_birth 列に追加します。

            // 患者一覧表の表示列定義
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable(),
                Tables\Columns\TextColumn::make('type'),
                Tables\Columns\TextColumn::make('date_of_birth')
                    ->sortable(),
                Tables\Columns\TextColumn::make('owner.name')
                    ->searchable(),
            ])

これにより、カラムヘッダーにソートアイコン ボタンが追加されます。クリックすると、表が生年月日順にソートされます。

▼ソートアイコンボタンが追加されている

患者のType毎に表をフィルタリング

type フィールドを検索可能にすることもできますが、フィルター可能にした方がユーザー エクスペリエンスがはるかに向上します。

Filament テーブルにはフィルターを含めることができます。フィルターは、Eloquent クエリにスコープを追加することでテーブル内のレコード数を減らすコンポーネントです。フィルターにはカスタム フォーム コンポーネントを含めることもできるため、インターフェイスを構築するための強力なツールになります。

Filament には、テーブルの filters() に追加できる事前構築済みの SelectFilter が含まれています。

▼「app/Filament/Resources/PatientResource.php」

の table() メソッド内の filters() メソッドを編集

            // フィルター定義
            ->filters([
                Tables\Filters\SelectFilter::make('type')
                    ->options([     // フィルター選択肢
                        'cat' => 'Cat',
                        'dog' => 'Dog',
                        'rabbit' => 'Rabbit',
                    ]),
            ])

ページをリロードすると、右上隅 (検索フォームの隣) に新しいフィルター アイコンが表示されます。フィルターにより、患者タイプのリストを含む選択メニューが開きます。患者をタイプ別にフィルタリングしてみてください。

リレーションマネージャーの導入

現在、私たちのシステムでは患者をその飼い主と関連付けることができます。しかし、3 番目のレベルが必要な場合はどうなるでしょうか?患者は治療を求めて獣医師の診療所を訪れますが、システムはこれらの治療を記録し、患者と関連付けることができる必要があります。

1 つのオプションは、治療を患者に関連付ける選択フィールドを含む新しい治療リソースを作成することです。しかし、治療を他の患者情報とは別に管理することは、ユーザーにとって煩雑です。 Filament は、この問題を解決するために「リレーション マネージャー」を使用します。

リレーションマネージャーは、親リソースの編集画面に既存のリソースの関連レコードを表示するテーブルです。たとえば、私たちのプロジェクトでは、編集フォームのすぐ下で患者の治療を表示および管理できます。

Filament の「アクション」を使用してモーダル フォームを開いて、患者のテーブルから直接治療を作成、編集、削除することもできます。

make:filament-relation-manager 職人コマンドを使用してリレーション マネージャーをすばやく作成し、患者リソースを関連する治療に接続します。

php artisan make:filament-relation-manager PatientResource treatments description

「app/Filament/Resources/PatientResource/RelationManagers/TreatmentsRelationManager.php」が作成されます。

🔵PatientResource は、オーナー モデルのリソース クラスの名前です。治療は患者に属するため、治療は [患者の編集] ページに表示される必要があります。
🔵treatments は、前に作成した患者モデル内の関係の名前です。
🔵description は、処理テーブルから表示する列です。

これにより、PatientResource/RelationManagers/TreatmentsRelationManager.php ファイルが作成されます。新しいリレーション マネージャーを PatientResource の getRelations() メソッドに登録する必要があります。

▼「app/Filament/Resources/PatientResource.php」

の getRelations() メソッドを編集します。

    public static function getRelations(): array
    {
        return [
            RelationManagers\TreatmentsRelationManager::class,
        ];
    }

TreatmentsRelationManager.php ファイルには、make:filament-relation-manager artisanコマンドのパラメーターを使用してフォームと表が事前に設定されたクラスが含まれています。リソースの場合と同様に、リレーション マネージャーのフィールドとカラムをカスタマイズできます。

患者の 1 人の編集ページにアクセスします。その患者の治療法を作成、編集、削除、および一覧表示できるようになっているはずです。

▼治療内容を入力して「作成」ボタンで登録

▼登録した治療内容が一覧表示されます。

治療フォームの設定

デフォルトでは、テキストフィールドはフォームの幅の半分しか広がりません。説明フィールドには多くの情報が含まれる可能性があるため、フィールドがモーダル フォームの幅全体に広がるように、columnSpan(‘full’) メソッドを追加します。

▼「app/Filament/Resources/PatientResource/RelationManagers/TreatmentsRelationManager.php」

の form() メソッド内の schema() メソッドを編集します。

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('description')
                    ->required()
                    ->maxLength(255)
                    ->columnSpan('full'),
            ]);
    }

治療に関する詳細を追加するために使用できるメモ フィールドを追加しましょう。 textarea フィールドを columnSpan(‘full’) で使用できます。

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('description')
                    ->required()
                    ->maxLength(255)
                    ->columnSpan('full'),
                Forms\Components\Textarea::make('notes')
                    ->maxLength(65535)
                    ->columnSpan('full'),
            ]);
    }

▼モーダルフォームにテキストエリアが追加されています

価格フィールドの構成

治療の価格フィールドを追加しましょう。テキスト入力をいくつかのカスタマイズとともに使用して、通貨入力に適したものにすることができます。これは、検証を追加し、モバイル デバイスのキーボード レイアウトを変更する numeric() である必要があります。 prefix() メソッドを使用して、希望の通貨プレフィックスを追加します。たとえば、prefix(‘€’) は、保存された出力値に影響を与えることなく、入力の前に € を追加します。

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('description')
                    ->required()
                    ->maxLength(255)
                    ->columnSpan('full'),
                Forms\Components\Textarea::make('notes')
                    ->maxLength(65535)
                    ->columnSpan('full'),
                Forms\Components\TextInput::make('price')
                    ->numeric()
                    ->prefix('€')
                    ->maxValue(42949672.95),
            ]);
    }

価格を整数にキャストする

Filament は、四捨五入や精度の問題を回避するために、通貨値を (浮動小数点数ではなく) 整数として保存します。これは、Laravel コミュニティで広く受け入れられているアプローチです。ただし、これには、取得時に整数を浮動小数点に変換し、データベースに保存するときに整数に戻すキャストを Laravel で作成する必要があります。次のartisanコマンドを使用してキャストを作成します。

php artisan make:cast MoneyCast

「app/Casts/MoneyCast.php」が作成されます。

新しい app/Casts/MoneyCast.php ファイル内で、get() メソッドと set() メソッドを更新します。

▼「app/Casts/MoneyCast.php」の get() と set() を編集します。

    public function get(Model $model, string $key, mixed $value, array $attributes): mixed
    {
        // Transform the integer stored in the database into a float.
        return round(floatval($value) / 100, precision: 2);
    }

    public function set(Model $model, string $key, mixed $value, array $attributes): mixed
    {
        // Transform the float into an integer for storage.
        return round(floatval($value) * 100);
    }

ここで、MoneyCast を治療モデルの価格属性に追加します。

▼「app/Models/Treatment.php」を編集

※宣言部を追記

use App\Casts\MoneyCast;

※プロパティ「$casts」を追記

    protected $casts = [
        'price' => MoneyCast::class,
    ];

※完成形

<?php

namespace App\Models;

use App\Casts\MoneyCast;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Treatment extends Model
{
    use HasFactory;

    protected $casts = [
        'price' => MoneyCast::class,
    ];

    public function patient(): BelongsTo
    {
        return $this->belongsTo(Patient::class);
    }
}

治療一覧表のセットアップ

以前にリレーション マネージャーを生成したときに、説明テキスト列が自動的に追加されました。また、通貨プレフィックスを付けた価格の sortable() 列を追加しましょう。 Filament Money() メソッドを使用して、価格列をお金としてフォーマットします。この場合は ユーロ (€) です。

▼「app/Filament/Resources/PatientResource/RelationManager/TreatmentsRelationManager.php」

の table() メソッド内の columns() メソッドを編集

            ->columns([
                Tables\Columns\TextColumn::make('description'),
                Tables\Columns\TextColumn::make('price')
                    ->money('EUR')
                    ->sortable(),
            ])

また、デフォルトの created_at タイムスタンプを使用して治療がいつ実施されたかを示す列を追加しましょう。 dateTime() メソッドを使用して、人間が判読できる形式で日付と時刻を表示します。

有効な PHP 日付書式設定文字列を dateTime() メソッドに渡すことができます (例: dateTime(‘m-d-Y h:i A’))。

            ->columns([
                Tables\Columns\TextColumn::make('description'),
                Tables\Columns\TextColumn::make('price')
                    ->money('EUR')
                    ->sortable(),
                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime('Y年m月d日(D) H時i分s秒(T)'),
            ])

ウィジェットの導入

Filament widgetsは、ダッシュボードに情報、特に統計を表示するコンポーネントです。ウィジェットは通常、パネルのデフォルトのダッシュボードに追加されますが、リソース ページを含む任意のページに追加できます。 Filament には、重要な統計を簡単な概要で表示するための統計ウィジェットなどの組み込みウィジェットが含まれています。インタラクティブなグラフをレンダリングできるグラフ ウィジェットテーブル ウィジェットを使用すると、テーブル ビルダーを簡単に埋め込むことができます。

デフォルトのダッシュボード ページに統計ウィジェットを追加しましょう。このウィジェットには、患者の種類ごとの統計と、時間の経過とともに実施された治療を視覚化するグラフが含まれています。

統計ウィジェットの作成

次のartisanコマンドを使用して、患者のTypeをレンダリングする統計ウィジェットを作成します。

プロンプトが表示されたら、リソースを指定せず、場所として「admin」を選択します。

php artisan make:filament-widget PatientTypeOverview --stats-overview

▼どのリソースにウィジェットを追加するか訊かれるが、

何も入力せずに、そのまま[Enter]で確定します。

▼「The [admin] panel」を選択して[Enter]で確定します。

これにより、新しい app/Filament/Widgets/PatientTypeOverview.php ファイルが作成されます。それを開き、 getStats() メソッドから Stat インスタンスを返します。

▼「app/Filament/Widgets/PatientTypeOverview.php」を編集

※宣言部に追記

use App\Models\Patient;

※ getStats() メソッドの return に追記

    protected function getStats(): array
    {
        return [
            Stat::make('Cats', Patient::query()->where('type', 'cat')->count()),
            Stat::make('Dogs', Patient::query()->where('type', 'dog')->count()),
            Stat::make('Rabbits', Patient::query()->where('type', 'rabbit')->count()),
        ];
    }

ダッシュボードを開くと、新しいウィジェットが表示されるはずです。各統計には、指定されたタイプの患者の総数が表示されます。

▼ダッシュボードに統計が表示されました。

グラフウィジェットの作成

ダッシュボードにグラフを追加して、時間の経過とともに実施された治療の数を視覚化しましょう。次の職人コマンドを使用して、新しいグラフ ウィジェットを作成します。

プロンプトが表示されたら、リソースを指定せず、場所として「admin」を選択し、グラフの種類として「折れ線グラフ」を選択します。

php artisan make:filament-widget TreatmentsChart --chart

▼どのリソースに追加するか訊かれるが未入力のまま[Enter]で確定

▼「The [admin] panel」を選択して[Enter]で確定

▼種類を訊かれるので「Line Chart」を選択し[Enter]で確定

app/Filament/Widgets/TreatmentsChart.php を開き、チャートの $heading を「Treatments」に設定します。

▼「app/Filament/Widgets/TreatmentsChart.php」を編集

※プロパティ「$heading」の値を「Treatments」に修正

    protected static ?string $heading = 'Treatments';

getData() メソッドは、データセットとラベルの配列を返します。各データセットは、チャート上にプロットするラベル付きの点の配列であり、各ラベルは文字列です。この構造は、Filament がグラフのレンダリングに使用する Chart.js ライブラリと同じです。

Eloquent モデルからチャート データを入力するには、filament は flowframe/laravel-trend パッケージをインストールすることをお勧めします。

composer require flowframe/laravel-trend

getData() を更新して、過去 1 年間の月ごとの治療数を表示します。

▼「app/Filament/Widgets/TreatmentsChart.php」を編集

※宣言部追記

use App\Models\Treatment;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;

※ getData() メソッドを編集

    protected function getData(): array
    {
        $data = Trend::model(Treatment::class)
            ->between(
                start: now()->subYear(),
                end: now(),
            )
            ->perMonth()
            ->count();
    
        return [
            'datasets' => [
                [
                    'label' => 'Treatments',
                    'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
                ],
            ],
            'labels' => $data->map(fn (TrendValue $value) => $value->date),
        ];
    }

次に、ダッシュボードで新しいグラフ ウィジェットを確認してください。

ダッシュボード ページをカスタマイズして、グリッドと表示されるウィジェットの数を変更できます。

▼ダッシュボードに折れ線グラフが表示されました

パネルビルダーを使用した次のステップ

おめでとう!基本的な Filament アプリケーションを構築する方法は理解できたので、さらに学習するためのヒントをいくつか示します。

🔵リソースに属さないカスタム ページをパネルに作成します。
🔵ユーザー入力を収集したり確認したりするためのモーダルを使用して、ページやリソースにアクション ボタンを追加する方法について詳しく説明します。
🔵利用可能なフィールドを調べて、ユーザーからの入力を収集します。
🔵フォーム レイアウト コンポーネントのリストを確認してください。
🔵CSS に触れることなく、複雑で応答性の高いテーブル レイアウトを構築する方法を学びましょう。
🔵テーブルに要約を追加する
🔵一連のヘルパー メソッドを使用して、パネルの自動テストを作成します。

以上、お疲れさまでした。

コメント

タイトルとURLをコピーしました