Filament 5.8 มีอะไรใหม่ โหลดส่วนของฟอร์มเมื่อเปิดดู และตารางจำการจัดกลุ่ม

Filament 5.8 เพิ่ม deferLoading() ให้ section, tab, wizard และรายการใน repeater เรนเดอร์เมื่อผู้ใช้เปิดดูจริง ตารางจำการจัดกลุ่มไว้ใน session ได้ hook อย่าง afterSave() ใน trait ไม่โดน page ทับอีกแล้ว และมีของเล็ก ๆ อีกหลายตัว

เผยแพร่
เวลาอ่าน
4 นาที
สรุปจาก
Paul Redmond · laravel-news.com
ในโพสต์นี้ 4 หัวข้อ
  1. deferLoading() ให้ส่วนที่ยังไม่เห็นรอโหลดทีหลัง
  2. ตารางจำการจัดกลุ่มไว้ใน session
  3. hook ใน trait ไม่โดน page ทับอีกแล้ว
  4. ของเล็ก ๆ ที่เพิ่มมา

deferLoading() ให้ส่วนที่ยังไม่เห็นรอโหลดทีหลัง

หน้าแก้ข้อมูลลูกค้าในระบบหลังร้านมักยาว มีข้อมูลทั่วไป ที่อยู่จัดส่ง ข้อมูลออกใบกำกับภาษี และประวัติการติดต่อ ทุก section เรนเดอร์ตั้งแต่เปิดหน้า แม้ผู้ใช้จะพับไว้หรือไม่เคยเลื่อนลงไปดู ยิ่งมี select ที่ต้อง query ตัวเลือก หน้าก็ยิ่งเปิดช้า

