mcpField
U
unopim-datagrid

unopim-datagrid

github.com/unopim開発140 回インストール2 週間前に更新
リポジトリ

unopim-datagrid について

UnoPim の管理画面でデータグリッドや一覧ページを実装するためのリポジトリ向けスキルです。クエリ、列、操作、翻訳、Blade の規約と実例を示します。

主な機能

  1. 01データグリッド構成とクエリ規則
  2. 02列と操作の設定要件
  3. 03操作の権限チェック
  4. 04HTML エスケープとラベル翻訳
  5. 05コントローラーと一覧 Blade のパターン

活用シーン

  1. 01管理画面の一覧グリッド実装
  2. 02権限付き行操作や一括操作の追加
  3. 03モジュール一覧ページの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/unopim/agent-skills --skill unopim-datagrid

インストール後、Claude Code で/unopim-datagridを入力して読み込まれたか確認します。

詳細

UnoPim DataGrid

以下の実例に合わせてください。エンジン API を推測して作成しないでください。

  • Grid クラス:packages/Webkul/AiAgent/src/DataGrids/Credential/CredentialDataGrid.php
  • 一括アクション:packages/Webkul/Admin/src/DataGrids/Catalog/ProductDataGrid.php
  • 一覧 Blade:packages/Webkul/Webhook/src/Resources/views/webhooks/index.blade.php
  • プレフィックス付きの生 SQL:packages/Webkul/Measurement/src/DataGrids/UnitDataGrid.php

ルール

  • Grid はサブディレクトリ src/DataGrids/{Section}/{Name}DataGrid.php に配置し、Webkul\DataGrid\DataGrid を継承します。
  • prepareQueryBuilder() では、プレーンなテーブル名(プレフィックスなし)を指定して DB::table() を使用する必要があります。Laravel が env('DB_PREFIX', '') を適用します。ここで Eloquent モデルを使用してクエリを実行してはいけません。
  • テーブル名を指定する生のフラグメント(selectRaw、whereRaw、orderByRaw、DB::raw)では、必ず DB::getTablePrefix() を先頭に付けてください。packages/Webkul/Measurement/src/DataGrids/UnitDataGrid.php を参照してください。CI では MySQL と PostgreSQL の両方を実行するため、MySQL 専用 SQL(GROUP_CONCAT、バッククォート、DATE_FORMAT)は使用しないでください。
  • addColumn() では、index、label、type、searchable、filterable、sortable の6つすべてを設定する必要があります。エンジンは3つのフラグを null 合体なしで読み取るため、どれかを省略するとリクエスト時に「Undefined array key」が発生します。
  • フックのシグネチャ:抽象基底クラスでは prepareColumns()/prepareActions() に型を宣言していないため、PHPDoc の @return のみを付けた形式(古い Admin Grid)と : void を付けた形式(Credential の実例を含む最新の Grid)のどちらもコンパイルできます。新しいコードでは : void を使用し、既存コードを編集する場合は既存のスタイルに合わせてください。どちらのスタイルも違反として指摘してはいけません。
  • アクションの url には任意の callable を指定できます。fn ($row): string => route(...) を優先してください。一括アクションの url は通常の route(...) 文字列であり、callable ではありません。
  • すべてのアクションと一括アクションに bouncer()->hasPermission() による認可チェックを設定してください。一括アクションの ACL キーは、ルート名に合わせて snake_case({module-slug}.credentials.mass_delete)にします。ハイフン区切り(mass-delete)は使用してはいけません。
  • Column の closure の出力は生の HTML としてレンダリングされます。エンジンが strip_tags() でサニタイズするのはプレーンな文字列セルのみです。closure の HTML にユーザー提供の値を埋め込む場合は、必ず e() でエスケープしてください。
  • すべてのラベルとタイトルで trans() を使用し、キーはまず en_US に追加してから、残り33のロケールにも追加してください。ブール値のバッジには、true の場合は label-active、false の場合は label-info text-gray-600 dark:text-gray-300 を使用してください。
  • メソッド本体や配列リテラル内にコメントを記述しないでください。メソッドの PHPDoc は1行の命令形の要約にし、ネイティブの戻り値型がない場合に限り @return を記述してください。

