# 画面設計書 42-ナビゲーション設定

## 概要

本ドキュメントは、Ghost管理画面の「ナビゲーション設定」画面の設計仕様を定義する。この画面はサイトのプライマリ（主要）ナビゲーションとセカンダリ（補助）ナビゲーションメニューの設定を行う機能を提供する。

### 本画面の処理概要

この画面では、サイトのヘッダーやフッターに表示されるナビゲーションメニューを管理する。メニュー項目の追加・編集・削除・並び替えが可能である。

**業務上の目的・背景**：Ghostサイトのナビゲーションはユーザーエクスペリエンスの中核要素である。訪問者がサイト内を容易に移動できるよう、適切なリンク構造を設定することが必要である。プライマリナビゲーション（通常ヘッダーに表示）とセカンダリナビゲーション（通常フッターに表示）を分けて管理することで、サイト設計の柔軟性を確保する。

**画面へのアクセス方法**：管理画面のサイドバーから「Settings」→「Site」セクション→「Navigation」カードの「Customize」ボタンをクリックしてアクセスする。URLは`/ghost/#/settings/navigation/edit`となる。

**主要な操作・処理内容**：
1. プライマリナビゲーション項目の一覧表示・編集
2. セカンダリナビゲーション項目の一覧表示・編集
3. 新規ナビゲーション項目の追加（ラベルとURL）
4. 既存項目のラベル・URLの編集
5. 項目の削除（ゴミ箱アイコン）
6. ドラッグ＆ドロップによる項目の並び替え
7. Primary/Secondaryタブの切り替え

**画面遷移**：設定画面（Site設定セクション）から遷移し、ナビゲーション編集モーダルが表示される。保存またはキャンセル後は設定画面に戻る。

**権限による表示制御**：Administrator以上のロールを持つユーザーのみがナビゲーション設定にアクセスできる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 35 | 一般設定 | 主機能 | サイトナビゲーションメニューの設定 |

## 画面種別

設定画面（モーダル型）

## URL/ルーティング

- メイン画面: `/ghost/#/settings` (navid: `navigation`)
- 編集モーダル: `/ghost/#/settings/navigation/edit`

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|---------|------|------|
| ラベル | 入力 | string | 必須 | メニュー項目の表示テキスト |
| URL | 入力 | string | 必須 | メニュー項目のリンク先（相対パスまたは絶対URL） |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| Primary Navigation Items | NavigationItem[] | プライマリナビゲーションの項目一覧 |
| Secondary Navigation Items | NavigationItem[] | セカンダリナビゲーションの項目一覧 |

## イベント仕様

### 1-Customizeボタン押下

「Customize」ボタンをクリックすると、`navigation/edit`ルートへ遷移し、ナビゲーション編集モーダルが表示される。

### 2-タブ切り替え

「Primary」「Secondary」タブを切り替えると、対応するナビゲーションの編集フォームが表示される。

### 3-項目追加

新規項目入力欄でラベルとURLを入力し、「+」ボタン（またはEnterキー）で追加：

1. 入力値のバリデーション実行
2. バリデーション成功時、`navigation`または`secondary_navigation`設定を更新
3. バリデーション失敗時、エラーメッセージを表示

### 4-項目編集

既存項目のラベルまたはURLを変更すると：

1. `updateItem`関数で対応する項目を更新
2. 設定の`dirty`フラグがtrueになる

### 5-項目削除

ゴミ箱アイコンをクリックすると：

1. `removeItem`関数で対応する項目を削除
2. 設定の`dirty`フラグがtrueになる

### 6-項目並び替え

項目をドラッグ＆ドロップすると：

1. `SortableList`コンポーネントが順序変更を処理
2. `moveItem`関数で新しい順序を設定に反映

### 7-保存

「Save」ボタンをクリックすると：

1. 全項目のバリデーション実行（`navigation.validate()`）
2. バリデーション成功時、`handleSave`で設定をAPIに送信
3. モーダルを閉じて設定画面に戻る

### 8-キャンセル

「Close」ボタンまたはモーダル外をクリックすると：

1. 変更がある場合は確認なしで閉じる（dirty状態は保持）
2. モーダルを閉じて設定画面に戻る

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ナビゲーション保存 | settings | UPDATE | navigation設定のJSON更新 |
| ナビゲーション保存 | settings | UPDATE | secondary_navigation設定のJSON更新 |

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

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | key='navigation' | JSON配列（[{label, url}, ...]） | プライマリナビゲーション |
| UPDATE | key='secondary_navigation' | JSON配列（[{label, url}, ...]） | セカンダリナビゲーション |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| エラー | You must specify a label | ラベルが空の場合 |
| エラー | You must specify a valid URL or relative path | URLが無効な場合 |
| 状態 | Saving... | 保存処理中 |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| バリデーションエラー | 該当項目の下にエラーメッセージを表示、保存を中断 |
| ネットワークエラー | エラートーストを表示 |

## 備考

- ナビゲーション項目はJSON形式で`settings`テーブルに保存される
- URLはサイトのベースURLに対する相対パス（例：`/about/`）または絶対URL（例：`https://example.com`）を指定可能
- URLはスキーム（`http://`, `https://`, `mailto:`など）で始まる場合、またはスラッシュ（`/`）やハッシュ（`#`）で始まる場合に有効
- ドラッグ＆ドロップによる並び替えは`@dnd-kit/sortable`ライブラリを使用
- 新規項目のデフォルトURLは`/`

