怎樣透過模型讓 Filament Table 消費外部 API 資料

Marden發表於2022-12-12

有時,我們使用 Filament Table 時資料來源並非來自於資料庫表。本文將展示如何從外部資料來源(JSON API)獲取資料提供給模型使用。

安裝 calebporzio/sushi 包:

composer require calebporzio/sushi

新建 Product 模型和 Product Resource:

php artisan make:model Product
php artisan make:filament-resource Product --simple --view

將 Sushi trait 新增到 Product 模型。你可以執行 getRows() 方法從外部源獲取資料。

//app\Models\Product.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Sushi\Sushi;

class Product extends Model
{
    use Sushi;

    /**
     * Model Rows
     *
     * @return void
     */
    public function getRows()
    {
        //API
        $products = Http::get('https://dummyjson.com/products')->json();

        //filtering some attributes
        $products = Arr::map($products['products'], function ($item) {
            return Arr::only($item,
                [
                    'id',
                    'title',
                    'description',
                    'price',
                    'rating',
                    'brand',
                    'category',
                    'thumbnail',
                ]
            );
        });

        return $products;
    }
}

你可以在 Product Resource 檔案中建立表單欄位和表格欄位:

表單欄位:

//app\Filament\Resources\ProductResource.php

use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;

public static function form(Form $form): Form
{
    return $form
        ->schema([

            //title
            TextInput::make('title'),

            //brand
            TextInput::make('brand'),

            //category
            TextInput::make('category'),

            //description
            RichEditor::make('description'),

            //price
            TextInput::make('price')
                ->prefix('$'),

            //rating
            TextInput::make('rating')
                ->numeric(),
        ]);
}

表格欄位:

//app\Filament\Resources\ProductResource.php

use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;

...
->columns([

    //thumbnail
    ImageColumn::make('thumbnail')
        ->label('Image')
        ->rounded(),

    //title
    TextColumn::make('title')
        ->searchable()
        ->sortable()
        ->weight('medium')
        ->alignLeft(),

    //brand
    TextColumn::make('brand')
        ->searchable()
        ->sortable()
        ->color('secondary')
        ->alignLeft(),

    //category
    TextColumn::make('category')
        ->sortable()
        ->searchable(),

    //description
    TextColumn::make('description')
        ->sortable()
        ->searchable()
        ->limit(30),

    //price
    BadgeColumn::make('price')
        ->colors(['secondary'])
        ->prefix('$')
        ->sortable()
        ->searchable(),

    //rating
    BadgeColumn::make('rating')
    ->colors([
        'danger' => static fn ($state): bool => $state <= 3,
        'warning' => static fn ($state): bool => $state > 3 && $state <= 4.5,
        'success' => static fn ($state): bool => $state > 4.5,
    ])
    ->sortable()
    ->searchable(),

])

表格過濾器:

//app\Filament\Resources\ProductResource.php

use Filament\Tables\Filters\SelectFilter;

...
->filters([

    //brand
    SelectFilter::make('brand')
        ->multiple()
        ->options(Product::select('brand')
            ->distinct()
            ->get()
            ->pluck('brand', 'brand')
        ),

    //category
    SelectFilter::make('category')
        ->multiple()
        ->options(Product::select('category')
            ->distinct()
            ->get()
            ->pluck('category', 'category')
        ),
])

如你所見,API 是隻讀的。你可以隱藏一些Action按鈕:

//app\Filament\Resources\ProductResource.php

...
->actions([
    Tables\Actions\ViewAction::make(),
    //Tables\Actions\EditAction::make(),
    //Tables\Actions\DeleteAction::make(),
])
->bulkActions([
    //Tables\Actions\DeleteBulkAction::make(),
])
//app\Filament\Resources\ProductResource\Pages\ManageProducts.php
protected function getActions(): array
{
    return [
        //Actions\CreateAction::make(),
    ];
}

現在可以到 /admin/products 中訪問 Product 資源了!

點此檢視更多 Filament 詳情

本作品採用《CC 協議》,轉載必須註明作者和本文連結
Laravel Filament 中文站站長

相關文章