Filament 5.8 เพิ่ม deferLoading() (PR #19867 โดย Kian Acquoij) ส่วนที่ใส่ไว้จะขึ้นเป็นตัว loading ก่อน แล้วค่อยเรนเดอร์ field ของตัวเองใน request แยกเมื่อเลื่อนมาถึง วิธีใช้คือส่ง Schema เข้า schema() แทน array แล้วต่อท้ายด้วย deferLoading()

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

Section::make('ข้อมูลออกใบกำกับภาษี')
    ->key('taxInfo')
    ->schema(
        Schema::make()
            ->components([
                TextInput::make('tax_id'),
                TextInput::make('branch_code'),
            ])
            ->deferLoading(),
    )
    ->collapsed()

ถ้าส่วนนั้นอยู่ใน section ที่พับไว้หรือแท็บที่ยังไม่ได้เปิด Filament จะรอจนผู้ใช้กางหรือเปิดแท็บนั้นก่อน wizard ก็เหมือนกัน แต่ละ step โหลดเมื่อผู้ใช้เดินมาถึง ส่วน repeater และ builder ใส่ deferLoading() ที่ schema ของแต่ละรายการได้ เหมาะกับรายการสินค้าในใบสั่งซื้อที่มีหลายสิบแถวแล้วพับไว้

เอกสารของ v5.8.0 บอกพฤติกรรมที่ควรรู้ไว้สามข้อ

  • ทุก schema ที่ defer ต้องมี key ไม่ซ้ำกัน schema ลูกใช้ key ของ section แม่ (taxInfo ข้างบน) ถ้า component เดียวมี schema ลูกที่ defer หลายชุด ต้องใส่ key() เองให้ชุดที่เหลือ ส่วนรายการใน repeater กับ builder ได้ key จาก state path ให้เอง
  • ถ้าส่วนที่ยังไม่โหลดมี error จาก validation Filament จะโหลดส่วนนั้นให้เองเพื่อแสดง error ผู้ใช้จึงไม่ติดอยู่กับฟอร์มที่บันทึกไม่ได้โดยไม่รู้ว่าผิดตรงไหน
  • โหลดแล้วอยู่ต่อจนปิดหน้า พับกลับแล้วกางใหม่ไม่ต้องโหลดซ้ำ

deferLoading() รับ boolean หรือ closure ได้ด้วย ถ้าอยากเปิดตามเงื่อนไข เช่น defer เฉพาะตอนแก้ไข แต่ตอนสร้างใหม่ให้โหลดทั้งหมด (closure รับค่าแบบเดียวกับที่อธิบายไว้ในโพสต์เรื่อง utility injection)

ตารางจำการจัดกลุ่มไว้ใน session

ตารางของ Filament จำการเรียง การค้นหา filter และคอลัมน์ที่ซ่อนไว้ใน session ได้มานานแล้ว 5.8 เพิ่มการจัดกลุ่มเข้าไปด้วย persistGroupInSession() (PR #20165) ฝ่ายบัญชีที่ดูใบสั่งซื้อแบบจัดกลุ่มตามสถานะทุกเช้า กลับมาหน้านี้ก็ยังเห็นแบบเดิม

return $table
    ->groups(['status', 'customer.name'])
    ->defaultGroup('status', direction: 'desc')
    ->persistGroupInSession();

defaultGroup() รับ direction ได้แล้วเหมือน defaultSort() (PR #20267) เดิมกลุ่มเริ่มต้นเรียงจากน้อยไปมากอย่างเดียว รุ่นนี้ยังแก้ชื่อ hook ของ Livewire ที่ไม่ตรงกับ property $tableGrouping ด้วย เปลี่ยนการจัดกลุ่มแล้วตารางจึงกลับไปหน้าแรก ไม่ค้างอยู่หน้าที่อาจไม่มีข้อมูลแล้ว

hook ใน trait ไม่โดน page ทับอีกแล้ว

ถ้าเราเขียน trait ที่ใช้ร่วมกันหลาย page แล้วใส่ afterSave() ไว้ใน trait พอ page ไหนเขียน afterSave() ของตัวเอง ของใน trait ก็หายไปเงียบ ๆ ตามกฎของ PHP ที่เมธอดของคลาสทับเมธอดของ trait

5.8 ใช้วิธีเดียวกับ boot{TraitName}() ของ Eloquent (PR #20189) ให้ตั้งชื่อ hook ใน trait ต่อท้ายด้วยชื่อ trait แล้ว Filament จะเรียก hook ของ page ก่อน ตามด้วย hook ของทุก trait

trait LogsChanges
{
    protected function afterSaveLogsChanges(): void
    {
        // บันทึกประวัติการแก้ไข ทำงานต่อจาก afterSave() ของ page
    }
}

class EditOrder extends EditRecord
{
    use LogsChanges;

    protected function afterSave(): void
    {
        // ทำก่อน แล้ว Filament จึงเรียก afterSaveLogsChanges()
    }
}

ใช้ได้กับ page ใน panel ทั้งหน้าสร้าง แก้ไข และดูข้อมูล และใช้กับ importer ได้ด้วย

ของเล็ก ๆ ที่เพิ่มมา

  • placeholder ของ stat Stat::make('ยอดขายวันนี้', $total)->placeholder('-') แสดงขีดแทนช่องว่างเมื่อยังไม่มีค่า ถ้าอยากตั้งให้ทุก stat ใช้ Stat::configureUsing() ใน boot() ของ service provider (PR #20176)
  • ใช้หน้ายืนยันรหัส MFA ในหน้าอื่นได้ คลาส MultiFactorChallenge แยกออกมาจากหน้า login ให้ component ของเราเรียกถามรหัสก่อนทำ action อันตราย อย่างลบข้อมูลหรือเปลี่ยนบัญชีรับเงิน มีตัวจำกัดจำนวนครั้งในตัว เอกสารเตือนว่า schema ที่ว่างเปล่า validate ผ่านเสมอ จึงต้องเรียก hasEnabledProviders() ซ้ำอีกครั้งก่อน validate (PR #20353)
  • ความสูงของ editor RichEditor และ MarkdownEditor มี minHeight() กับ maxHeight() รับหน่วย CSS ค่าเริ่มต้นคือ 10rem และเมื่อเนื้อหายาวเกิน maxHeight() จะเลื่อนในกรอบแทนการยืดทั้งหน้า (PR #20258)
  • ตัวดาวน์โหลดไฟล์ export ของเราเอง override getDownloader() ใน exporter ได้ เช่น ให้ redirect ไปที่ temporary URL ของไฟล์บน S3 แทนการ stream ผ่านแอป เหมาะกับ host ที่ไม่ให้ stream ไฟล์ใหญ่ ฝั่ง importer มี getFailedRowsDownloader() สำหรับไฟล์แถวที่นำเข้าไม่ผ่าน (PR #20285)
  • คู่มือ Boost เป็น Agent Skill เดิม Laravel Boost ใส่ guideline ของ Filament ทั้งชุดเข้า context ของ AI agent ทุก session ตอนนี้เป็น skill ที่โหลดเฉพาะตอน agent แก้โค้ด Filament ประหยัด context ไปได้มาก ต้องรัน php artisan boost:install แล้วเลือก Agent Skills ตามด้วย filament/filament (skills) เพราะ boost:update อย่างเดียวไม่เพิ่มให้ (PR #20338)

รายการทั้งหมดดูได้ที่ release notes ของ v5.8.0

อ่านต่อ

ล่าสุด

ดูทั้งหมด →