---

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

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

### 推奨読解順序

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

まず、ナビゲーション項目のデータ型定義を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | use-navigation-editor.tsx | `apps/admin-x-settings/src/hooks/site/use-navigation-editor.tsx` | NavigationItem型、EditableItem型、NavigationEditor型の定義（4-23行目） |

**読解のコツ**: `NavigationItem`は基本的なデータ構造、`EditableItem`は編集用の拡張型（idとerrorsを追加）、`NavigationEditor`は編集操作のインターフェースを定義している。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | navigation.tsx | `apps/admin-x-settings/src/components/settings/site/navigation.tsx` | メインコンポーネントの構造（6-24行目） |
| 2-2 | navigation-modal.tsx | `apps/admin-x-settings/src/components/settings/site/navigation-modal.tsx` | モーダルコンポーネントの構造（10-84行目） |

**主要処理フロー**:
1. **navigation.tsx 8-10行目**: `openPreviewModal`でモーダルを表示
2. **navigation-modal.tsx 21-24行目**: 設定から現在のナビゲーション項目を取得
3. **navigation-modal.tsx 26-36行目**: Primary/Secondary両方の`useNavigationEditor`を初期化

#### Step 3: 編集ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | use-navigation-editor.tsx | `apps/admin-x-settings/src/hooks/site/use-navigation-editor.tsx` | 編集ロジックの実装（25-124行目） |

**主要処理フロー**:
- **38-52行目**: URLバリデーションの正規表現とロジック
- **54-57行目**: `updateItem` - 項目の更新
- **59-67行目**: `addItem` - 項目の追加（バリデーション付き）
- **73-75行目**: `moveItem` - ドラッグ＆ドロップによる並び替え
- **100-122行目**: `validate` - 全項目のバリデーション

#### Step 4: 編集フォームUIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | navigation-edit-form.tsx | `apps/admin-x-settings/src/components/settings/site/navigation/navigation-edit-form.tsx` | 編集フォーム全体のレイアウト |
| 4-2 | navigation-item-editor.tsx | `apps/admin-x-settings/src/components/settings/site/navigation/navigation-item-editor.tsx` | 個別項目の編集UI |

**主要処理フロー**:
- **navigation-edit-form.tsx 11-24行目**: `SortableList`による並び替え可能なリスト表示
- **navigation-item-editor.tsx 22-42行目**: ラベル入力フィールドとEnterキー処理
- **navigation-item-editor.tsx 44-70行目**: URL入力フィールドとバリデーション

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

```
Navigation (navigation.tsx)
    │
    └─ openPreviewModal()
           │
           └─ updateRoute('navigation/edit')
                  │
                  └─ NavigationModal (navigation-modal.tsx)
                         │
                         ├─ useSettingGroup()
                         │      └─ localSettings (navigation, secondary_navigation)
                         │
                         ├─ useNavigationEditor() [Primary]
                         │      ├─ items: EditableItem[]
                         │      ├─ updateItem()
                         │      ├─ addItem()
                         │      ├─ removeItem()
                         │      ├─ moveItem()
                         │      └─ validate()
                         │
                         ├─ useNavigationEditor() [Secondary]
                         │      └─ (同上)
                         │
                         ├─ TabView (Primary/Secondary)
                         │      └─ NavigationEditForm
                         │             └─ SortableList
                         │                    └─ NavigationItemEditor
                         │
                         └─ handleSave()
                                └─ PUT /settings/ (navigation, secondary_navigation)
```

### データフロー図

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

                    ┌─────────────────┐
Settings DB ────────┤  getSettingValues │
(JSON string)       │  JSON.parse()     │
                    └────────┬─────────┘
                             │
                    ┌────────▼────────┐
                    │useNavigationEditor│
ユーザー入力 ───────┤                   ├────────► 画面表示
(label, url)        │ - validate()      │         (NavigationItem[])
                    │ - updateItem()    │
                    │ - addItem()       │
                    │ - removeItem()    │
                    │ - moveItem()      │
                    └────────┬─────────┘
                             │
                    ┌────────▼────────┐
handleSave() ───────┤   updateSetting   │
                    │  JSON.stringify() │
                    └────────┬─────────┘
                             │
                    ┌────────▼────────┐
                    │   PUT /settings/  │───────► Settings DB
                    └─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| navigation.tsx | `apps/admin-x-settings/src/components/settings/site/navigation.tsx` | ソース | メイン設定カードコンポーネント |
| navigation-modal.tsx | `apps/admin-x-settings/src/components/settings/site/navigation-modal.tsx` | ソース | ナビゲーション編集モーダル |
| navigation-edit-form.tsx | `apps/admin-x-settings/src/components/settings/site/navigation/navigation-edit-form.tsx` | ソース | 編集フォームコンテナ |
| navigation-item-editor.tsx | `apps/admin-x-settings/src/components/settings/site/navigation/navigation-item-editor.tsx` | ソース | 個別項目の編集UI |
| use-navigation-editor.tsx | `apps/admin-x-settings/src/hooks/site/use-navigation-editor.tsx` | ソース | ナビゲーション編集ロジックフック |
| settings.ts | `apps/admin-x-framework/src/api/settings.ts` | ソース | 設定API定義 |
| use-setting-group.ts | `apps/admin-x-settings/src/hooks/use-setting-group.ts` | ソース | 設定グループ管理フック |
