# 画面設計書 190-ロケール追加画面

## 概要

本ドキュメントは、Medusa Admin Dashboard におけるロケール追加画面の設計仕様を定義する。

### 本画面の処理概要

ロケール追加画面は、ストアにサポートするロケール（言語）を追加するための画面である。利用可能なすべてのロケールの一覧からチェックボックスで選択し、ストアに追加できる。

**業務上の目的・背景**：
多言語対応において、どの言語をサポートするかを設定することは、翻訳作業の範囲を決定する重要な設定である。本画面では、システムで利用可能なすべてのロケールから、ストアでサポートする言語を選択できる。既に追加されているロケールは選択不可として表示される。

**画面へのアクセス方法**：
翻訳一覧画面 > ロケール未設定時のアラート内「設定」ボタンをクリックすることでアクセスする。

**主要な操作・処理内容**：
1. ロケール一覧の表示 - DataTableでページネーション表示
2. ロケールの検索 - 名前やコードで検索
3. ロケールの選択 - チェックボックスで複数選択
4. ソート - 名前順/コード順でソート
5. ロケールの追加 - 選択したロケールをストアに追加

**画面遷移**：
- 遷移元：翻訳一覧画面
- 遷移先：なし（モーダルを閉じて翻訳一覧画面に戻る）

**権限による表示制御**：
管理者権限を持つユーザーのみがアクセス可能。Feature Flagで翻訳機能が有効な場合のみアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 85 | 翻訳CRUD | 主機能 | ストアのロケール設定 |

## 画面種別

フルスクリーンモーダル（RouteFocusModal）

## URL/ルーティング

`/settings/translations/add-locales`

## 入出力項目

### 入力項目

| 項目名 | 必須 | 型 | 入力形式 | 最大長 | 制約・補足 |
|--------|------|-----|---------|--------|-----------|
| locales | Yes | string[] | チェックボックス | - | 選択されたロケールコードの配列 |

### バリデーション仕様

| 項目 | ルール | エラーメッセージ |
|------|--------|----------------|
| locales | 1件以上選択必須 | - |

## 表示項目

### ヘッダー

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| エラーヒント | Hint | バリデーションエラー時に表示 |

### データテーブル

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| チェックボックス | チェックボックス | ロケール選択（既存は無効） |
| ロケール名 | テキスト | 言語名 |
| ロケールコード | テキスト | 言語コード（例：ja, en-US） |

### フッター

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| キャンセルボタン | ボタン | モーダルを閉じる |
| 保存ボタン | ボタン | 選択したロケールを追加 |

## イベント仕様

### 1-画面初期表示

1. Feature Flagで翻訳機能が有効か確認（無効な場合は戻る）
2. `useStore` でストア情報を取得
3. `useLocales` で利用可能なすべてのロケールを取得
4. 既存のサポートロケールを特定し、選択不可として設定

### 2-検索

1. 検索ボックスに入力
2. `useLocalesTableQuery` でクエリパラメータを更新
3. `useLocales` が再取得を実行
4. テーブル表示が更新される

### 3-ロケール選択

1. チェックボックスをクリック
2. `rowSelection` 状態を更新
3. フォームの `locales` フィールドを更新

### 4-ソート

1. ソートドロップダウンでフィールドを選択
2. クエリパラメータが更新される
3. テーブル表示がソートされる

### 5-ページネーション

1. ページネーションコントロールを操作
2. クエリパラメータが更新される
3. 次のページのデータが取得される

### 6-保存ボタン押下

1. フォームの送信処理が実行される
2. 新規選択したロケールと既存ロケールを結合
3. `useUpdateStore` でストアのサポートロケールを更新
4. 成功時：トースト表示、モーダルを閉じる
5. 失敗時：エラートースト表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面初期表示 | store | SELECT | ストア情報の取得 |
| 画面初期表示 | locale | SELECT | ロケール一覧の取得 |
| 保存ボタン押下 | store | UPDATE | サポートロケールの更新 |

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

#### store

| 列名 | UPDATE | 備考 |
|------|--------|------|
| supported_locales | 更新可 | ロケールコードの配列 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| store.toast.localesUpdated | 成功 | ロケールが更新されました | 保存成功時 |
| store.localeAlreadyAdded | ツールチップ | 既に追加されています | 既存ロケールのチェックボックスホバー時 |
| - | エラー | APIエラーメッセージ | 保存失敗時 |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|----------|
| 翻訳機能が無効 | navigate(-1)で戻る |
| API通信エラー | エラーをスローし、エラーバウンダリでキャッチ |
| データ取得中 | テーブルにローディング表示 |
| 保存中 | 保存ボタンにローディング表示 |

## 備考