Grid クラス

<?php

namespace Webkul\{ModuleName}\DataGrids\Credential;

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Webkul\DataGrid\DataGrid;

class CredentialDataGrid extends DataGrid
{
    /**
     * Prepare query builder.
     *
     * @return Builder
     */
    public function prepareQueryBuilder()
    {
        return DB::table('{module}_credentials')
            ->select('id', 'label', 'status', 'created_at');
    }

    /**
     * Prepare columns.
     */
    public function prepareColumns(): void
    {
        $this->addColumn([
            'index'      => 'label',
            'label'      => trans('{module-name}::app.credentials.datagrid.label'),
            'type'       => 'string',
            'searchable' => true,
            'filterable' => true,
            'sortable'   => true,
        ]);

        $this->addColumn([
            'index'      => 'status',
            'label'      => trans('{module-name}::app.credentials.datagrid.status'),
            'type'       => 'boolean',
            'searchable' => false,
            'filterable' => true,
            'sortable'   => true,
            'closure'    => fn ($row): string => $row->status
                ? '<span class="label-active">'.trans('admin::app.common.yes').'</span>'
                : '<span class="label-info text-gray-600 dark:text-gray-300">'.trans('admin::app.common.no').'</span>',
        ]);
    }

    /**
     * Prepare actions.
     */
    public function prepareActions(): void
    {
        if (bouncer()->hasPermission('{module-slug}.credentials.edit')) {
            $this->addAction([
                'icon'   => 'icon-edit',
                'title'  => trans('{module-name}::app.credentials.datagrid.edit'),
                'method' => 'GET',
                'url'    => fn ($row): string => route('{module-slug}.credentials.edit', $row->id),
            ]);
        }

        if (bouncer()->hasPermission('{module-slug}.credentials.delete')) {
            $this->addAction([
                'icon'   => 'icon-delete',
                'title'  => trans('{module-name}::app.credentials.datagrid.delete'),
                'method' => 'DELETE',
                'url'    => fn ($row): string => route('{module-slug}.credentials.destroy', $row->id),
            ]);
        }
    }

    /**
     * Prepare mass actions.
     */
    public function prepareMassActions(): void
    {
        if (bouncer()->hasPermission('{module-slug}.credentials.mass_delete')) {
            $this->addMassAction([
                'title'   => trans('{module-name}::app.credentials.datagrid.delete'),
                'url'     => route('{module-slug}.credentials.mass_delete'),
                'method'  => 'POST',
                'options' => ['actionType' => 'delete'],
            ]);
        }
    }
}

ステータスの一括更新では、packages/Webkul/Admin/src/DataGrids/Catalog/ProductDataGrid.php の catalog.products.mass_update ブロックから、ラベルと値のペアを含む options 配列をコピーしてください。

コントローラー

public function index()
{
    if (request()->ajax()) {
        return resolve(CredentialDataGrid::class)->toJson();
    }

    return view('{module-name}::credentials.index');
}

一覧 Blade

admin::layouts.master と @extends は存在しません。admin レイアウトはコンポーネントです。Create はインデックスページ上のモーダルであり、store() は編集ページへリダイレクトします(Webhook の実例から v-create-webhook-form をコピーしてください)。GET の create ページは追加しないでください。

<x-admin::layouts>
    <x-slot:title>
        @lang('{module-name}::app.credentials.index.title')
    </x-slot>

    <x-admin::layouts.page-header :title="trans('{module-name}::app.credentials.index.title')" />

    <x-admin::datagrid :src="route('{module-slug}.credentials.index')" />
</x-admin::layouts>

コメント