# 画面設計書 2-ドロワーメニュー

## 概要

本ドキュメントは、InvenTree Flutterアプリケーションのドロワーメニュー（InvenTreeDrawer）の画面設計を定義するものである。

### 本画面の処理概要

ドロワーメニューはアプリケーションのサイドナビゲーションメニューであり、画面左端からスワイプまたはメニューボタンタップで表示される。各主要機能への迅速なアクセスを提供する。

**業務上の目的・背景**：在庫管理業務において、どの画面からでも主要機能（部品、在庫、購入注文、販売注文、通知、設定）へ素早くアクセスできるようにすることで、作業効率を向上させる。また、テーマ切り替え機能により、ユーザーの作業環境（明るい/暗い環境）に応じた表示を可能にする。

**画面へのアクセス方法**：任意の画面で左端からスワイプ、またはBottomAppBarのメニューアイコンをタップ。

**主要な操作・処理内容**：
1. ホーム画面への遷移（InvenTreeロゴタップでナビゲーションスタックをクリア）
2. 部品カテゴリ画面への遷移（「部品」メニュー項目タップ）
3. 在庫ロケーション画面への遷移（「在庫」メニュー項目タップ）
4. 購入注文一覧への遷移（「購入注文」メニュー項目タップ）
5. 販売注文一覧への遷移（「販売注文」メニュー項目タップ）
6. 通知画面への遷移（「通知」メニュー項目タップ）
7. 設定画面への遷移（「設定」メニュー項目タップ）
8. テーマ切り替えダイアログの表示と適用（「カラースキーム」タップ）

**画面遷移**：
- 遷移元：全画面のドロワー機能
- 遷移先：ホーム画面、部品カテゴリ画面、在庫ロケーション画面、購入注文一覧画面、販売注文一覧画面、通知画面、設定画面

**権限による表示制御**：ユーザーの権限（canView）に応じて各メニュー項目の表示/非表示が制御される。権限がないメニューは表示されない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | パーツ一覧表示 | 遷移先機能 | パーツメニュー押下時にパーツカテゴリ画面へ遷移 |
| 14 | 在庫アイテム一覧表示 | 遷移先機能 | 在庫メニュー押下時に在庫ロケーション画面へ遷移 |
| 23 | 発注一覧表示 | 遷移先機能 | 発注メニュー押下時に発注一覧画面へ遷移 |
| 32 | 受注一覧表示 | 遷移先機能 | 受注メニュー押下時に受注一覧画面へ遷移 |
| 51 | 通知一覧表示 | 遷移先機能 | 通知メニュー押下時に通知画面へ遷移 |
| 57 | アプリ設定 | 遷移先機能 | 設定メニュー押下時に設定画面へ遷移 |
| 64 | テーマ切替 | 補助機能 | テーマ選択ダイアログの表示とテーマ変更処理 |

## 画面種別

サイドナビゲーションメニュー（Drawer）

## URL/ルーティング

- Flutter Widget：`InvenTreeDrawer`（StatelessWidget）
- 表示方法：`Scaffold.drawer`プロパティに設定

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| context | 入力 | BuildContext | 必須 | コンストラクタに渡される親画面のコンテキスト |

## 表示項目

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| アプリロゴ・タイトル | Widget | InvenTreeロゴとアプリタイトル | assets/image/logo_transparent.png, L10().appTitle |
| 部品メニュー | Widget | 部品カテゴリへのリンク | InvenTreePart().canView |
| 在庫メニュー | Widget | 在庫ロケーションへのリンク | InvenTreeStockLocation().canView |
| 購入注文メニュー | Widget | 購入注文一覧へのリンク | InvenTreePurchaseOrder().canView |
| 販売注文メニュー | Widget | 販売注文一覧へのリンク | InvenTreeSalesOrder().canView |
| 通知メニュー | Widget | 通知画面へのリンク（未読件数表示付き） | InvenTreeAPI().notification_counter |
| カラースキームメニュー | Widget | テーマ選択ダイアログ表示 | AdaptiveTheme.of(context).mode |
| 設定メニュー | Widget | 設定画面へのリンク | 常時表示 |

## イベント仕様

### 1-ホームタイル押下

InvenTreeロゴ・タイトルタイルをタップした際にホーム画面へ遷移する。

**処理フロー**：
1. ユーザーがロゴタイルをタップ
2. `_home()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `Navigator.of(context).canPop()`がtrueの間、`pop()`を繰り返しナビゲーションスタックをクリア
5. ホーム画面に戻る

### 2-部品メニュー押下

部品メニューをタップした際に部品カテゴリ画面へ遷移する。

**処理フロー**：
1. ユーザーが部品メニューをタップ
2. `_parts()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `_checkConnection()`で接続確認
5. 接続済みの場合、`Navigator.push()`で`CategoryDisplayWidget(null)`へ遷移