- RouteFocusModalレイアウトを使用
- _DataTableコンポーネントで一覧表示
- ページサイズは50件固定
- 検索はオートフォーカス
- 既存のサポートロケールは選択不可（チェックボックス無効化）
- 既存ロケールにはツールチップで「既に追加されています」と表示
- AddLocalesFormはストア設定画面（store-add-locales）と共通

---

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

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

### 推奨読解順序

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

画面のメインコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | add-locales.tsx | `packages/admin/dashboard/src/routes/translations/add-locales/add-locales.tsx` | 全体構造 |

**主要処理フロー**:
1. **8行目**: useFeatureFlagで翻訳機能の有効確認
2. **11-14行目**: 無効時はnavigate(-1)で戻る
3. **16行目**: useStoreでストア情報を取得
4. **24-27行目**: RouteFocusModal内にAddLocalesFormを表示

**読解のコツ**: AddLocalesFormはストア設定画面と共通のコンポーネントを使用。

#### Step 2: フォームコンポーネントを理解する

メインのフォームコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | add-locales-form.tsx | `packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx` | フォーム処理全体 |

**主要処理フロー**:
- **27-29行目**: AddLocalesSchemaでバリデーション定義
- **31-32行目**: PAGE_SIZE = 50, PREFIX = "al"
- **38-41行目**: useLocalesTableQueryでクエリ管理
- **43-51行目**: useLocalesでロケール一覧取得
- **53-58行目**: React Hook Formのセットアップ
- **60行目**: rowSelectionで選択状態管理
- **64-74行目**: updaterで選択状態をフォームに同期
- **76-77行目**: preSelectedRowsで既存ロケールを特定
- **81-94行目**: useDataTableでテーブル設定（enableRowSelectionで既存は無効）
- **96行目**: useUpdateStoreでストア更新
- **98-119行目**: handleSubmitで保存処理

#### Step 3: カラム定義を理解する

テーブルカラムの定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | add-locales-form.tsx | 同上 | 177-231行目: useColumnsでカラム定義 |

**主要処理フロー**:
- **185-226行目**: selectカラムでチェックボックス表示
- **202-203行目**: isPreSelectedで既存ロケールを判定
- **216-221行目**: 既存ロケールにはツールチップを表示

#### Step 4: API連携を理解する

APIフックの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | store.tsx | `packages/admin/dashboard/src/hooks/api/store.tsx` | ストア関連のAPIフック |

**主要処理フロー**:
- useStore: ストア情報の取得
- useUpdateStore: ストアの更新（supported_localesを含む）

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

```
TranslationsAddLocales (add-locales.tsx)
    │
    ├─ useFeatureFlag("translation") - 機能有効確認
    │
    ├─ useStore() - ストア情報取得
    │      └─ sdk.admin.store.retrieve()
    │
    └─ AddLocalesForm (store-add-locales共通)
           │
           ├─ useLocalesTableQuery() - クエリ管理
           │
           ├─ useLocales() - ロケール一覧取得
           │      └─ sdk.admin.locale.list()
           │
           ├─ React Hook Form
           │      └─ AddLocalesSchema
           │
           ├─ useDataTable() - テーブル状態管理
           │
           ├─ _DataTable - テーブル表示
           │
           └─ handleSubmit
                  └─ useUpdateStore()
                         └─ sdk.admin.store.update()
```

### データフロー図

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

ストア情報 ───▶ preSelectedRows抽出 ───▶ 選択不可ロケール特定

ロケール一覧 ───▶ useDataTable ───▶ _DataTable表示
    API             (enableRowSelection)

チェックボックス ───▶ updater ───▶ フォーム状態更新
    操作

保存ボタン ───▶ handleSubmit ───▶ useUpdateStore
                (既存 + 新規結合)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| add-locales.tsx | `packages/admin/dashboard/src/routes/translations/add-locales/add-locales.tsx` | ソース | ロケール追加画面のエントリーポイント |
| add-locales-form.tsx | `packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx` | ソース | ロケール追加フォーム（共通） |
| use-locales-table-query.ts | `packages/admin/dashboard/src/routes/store/common/hooks/use-locales-table-query.ts` | ソース | クエリ管理フック |
| use-locales-table-columns.ts | `packages/admin/dashboard/src/routes/store/common/hooks/use-locales-table-columns.ts` | ソース | カラム定義フック |
| store.tsx | `packages/admin/dashboard/src/hooks/api/store.tsx` | ソース | ストアAPIフック |
| locales.tsx | `packages/admin/dashboard/src/hooks/api/locales.tsx` | ソース | ロケールAPIフック |
| RouteFocusModal | `packages/admin/dashboard/src/components/modals/route-focus-modal` | ソース | フルスクリーンモーダル |
| _DataTable | `packages/admin/dashboard/src/components/table/data-table` | ソース | データテーブルコンポーネント |
