# 画面設計書 12-フォルダ表示画面

## 概要

本ドキュメントは、Payload CMSの管理画面における「フォルダ表示画面」の設計仕様を定義するものである。コレクションのドキュメントをフォルダ構造で整理・表示する画面である。

### 本画面の処理概要

フォルダ表示画面は、コレクションに紐づくドキュメントをフォルダ階層で整理・表示するための画面である。

**業務上の目的・背景**：大量のコンテンツを管理するCMSにおいて、ドキュメントをフォルダ構造で整理することは直感的で効率的なコンテンツ管理を実現する。特にメディアファイル（画像、動画、PDFなど）を扱うUploadコレクションにおいて、フォルダによる分類は業務効率を大幅に向上させる。この画面により、ユーザーはエクスプローラのようなUIでコンテンツを閲覧・管理できる。

**画面へのアクセス方法**：コレクション一覧画面のヘッダーから「フォルダ表示」ボタンをクリック、またはURLで `/{admin}/collections/{collectionSlug}/{foldersSlug}` に直接アクセスすることで表示される。特定のフォルダを開く場合は `/{admin}/collections/{collectionSlug}/{foldersSlug}/{folderID}` となる。

**主要な操作・処理内容**：
1. フォルダとドキュメントの一覧表示（グリッド表示またはリスト表示）
2. フォルダの作成・編集・削除
3. サブフォルダへのナビゲーション（フォルダを開く）
4. パンくずリストによる階層ナビゲーション
5. ドキュメントのフォルダ間移動
6. 表示形式の切り替え（グリッド/リスト）
7. ソート機能（名前順、更新日時順など）

**画面遷移**：
- 遷移元：コレクション一覧画面、ダッシュボード画面
- 遷移先：ドキュメント編集画面（ドキュメント選択時）、サブフォルダ（フォルダ選択時）、コレクション一覧画面（戻る）

**権限による表示制御**：コレクションの `read` 権限とFoldersコレクションの `read` 権限の両方が必要。フォルダ作成には `create` 権限、ドキュメント移動には `update` 権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | コレクション管理 | 主機能 | フォルダ構造によるコレクション表示 |
| 30 | Admin UI | 補助機能 | フォルダビューUIのレンダリング |

## 画面種別

一覧（フォルダ階層表示）

## URL/ルーティング

- ルート: `/{adminRoute}/collections/{collectionSlug}/{foldersSlug}`
- サブフォルダ: `/{adminRoute}/collections/{collectionSlug}/{foldersSlug}/{folderID}`

パラメータ:
- `{adminRoute}`: 管理画面のベースパス（デフォルト: `/admin`）
- `{collectionSlug}`: 対象コレクションのスラッグ
- `{foldersSlug}`: フォルダコレクションのスラッグ（設定による）
- `{folderID}`: 表示するフォルダのID（省略時はルートフォルダ）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|---------|------|------|
| collectionSlug | 入力 | string | Yes | 対象コレクションのスラッグ（URLパラメータ） |
| folderID | 入力 | string/number | No | 表示するフォルダID（URLパラメータ） |
| sort | 入力 | FolderSortKeys | No | ソートキー（クエリパラメータ） |
| viewPreference | 入力 | 'grid'/'list' | No | 表示形式（プリファレンス） |
| search | 入力 | string | No | 検索クエリ |
| subfolders | 出力 | array | - | サブフォルダの配列 |
| documents | 出力 | array | - | フォルダ内のドキュメント配列 |
| breadcrumbs | 出力 | array | - | パンくずリスト情報 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| フォルダ名 | string | フォルダの名前 |
| サムネイル | image | ドキュメントのサムネイル画像（Upload時） |
| ドキュメントタイトル | string | ドキュメントのタイトル |
| 更新日時 | datetime | 最終更新日時 |
| パンくずリスト | array | 現在の階層パス |
| アイテム数 | number | フォルダ内のアイテム数 |

## イベント仕様

### 1-フォルダ・ドキュメント一覧表示