### 3-在庫メニュー押下

在庫メニューをタップした際に在庫ロケーション画面へ遷移する。

**処理フロー**：
1. ユーザーが在庫メニューをタップ
2. `_stock()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `_checkConnection()`で接続確認
5. 接続済みの場合、`Navigator.push()`で`LocationDisplayWidget(null)`へ遷移

### 4-購入注文メニュー押下

購入注文メニューをタップした際に購入注文一覧画面へ遷移する。

**処理フロー**：
1. ユーザーが購入注文メニューをタップ
2. `_purchaseOrders()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `_checkConnection()`で接続確認
5. 接続済みの場合、`Navigator.push()`で`PurchaseOrderListWidget(filters: {})`へ遷移

### 5-販売注文メニュー押下

販売注文メニューをタップした際に販売注文一覧画面へ遷移する。

**処理フロー**：
1. ユーザーが販売注文メニューをタップ
2. `_salesOrders()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `_checkConnection()`で接続確認
5. 接続済みの場合、`Navigator.push()`で`SalesOrderListWidget(filters: {})`へ遷移

### 6-通知メニュー押下

通知メニューをタップした際に通知画面へ遷移する。

**処理フロー**：
1. ユーザーが通知メニューをタップ
2. `_notifications()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `_checkConnection()`で接続確認
5. 接続済みの場合、`Navigator.push()`で`NotificationWidget()`へ遷移

### 7-カラースキームメニュー押下

カラースキームメニューをタップした際にテーマ選択ダイアログを表示する。

**処理フロー**：
1. ユーザーがカラースキームメニューをタップ
2. `showDialog()`で`ThemeSelectionDialog`を表示
3. ユーザーがテーマ（System/Light/Dark）を選択
4. `AdaptiveTheme.of(context).setThemeMode()`でテーマを適用
5. ダイアログを閉じ、ドロワーを閉じる

### 8-設定メニュー押下

設定メニューをタップした際に設定画面へ遷移する。

**処理フロー**：
1. ユーザーが設定メニューをタップ
2. `_settings()`メソッドが呼び出される
3. `_closeDrawer()`でドロワーを閉じる
4. `Navigator.push()`で`InvenTreeSettingsWidget()`へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| テーマ変更 | settings（ローカル） | UPDATE | AdaptiveThemeによるテーマ設定保存 |

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

#### settings（ローカルDB - AdaptiveTheme管理）

| 操作 | 項目 | 更新値 | 備考 |
|-----|------|-------|------|
| UPDATE | themeMode | AdaptiveThemeMode値 | System/Light/Darkのいずれか |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| MSG-001 | 表示 | L10().appTitle | ホームタイルのタイトル |
| MSG-002 | 表示 | L10().parts | 部品メニューのタイトル |
| MSG-003 | 表示 | L10().stock | 在庫メニューのタイトル |
| MSG-004 | 表示 | L10().purchaseOrders | 購入注文メニューのタイトル |
| MSG-005 | 表示 | L10().salesOrders | 販売注文メニューのタイトル |
| MSG-006 | 表示 | L10().notifications | 通知メニューのタイトル |
| MSG-007 | 表示 | L10().colorScheme | カラースキームメニューのタイトル |
| MSG-008 | 表示 | L10().colorSchemeDetail | カラースキームメニューのサブタイトル |
| MSG-009 | 表示 | L10().settings | 設定メニューのタイトル |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| サーバー未接続 | _checkConnection()がfalseを返す | ナビゲーション処理をスキップ（SnackBarで通知） |
| 権限なし | canViewがfalse | 該当メニュー項目を非表示 |

## 備考

- ドロワーメニューはStatelessWidgetとして実装されている
- 通知メニューには未読通知件数がtrailingに表示される
- カラースキームメニューには現在のテーマモードを示すアイコンがtrailingに表示される
- ThemeSelectionDialogはドロワーメニュー内に定義された別クラスである

---

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

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

### 推奨読解順序

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

まず、ドロワーメニューで使用されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | api.dart | `lib/api.dart` | InvenTreeAPIクラスのnotification_counter、checkConnection()を理解する |
| 1-2 | adaptive_theme | 外部パッケージ | AdaptiveThemeModeの種類（system, light, dark）を理解する |

**読解のコツ**: adaptive_themeパッケージはFlutterのテーマ管理を簡易化するもので、AdaptiveTheme.of(context)でテーマ状態にアクセスできる。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drawer.dart | `lib/widget/drawer.dart` | InvenTreeDrawerクラスとThemeSelectionDialogクラスの構造を理解する |

