# 画面設計書 28-カテゴリ一覧画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における「カテゴリ一覧画面」の設計仕様を定義するものである。

### 本画面の処理概要

カテゴリ一覧画面は、商品カテゴリをツリー構造で一覧表示し、カテゴリの検索・作成・編集・削除を行うための画面である。

**業務上の目的・背景**：ECサイトにおいて商品カテゴリは商品の分類・検索・ナビゲーションの基盤となる。カテゴリを階層構造で管理することで、顧客が商品を見つけやすくなり、サイトの使いやすさが向上する。この画面により、管理者はカテゴリの全体像を把握し、必要に応じて追加・編集・削除・並び替えを行える。

**画面へのアクセス方法**：サイドメニューの「カテゴリ」をクリックすることでアクセス可能。URLは `/categories` となる。

**主要な操作・処理内容**：
1. カテゴリ一覧のツリー形式での表示（展開・折りたたみ可能）
2. カテゴリの検索（検索時は階層パスを表示）
3. 新規カテゴリの作成画面への遷移
4. カテゴリの並び替え画面への遷移
5. カテゴリの編集・削除

**画面遷移**：カテゴリ作成画面、カテゴリ詳細画面、カテゴリ並び替え画面への遷移が可能。

**権限による表示制御**：カテゴリ管理権限を持つユーザーのみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | 商品カテゴリ管理 | 主機能 | カテゴリの一覧表示・作成・編集・削除 |

## 画面種別

一覧

## URL/ルーティング

`/categories`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力/出力 | 説明 |
|--------|--------|----------|------|-----------|------|
| 検索クエリ | q | string | - | 入力（URLパラメータ） | カテゴリ名での検索 |
| ページ番号 | offset | number | - | 入力（URLパラメータ） | ページネーションのオフセット |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| カテゴリ名 | string | カテゴリの名称（ツリー表示時は展開アイコン付き） |
| ハンドル | string | URLパスに使用されるスラッグ（先頭に/付与） |
| ステータス | StatusBadge | アクティブ/非アクティブの状態 |
| 可視性 | StatusBadge | 公開/内部の可視性設定 |
| アクションメニュー | ActionMenu | 編集・翻訳管理・削除のアクション |

## イベント仕様

### 1-ツリー展開/折りたたみ

カテゴリ行の展開アイコンをクリックすると、子カテゴリの表示/非表示を切り替える。アイコンは展開状態で90度回転する。

### 2-検索入力

検索ボックスにテキストを入力すると、カテゴリ名でフィルタリングされる。検索時はinclude_ancestors_tree=trueで親カテゴリの情報も取得し、階層パスを表示する。

### 3-作成ボタン押下

「作成」ボタンをクリックすると、カテゴリ作成画面（/categories/create）に遷移する。

### 4-整理ボタン押下

「整理」ボタンをクリックすると、カテゴリ並び替え画面（/categories/organize）に遷移する。カテゴリが1件以上存在する場合のみ表示される。

### 5-行クリック

カテゴリ行をクリックすると、そのカテゴリの詳細画面（/categories/:id）に遷移する。

### 6-編集アクション選択

アクションメニューから「編集」を選択すると、カテゴリ編集画面（/categories/:id/edit）に遷移する。

### 7-翻訳管理アクション選択

翻訳機能が有効な場合、アクションメニューから「翻訳を管理」を選択すると、翻訳編集画面に遷移する。

### 8-削除アクション選択

アクションメニューから「削除」を選択すると、確認ダイアログを表示後、カテゴリを削除する。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 削除アクション選択 | product_category | DELETE | カテゴリを削除 |

### テーブル別更新項目詳細

#### product_category

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | id = 選択したカテゴリID | 子カテゴリがある場合は削除不可 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| categories.domain | ヘッダー | カテゴリ | ヘッダー表示 |
| categories.subtitle | 説明 | カテゴリの管理 | サブタイトル表示 |
| categories.organize.action | ボタン | 整理 | 整理ボタンラベル |
| actions.create | ボタン | 作成 | 作成ボタンラベル |
| categories.delete.confirmation | 確認 | {name}を削除してもよろしいですか？ | 削除確認ダイアログ |
| categories.delete.successToast | 成功 | {name}が削除されました | 削除成功時 |
| - | エラー | {エラーメッセージ} | 削除失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| API呼び出し失敗 | エラーをthrowし、エラーバウンダリで処理 |
| 削除失敗（子カテゴリがある等） | トースト通知でエラーメッセージを表示 |

## 備考

- SingleColumnPageレイアウトを使用
- useProductCategoriesフックでカテゴリ一覧を取得
- 検索未実行時：include_descendants_tree=trueで子カテゴリをツリー表示
- 検索実行時：include_ancestors_tree=trueで親カテゴリの階層パスを表示
- keepPreviousDataでページネーション時のちらつき防止
- useDataTableフックでテーブル状態管理（enableExpandableRows=true）
- 拡張ポイント：product_category.list.before/after でウィジェット追加可能
- 翻訳機能フラグ（translation）で翻訳管理アクションの表示を制御

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