画面表示時にフォルダ内のサブフォルダとドキュメントを取得して表示する。

**処理フロー**：
1. URLパラメータからcollectionSlugとfolderIDを取得
2. ユーザープリファレンス（ソート、表示形式）を取得
3. `getFolderResultsComponentAndData()` でフォルダデータを取得
4. パンくずリスト情報を構築
5. グリッドまたはリスト形式で表示

### 2-フォルダ選択（ナビゲーション）

フォルダをクリックしてサブフォルダに移動する。

**処理フロー**：
1. クリックされたフォルダのIDを取得
2. URLを `/{admin}/collections/{collectionSlug}/{foldersSlug}/{folderID}` に更新
3. 新しいフォルダ内容を取得して表示

### 3-ドキュメント選択

ドキュメントをクリックして編集画面に遷移する。

**処理フロー**：
1. クリックされたドキュメントのIDを取得
2. ドキュメント編集画面へリダイレクト

### 4-表示形式切り替え

グリッド表示とリスト表示を切り替える。

**処理フロー**：
1. 現在の表示形式を反転
2. プリファレンスを更新
3. 表示を再レンダリング

### 5-ソート変更

ソート順を変更する。

**処理フロー**：
1. 選択されたソートキーを取得
2. URLクエリパラメータを更新
3. プリファレンスを保存
4. ソート済みデータを再取得

### 6-フォルダ作成

新しいフォルダを作成する。

**処理フロー**：
1. 作成ダイアログを表示
2. フォルダ名を入力
3. `payload.create()` でフォルダを作成
4. 一覧を再取得

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| フォルダ一覧表示 | {foldersSlug}, {collectionSlug} | SELECT | フォルダとドキュメントを取得 |
| フォルダ作成 | {foldersSlug} | INSERT | 新規フォルダを作成 |
| ドキュメント移動 | {collectionSlug} | UPDATE | フォルダフィールドを更新 |
| フォルダ削除 | {foldersSlug} | DELETE | フォルダを削除 |

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

#### {foldersSlug}（フォルダコレクション）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | - | WHERE parent = {folderID} | サブフォルダ取得 |
| INSERT | name, parent | フォルダ名、親フォルダID | フォルダ作成 |
| DELETE | - | WHERE id = {folderID} | フォルダ削除 |

#### {collectionSlug}（対象コレクション）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | - | WHERE {folderFieldName} = {folderID} | フォルダ内ドキュメント取得 |
| UPDATE | {folderFieldName} | 新しいフォルダID | ドキュメント移動 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| folder.created | 成功 | フォルダが作成されました | フォルダ作成成功時 |
| folder.deleted | 成功 | フォルダが削除されました | フォルダ削除成功時 |
| folder.moved | 成功 | アイテムが移動されました | ドキュメント移動成功時 |
| folder.createError | エラー | フォルダの作成に失敗しました | フォルダ作成失敗時 |
| folder.notEmpty | 警告 | フォルダが空ではありません | 空でないフォルダ削除試行時 |
| folder.notFound | エラー | フォルダが見つかりません | 存在しないフォルダアクセス時 |

## 例外処理

| 例外状態 | 対応 |
|---------|------|
| フォルダ機能が無効（config.folders = false） | not-foundエラーを投げる |
| コレクションまたはフォルダのread権限がない | not-foundエラーを投げる |
| フォルダIDが無効 | ルートフォルダにリダイレクト |
| コレクションが非表示設定 | not-foundエラーを投げる |

## 備考

- フォルダ機能は `config.folders` で有効化される
- `folderFieldName` はドキュメントがフォルダに属するためのフィールド名を定義
- プリファレンスは `{collectionSlug}-collection-folder` キーで保存される
- 表示形式（グリッド/リスト）とソート設定はユーザーごとに保存される
- フォルダIDが存在しない場合はルートフォルダにリダイレクトされる

---

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

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

### 推奨読解順序

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