**主要処理フロー**:
1. **行97-100**: InvenTreeDrawerクラスのコンストラクタでcontextを受け取る
2. **行102-105**: `_closeDrawer()`でNavigator.pop()を呼びドロワーを閉じる
3. **行107-109**: `_checkConnection()`でInvenTreeAPI().checkConnection()を呼び出す
4. **行115-121**: `_home()`でナビゲーションスタックをクリアしてホームに戻る
5. **行209-316**: `drawerTiles()`でメニュー項目リストを構築
6. **行318-321**: `build()`でDrawer Widgetを返す

#### Step 3: テーマ切り替えダイアログを理解する

テーマ選択機能を担当するダイアログを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | drawer.dart | `lib/widget/drawer.dart` | ThemeSelectionDialogクラス（行23-95）の構造を理解する |

**主要処理フロー**:
- **行31**: `AdaptiveTheme.of(context).mode`で現在のテーマモードを取得
- **行38-82**: RadioListTileで3つの選択肢（System, Light, Dark）を表示
- **行49, 64, 79**: `AdaptiveTheme.of(context).setThemeMode()`でテーマを変更

#### Step 4: 権限チェックを理解する

メニュー表示の権限制御を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inventree/part.dart | `lib/inventree/part.dart` | InvenTreePart().canViewの実装 |
| 4-2 | inventree/stock.dart | `lib/inventree/stock.dart` | InvenTreeStockLocation().canViewの実装 |
| 4-3 | inventree/purchase_order.dart | `lib/inventree/purchase_order.dart` | InvenTreePurchaseOrder().canViewの実装 |
| 4-4 | inventree/sales_order.dart | `lib/inventree/sales_order.dart` | InvenTreeSalesOrder().canViewの実装 |

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

```
InvenTreeDrawer (drawer.dart)
    |
    +-- build()
            |
            +-- drawerTiles()
                    |
                    +-- ListTile (ホーム)
                    |       +-- _home()
                    |               +-- _closeDrawer()
                    |               +-- Navigator.pop() x N
                    |
                    +-- ListTile (部品) [if canView]
                    |       +-- _parts()
                    |               +-- _closeDrawer()
                    |               +-- _checkConnection()
                    |               +-- Navigator.push(CategoryDisplayWidget)
                    |
                    +-- ListTile (在庫) [if canView]
                    |       +-- _stock()
                    |
                    +-- ListTile (購入注文) [if canView]
                    |       +-- _purchaseOrders()
                    |
                    +-- ListTile (販売注文) [if canView]
                    |       +-- _salesOrders()
                    |
                    +-- ListTile (通知)
                    |       +-- _notifications()
                    |
                    +-- ListTile (カラースキーム)
                    |       +-- showDialog(ThemeSelectionDialog)
                    |
                    +-- ListTile (設定)
                            +-- _settings()

ThemeSelectionDialog (drawer.dart)
    |
    +-- build()
            |
            +-- RadioListTile (System)
            |       +-- AdaptiveTheme.of(context).setThemeMode(system)
            |
            +-- RadioListTile (Light)
            |       +-- AdaptiveTheme.of(context).setThemeMode(light)
            |
            +-- RadioListTile (Dark)
                    +-- AdaptiveTheme.of(context).setThemeMode(dark)
```

### データフロー図

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

BuildContext           -->  InvenTreeDrawer()               -->  Drawer Widget
                                |
                                v
InvenTreeAPI           -->  notification_counter            -->  通知件数表示
                                |
                                v
canView (各Model)      -->  drawerTiles()                   -->  メニュー項目リスト
                                |
                                v
AdaptiveTheme          -->  _getThemeModeIcon()             -->  テーマアイコン
                                |
                                v
[メニュー選択]          -->  Navigator.push()               -->  画面遷移
                                |
                                v
[テーマ選択]            -->  AdaptiveTheme.setThemeMode()   -->  テーマ変更
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drawer.dart | `lib/widget/drawer.dart` | ソース | ドロワーメニューのメインWidget |
| api.dart | `lib/api.dart` | ソース | API通信・接続管理・通知カウンター |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリカラー定義（COLOR_ACTION） |
| l10.dart | `lib/l10.dart` | ソース | 多言語対応 |
| settings.dart | `lib/settings/settings.dart` | ソース | 設定画面（遷移先） |
| notifications.dart | `lib/widget/notifications.dart` | ソース | 通知画面（遷移先） |
| category_display.dart | `lib/widget/part/category_display.dart` | ソース | 部品カテゴリ画面（遷移先） |
| location_display.dart | `lib/widget/stock/location_display.dart` | ソース | 在庫ロケーション画面（遷移先） |
| purchase_order_list.dart | `lib/widget/order/purchase_order_list.dart` | ソース | 購入注文一覧画面（遷移先） |
| sales_order_list.dart | `lib/widget/order/sales_order_list.dart` | ソース | 販売注文一覧画面（遷移先） |
| logo_transparent.png | `assets/image/logo_transparent.png` | アセット | アプリロゴ画像 |