カテゴリの階層構造とAPIレスポンスの形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | category-list-table.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/category-list-table.tsx` | クエリパラメータの切り替え（26-37行目）で検索時と通常時の違いを確認 |
| 1-2 | use-category-table-columns.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/use-category-table-columns.tsx` | カラム定義（27-113行目）でテーブル表示内容を確認 |

**読解のコツ**: 検索未実行時はinclude_descendants_tree、検索実行時はinclude_ancestors_treeで異なるツリー情報を取得している。

#### Step 2: エントリーポイントを理解する

ルートコンポーネントの処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | category-list.tsx | `packages/admin/dashboard/src/routes/categories/category-list/category-list.tsx` | SingleColumnPageでレイアウト構成（8-17行目） |
| 2-2 | category-list.tsx | `packages/admin/dashboard/src/routes/categories/category-list/category-list.tsx` | useExtensionでウィジェット取得（6行目） |

**主要処理フロー**:
1. **6行目**: useExtensionでカスタムウィジェットを取得
2. **8-17行目**: SingleColumnPageでページレイアウトを構成
3. **16行目**: CategoryListTableコンポーネントでテーブルを描画

#### Step 3: テーブルコンポーネントの処理を理解する

カテゴリ一覧テーブルの実装詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | category-list-table.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/category-list-table.tsx` | useProductCategoriesでデータ取得（39-47行目） |
| 3-2 | category-list-table.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/category-list-table.tsx` | useDataTableで展開可能行を設定（51-59行目） |
| 3-3 | category-list-table.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/category-list-table.tsx` | CategoryRowActionsで行アクション（103-149行目） |

**主要処理フロー**:
- **24行目**: useCategoryTableQueryでURL検索パラメータを解析
- **26-37行目**: 検索クエリの有無でAPIパラメータを切り替え
- **51-59行目**: useDataTableでテーブル状態を管理（getSubRowsで子カテゴリ取得）
- **61-62行目**: 整理ボタンの表示条件判定
- **78-81行目**: 整理ボタンの描画（カテゴリが存在する場合のみ）
- **103-149行目**: 行アクションメニューの実装

### プログラム呼び出し階層図

```
CategoryList (category-list.tsx:5-19)
    │
    ├─ useExtension() → ウィジェット取得
    │
    └─ CategoryListTable (category-list-table.tsx:21-101)
           │
           ├─ useCategoryTableQuery() → URLパラメータ解析
           │
           ├─ useProductCategories(query) → カテゴリ一覧取得
           │      └─ sdk.admin.productCategory.list()
           │
           ├─ useColumns() → カラム定義
           │      └─ useCategoryTableColumns()
           │             └─ getIsActiveProps() / getIsInternalProps()
           │
           ├─ useDataTable() → テーブル状態管理
           │
           └─ CategoryRowActions × N
                  │
                  ├─ useDeleteProductCategoryAction()
                  │      └─ useDeleteProductCategory()
                  │             └─ sdk.admin.productCategory.delete()
                  │
                  └─ ActionMenu → 編集・翻訳・削除
```

### データフロー図

```
[入力]                           [処理]                              [出力]

URL検索パラメータ(q, offset) ───▶ useCategoryTableQuery ───▶ searchParams
                                          │
                                          ▼
                                   クエリ条件分岐
                                          │
                          ┌───────────────┴───────────────┐
                          ▼                               ▼
                    検索未実行時                      検索実行時
              include_descendants_tree         include_ancestors_tree
              parent_category_id: null               親階層パス表示
                          │                               │
                          └───────────┬───────────────────┘
                                      ▼
                              useProductCategories ───▶ カテゴリ一覧
                                      │
                                      ▼
                                useDataTable
                                      │
                          ┌───────────┴───────────┐
                          ▼                       ▼
                    ツリー表示                検索結果表示
                  (展開/折りたたみ)          (階層パス表示)
                          │                       │
                          └───────────┬───────────┘
                                      ▼
                                _DataTable描画
                                      │
行クリック ─────────────────────────▶ navigateTo() ───▶ 詳細画面遷移
削除選択 ──────────────────────────▶ handleDelete() ───▶ 削除処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| category-list.tsx | `packages/admin/dashboard/src/routes/categories/category-list/category-list.tsx` | ソース | 画面のエントリーポイント |
| category-list-table.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/category-list-table.tsx` | ソース | カテゴリ一覧テーブルコンポーネント |
| use-category-table-columns.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/use-category-table-columns.tsx` | ソース | テーブルカラム定義フック |
| use-category-table-query.tsx | `packages/admin/dashboard/src/routes/categories/category-list/components/category-list-table/use-category-table-query.tsx` | ソース | URLクエリパラメータ解析フック |
| use-delete-product-category-action.tsx | `packages/admin/dashboard/src/routes/categories/common/hooks/use-delete-product-category-action.tsx` | ソース | カテゴリ削除アクションフック |
| useProductCategories | `packages/admin/dashboard/src/hooks/api/categories.ts` | ソース | カテゴリ一覧取得フック |
| useDeleteProductCategory | `packages/admin/dashboard/src/hooks/api/categories.ts` | ソース | カテゴリ削除フック |
| SingleColumnPage | `packages/admin/dashboard/src/components/layout/pages/` | ソース | 1カラムページレイアウト |
| _DataTable | `packages/admin/dashboard/src/components/table/data-table/` | ソース | データテーブルコンポーネント |
