Filament で新規カスタマイズページを作成する
この記事について
Filamentのカスタマイズ方法について検証してみた 部分カスタマイズ編
- 上記記事の続きです
- 今回はFilamentの新規カスタマイズページについて検証してみます
新規カスタマイズページを作成する
新規カスタマイズページに関しては、下記が大変参考になりました。
https://github.com/askdkc/filamentphp_howto/blob/main/sub/add-custom-page.md
公式のドキュメントはこちら
新規作成する
流れとしては前記事の作業の流れと同様で、コマンドでファイルを生成し、中身を作っていくという感じです。
適当にOther
というページを作ってみます。
下記コマンドを実行します。
php artisan make:filament-page Other
コマンド実行後は、下記ファイルが生成されます。
src/app/Filament/Pages/Other.php
src/resources/views/filament/pages/other.blade.php
表示を確認してみます。
other.blade.php
を下記のようにしてみます。
<x-filament::page>
<p style="color: #00ff00; font-size: 3rem; line-height: 1;">Other表示</p>
</x-filament::page>
カスタムページでは、前記事で紹介したgetHeaderWidgets
、getFooterWidgets
メソッドが使用できます。
getHeaderWidgets
を使って、前記事でCustomerページに表示したMstItemウィジェットをヘッダー部分に表示してみます。
protected function getHeaderWidgets(): array
{
return [MstItemOverview::class];
}
表示を確認すると、下記のように表示されます。
Other.php
はgetViewData
メソッドも使用できるので、これらも使ってカスタマイズしていく形になりそうです。
自動生成ページに新規カスタマイズページのリンクを作成する
Customer
ページ下にあるCustomersOther
ページを新規に作成し、Customer
ページリンクを用意します。
下記コマンドを実行します。
php artisan make:filament-page CustomersOther --resource=CustomerResource --type=custom
コマンド実行後、下記ファイルが生成されます。
src/app/Filament/Resources/CustomerResource/Pages/CustomersOther.php
src/resources/views/filament/resources/customer-resource/pages/customers-other.blade.php
CustomerResource.php
のgetPages
メソッドを下記のように編集します。
public static function getPages(): array
{
return [
"index" => Pages\ListCustomers::route("/"),
"create" => Pages\CreateCustomer::route("/create"),
+ "customers-other" => Pages\CustomersOther::route(
+ "/customers-other"
+ ),
"edit" => Pages\EditCustomer::route("/{record}/edit"),
];
}
ここはいわゆるルーティングの定義のようなものとなります。
一覧ページのテーブル内の右上にリンクを表示させます。
CustomerResource.php
のtable
メソッドを下記のように編集します。
return $table
+ ->headerActions([
+ Tables\Actions\Action::make("カスタムOther")->url(
+ static::getUrl("customers-other")
+ ),
+ ])
->columns([
~省略~
こうするとテーブル右上にリンクが表示されます。
移動先のページは、用途にあわせて編集していきます。
また、テーブル内にユーザーデータごとのリンクを用意することも可能です。
編集リンクのとなりにPersonal
というリンクを作成し、ボタンをクリックしたらユーザーごとのcustomer-personal
ページに移動できるようにしてみます。
下記コマンドを実行します。
php artisan make:filament-page CustomerPersonal --resource=CustomerResource --type=custom
コマンド実行後、下記ファイルが生成されます。
src/app/Filament/Resources/CustomerResource/Pages/CustomerPersonal.php
src/resources/views/filament/resources/customer-resource/pages/customer-personal.blade.php
CustomerResource.php
のgetPages
メソッドを下記のように編集します。
public static function getPages(): array
{
return [
"index" => Pages\ListCustomers::route("/"),
"create" => Pages\CreateCustomer::route("/create"),
"customers-other" => Pages\CustomersOther::route(
"/customers-other"
),
+ "customers-personal" => Pages\CustomerPersonal::route(
+ "/{customerId}/customers-personal"
+ ),
"edit" => Pages\EditCustomer::route("/{record}/edit"),
];
}
テーブルの編集リンクの右となりにリンクを表示させます。
CustomerResource.php
のtable
メソッドを下記のように編集します。
return $table
~省略~
->actions([
Tables\Actions\EditAction::make(),
+ Tables\Actions\Action::make("personal")->url(function (
+ Customer $record
+ ) {
+ return static::getUrl("customers-personal", [
+ "customerId" => $record->id,
+ ]);
+ }),
])
~省略~
これでリンク自体は作成できます。
試しに、移動先であるcustomer-personal
ページも少し加工します。
CustomerPersonal.php
を下記のように編集します。
+ public string $customerId;
+ public function mount(string $customerId): void
+ {
+ $this->customerId = $customerId;
+ }
引数の$customerId
には、リンクで定義したCustomer.id
が入っています。
mount
メソッドは、Livewireのライフサイクルメソッドの1つで、コンポーネントが呼び出された初回だけ実行されます。
次に、customer-personal.blade.php
を下記を追加します。
<x-filament::page>
+ <p>customer-personal {{$customerId}}</p>
</x-filament::page>
試しにページに移動してみると、下記のようにユーザーごとのページが表示されます。
その他
テーブルの列名を加工したい
テーブルの列名などで文字色を変えたり、文字を大きくしたりしたい場合は、label
メソッドを下記のようにすると加工できます。
Tables\Columns\TextColumn::make("mst_item_id")->label(
function () {
// 文字色をピンクにする
return new HtmlString(
"<b style='color: #ff69b4; initial-letter: normal'>マスタアイテムid</b>"
);
}
),
これはlavel
メソッドだけでなく、description
メソッドなど引数にHtmlable
が指定可能なメソッドなら可能そうです。
結合したカラムの検索
Customerページで表示している顧客情報の「名前」部分については、table
メソッドで下記のようにしています。
Tables\Columns\TextColumn::make("name")
->label("名前")
->sortable()
->getStateUsing(function (Customer $record): string {
return $record->name_sei . $record->name_mei;
})
->searchable(
condition: ["name_sei", "name_mei"],
isIndividual: true,
isGlobal: false
),
姓と名を連結して表示し、「名前」列に対して検索が実行できるようにしています。
ただ、これだと姓/名それぞれのワードで検索するとヒットしますが、姓+名のワードで検索するとヒットしないという問題がありました。
(「山田大」と入力すると、「レコードが見つからない」という表示がされます)
これについて検証したところ、姓と名の間に半角スペースを入れるとヒットするようになります。
カラムを連結して表示している場合は、テーブルのカラムにあわせて単語を半角スペースで区切ると検索がしやすくなるかもしれません。
まとめ
部分カスタマイズでも述べましたが、いろいろ検証して感じたのは、Livewireの知見があるかないかでFilamentの難易度は変わるなと思いました。
基本自動生成で作成する機能はCRUD機能のみとし、少しでも特殊な用途となる画面についてはカスタマイズページとして作成する方が実装しやすいかなと思います。
業務でFilamentを使用する場合は、事前にチームのエンジニアや実際の管理画面を運用していく方たちの話を聞いて、どういったことを実現したいかと工数感を擦りあわせて、採用するか検討していければいいなと思いました。
参考
Discussion