フォルダ表示画面で扱うデータ構造の理解が重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types | `packages/payload/src/admin/types.ts` | FolderListViewClientProps, FolderSortKeys型 |
| 1-2 | buildView.tsx | `packages/next/src/views/CollectionFolders/buildView.tsx` | BuildCollectionFolderViewStateArgs型（行19-27） |

**読解のコツ**: フォルダビューはコレクション一覧とは異なる専用のprops型を使用している。`browseByFolder: false` が設定されているのがCollectionFolderView固有の設定である。

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

フォルダ表示画面のエントリーポイントとなるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.tsx | `packages/next/src/views/CollectionFolders/index.tsx` | CollectionFolderViewコンポーネントの構造 |

**主要処理フロー**:
1. **行9**: CollectionFolderViewコンポーネント定義
2. **行10-11**: buildCollectionFolderViewを呼び出し、Viewを取得
3. **行14-20**: エラーハンドリング（NEXT_REDIRECT, not-found）

#### Step 3: ビュー構築ロジックを理解する

フォルダビューを構築するロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | buildView.tsx | `packages/next/src/views/CollectionFolders/buildView.tsx` | buildCollectionFolderView関数の実装 |

**主要処理フロー**:
- **行63-65**: config.foldersが無効な場合のエラー処理
- **行67-72**: コレクション・フォルダの権限チェック
- **行89-98**: upsertPreferencesでユーザー設定を取得・保存
- **行103-121**: getFolderResultsComponentAndDataでフォルダデータを取得
- **行125-135**: フォルダIDの検証とリダイレクト処理
- **行168-207**: Viewコンポーネントの組み立て

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

```
CollectionFolderView (CollectionFolders/index.tsx)
    │
    └─ buildCollectionFolderView (buildView.tsx)
           │
           ├─ 権限チェック
           │   ├─ permissions.collections[collectionSlug].read
           │   └─ permissions.collections[foldersSlug].read
           │
           ├─ upsertPreferences() - ソート・表示形式設定
           │
           ├─ getFolderResultsComponentAndData()
           │   ├─ browseByFolder: false
           │   ├─ collectionsToDisplay: [foldersSlug, collectionSlug]
           │   └─ folderID, sort
           │
           ├─ フォルダID検証・リダイレクト
           │
           └─ RenderServerComponent()
                  │
                  └─ DefaultCollectionFolderView
                         │
                         ├─ FolderResultsComponent
                         ├─ Breadcrumbs
                         └─ CreateFolder/Document buttons
```

### データフロー図

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

URLパラメータ ───▶ CollectionFolderView ───▶ フォルダ/ドキュメント表示
  - collectionSlug          │
  - folderID                ├─▶ buildCollectionFolderView()
  - sort                    │      │
                            │      ├─▶ upsertPreferences()
クエリパラメータ ───────────┤      │      └─▶ ソート・表示形式保存
  - viewPreference          │      │
                            │      ├─▶ getFolderResultsComponentAndData()
                            │      │      │
                            │      │      ├─▶ サブフォルダ取得
                            │      │      └─▶ フォルダ内ドキュメント取得
                            │      │
                            │      └─▶ breadcrumbs構築
                            │
                            └─▶ DefaultCollectionFolderView表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/next/src/views/CollectionFolders/index.tsx` | ソース | フォルダ表示画面のエントリーポイント |
| buildView.tsx | `packages/next/src/views/CollectionFolders/buildView.tsx` | ソース | ビュー構築ロジック |
| DefaultCollectionFolderView | `packages/ui/src/views/FolderView/Default.tsx` | ソース | クライアント側フォルダビューコンポーネント |
| getFolderResultsComponentAndData | `packages/ui/src/rsc/getFolderResultsComponentAndData.ts` | ソース | フォルダデータ取得ロジック |
| upsertPreferences | `packages/ui/src/rsc/upsertPreferences.ts` | ソース | プリファレンス管理 |
| HydrateAuthProvider | `packages/ui/src/providers/Auth/index.tsx` | ソース | 認証情報プロバイダー |
