# 画面設計書 9-ダッシュボードホーム画面

## 概要

本ドキュメントは、Chatwootアプリケーションのダッシュボードホーム画面に関する設計書です。会話一覧と詳細を表示するメイン画面について記述しています。

### 本画面の処理概要

ダッシュボードホーム画面は、Chatwootの中核となるメイン画面であり、全チャネルからの会話一覧と選択した会話の詳細を表示します。エージェントはこの画面を通じて顧客とのコミュニケーションを管理します。

**業務上の目的・背景**：カスタマーサポート業務において、エージェントは複数のチャネル（メール、チャット、SNS等）からの問い合わせを効率的に処理する必要があります。本画面は、すべての会話を一元管理し、迅速な対応を可能にするワークスペースとして機能します。会話のフィルタリング、ステータス管理、エージェント割り当て、ラベル付けなど、日常業務に必要なすべての機能を提供します。

**画面へのアクセス方法**：ログイン後、自動的にこの画面にリダイレクトされます。URL直接アクセスも可能です（`/app/accounts/:accountId/dashboard`）。

**主要な操作・処理内容**：
1. 会話一覧の表示とスクロールによる追加読み込み
2. 担当者タブ（自分、未割当、全員）による会話のフィルタリング
3. ステータス（オープン、解決済み、保留中）によるフィルタリング
4. 会話の選択と詳細表示
5. メッセージの送受信
6. 会話へのラベル付与、エージェント割り当て
7. 会話の一括操作（バルクアクション）
8. 高度なフィルタリングとカスタムビューの作成

**画面遷移**：
- 遷移元：ログイン画面（認証成功後）、他のダッシュボード画面
- 遷移先：インボックス別会話一覧、ラベル別会話一覧、チーム別会話一覧、会話詳細画面、各種設定画面

**権限による表示制御**：
- administrator、agent、conversation_manage、conversation_unassigned_manage、conversation_participating_manage権限を持つユーザーがアクセス可能
- 担当者タブの表示は権限により制御される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | 会話CRUD | 主機能 | 全会話の一覧表示と選択 |
| 26 | 会話検索・フィルタリング | 補助機能 | 会話のフィルタリングと検索 |
| 43 | メッセージ送受信 | API連携 | 選択した会話のメッセージ表示・送信 |
| 29 | 割り当て管理 | 補助機能 | 会話のエージェント割り当て変更 |
| 30 | ラベル管理 | 補助機能 | 会話へのラベル付与 |

## 画面種別

一覧・詳細（メインダッシュボード）

## URL/ルーティング

| パス | ルート名 | 説明 |
|------|----------|------|
| `/app/accounts/:accountId/dashboard` | `home` | ダッシュボードホーム画面 |

### ルートパラメータ

| パラメータ | 型 | 説明 |
|-----------|-----|------|
| `accountId` | String | アカウントID |

### ルートメタ情報

| メタキー | 値 | 説明 |
|---------|-----|------|
| `permissions` | `['administrator', 'agent', 'conversation_manage', 'conversation_unassigned_manage', 'conversation_participating_manage']` | アクセス権限 |

## 入出力項目

### 入力項目

本画面では直接的な入力フォームはありませんが、以下の操作で入力を受け付けます。

| 項目名 | 説明 |
|--------|------|
| 担当者タブ選択 | 自分/未割当/全員の切り替え |
| ステータスフィルター | オープン/解決済み/保留中/全てのフィルタリング |
| ソートオプション | 最終活動日時/作成日時でのソート |
| 高度なフィルター | 複数条件によるフィルタリング |

### 出力項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| 会話一覧 | フィルタ条件に合致する会話リスト | 常時 |
| 会話詳細 | 選択した会話のメッセージと情報 | 会話選択時 |
| 会話統計 | 各タブの会話件数 | 常時 |

## 表示項目

| 項目名 | 説明 | 表示条件 |
|--------|------|----------|
| ChatListHeader | 画面タイトルとフィルターオプション | 常時 |
| ChatTypeTabs | 担当者タブ（自分/未割当/全員） | フィルター未適用時 |
| ConversationItem | 会話アイテム（バーチャルスクロール） | 会話存在時 |
| ConversationBox | 会話詳細ボックス | レイアウト設定に応じて |
| ConversationSidebar | 連絡先情報サイドバー | サイドバー開時 |
| ConversationBulkActions | 一括操作パネル | 会話選択時 |
| LoadingSpinner | 読み込み中スピナー | ローディング時 |
| EmptyMessage | 会話なしメッセージ | 会話が存在しない時 |
| EndOfListMessage | リスト終端メッセージ | リスト終端到達時 |

## イベント仕様

### 1-会話一覧読み込み

**トリガー**: 画面マウント時、フィルター変更時、スクロール時

**処理フロー**:
1. `fetchConversations`でAPI呼び出し
2. `GET /api/v1/accounts/:accountId/conversations` にフィルター条件を送信
3. 取得した会話をVuexストアに保存
4. バーチャルスクロールで表示
5. スクロール終端で`loadMoreConversations`を呼び出し

**データフロー**:
```
[画面マウント/フィルター変更]
    │
    ▼
[conversationFilters生成]
    │
    ▼
[fetchAllConversations dispatch]
    │
    ▼
[API呼び出し: GET /conversations]
    │
    ▼
[Vuexストアに保存]
    │
    ▼
[バーチャルスクロールで表示]
```

### 2-担当者タブ切り替え

**トリガー**: 担当者タブのクリック

**処理フロー**:
1. `updateAssigneeTab`でアクティブタブを更新
2. バルクアクションをリセット
3. 検索入力をクリア
4. ページ未取得の場合は会話を再取得

### 3-会話選択

**トリガー**: 会話アイテムのクリック

**処理フロー**:
1. ルーターで会話詳細URLに遷移
2. `setActiveChat` dispatchで選択状態を設定
3. 会話詳細をConversationBoxに表示
4. メッセージIDが指定されている場合はスクロール

### 4-バルクアクション

**トリガー**: 会話のチェックボックス選択

**処理フロー**:
1. `selectConversation`で選択リストに追加
2. ConversationBulkActionsパネルを表示
3. エージェント割り当て、ラベル付与、ステータス変更が可能

### 5-高度なフィルター適用

**トリガー**: フィルターモーダルでの適用

**処理フロー**:
1. `onApplyFilter`でフィルター条件を生成
2. `fetchFilteredConversations`でフィルタ済み会話を取得
3. 結果を表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 会話一覧取得 | conversations | SELECT | フィルター条件に合致する会話を取得 |
| 会話ステータス変更 | conversations | UPDATE | status, resolved_at等の更新 |
| エージェント割り当て | conversations | UPDATE | assignee_id, assignee_last_seen_at等の更新 |
| ラベル付与 | conversations_labels | INSERT | 会話とラベルの関連付け |
| ラベル削除 | conversations_labels | DELETE | 会話とラベルの関連付け解除 |
| チーム割り当て | conversations | UPDATE | team_id の更新 |
| 会話削除 | conversations | DELETE | 会話レコードの削除 |

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

#### conversations

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status | 'open'/'resolved'/'snoozed'/'pending' | ステータス変更時 |
| UPDATE | assignee_id | エージェントID | エージェント割り当て時 |
| UPDATE | team_id | チームID | チーム割り当て時 |
| UPDATE | priority | 'low'/'medium'/'high'/'urgent' | 優先度変更時 |
| UPDATE | snoozed_until | スヌーズ終了日時 | スヌーズ設定時 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| CHAT_LIST.LIST.404 | 情報 | 会話が見つかりません | 会話が存在しない時 |
| CHAT_LIST.EOF | 情報 | これ以上の会話はありません | リスト終端到達時 |
| CONVERSATION.CHANGE_STATUS | 成功 | ステータスを変更しました | ステータス変更成功時 |
| CONVERSATION.SUCCESS_DELETE_CONVERSATION | 成功 | 会話を削除しました | 会話削除成功時 |
| CONVERSATION.FAIL_DELETE_CONVERSATION | エラー | 会話の削除に失敗しました | 会話削除失敗時 |

## 例外処理

| 例外条件 | 状態・動作 |
|---------|----------|
| 会話取得エラー | エラーメッセージを表示 |
| ステータス変更エラー | エラーメッセージを表示 |
| ネットワークエラー | 再試行を促すメッセージを表示 |
| 権限エラー | アクセス拒否メッセージを表示 |

## 備考

- バーチャルスクロール（vue-virtual-scroller）により大量の会話を効率的に表示
- レイアウトはcondensed（凝縮）とexpanded（拡大）の2種類から選択可能
- 会話の必須属性が設定されている場合、解決時に属性入力モーダルを表示
- WebSocketによるリアルタイム更新に対応
- UI設定（フィルター、ソート、レイアウト）はユーザー設定として保存される

---

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

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

### 推奨読解順序

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

会話データの構造とVuexストア管理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | conversations/index.js | `app/javascript/dashboard/store/modules/conversations/index.js` | 会話Vuexモジュールの構造 |
| 1-2 | conversations/getters.js | `app/javascript/dashboard/store/modules/conversations/getters.js` | 会話一覧取得のgetter |

**読解のコツ**: Vuexストアのstate、getters、mutations、actionsの役割を理解してください。

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

処理の起点となるVueコンポーネントを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConversationView.vue | `app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue` | メイン画面コンポーネント |
| 2-2 | conversation.routes.js | `app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` | ルーティング定義 |

**主要処理フロー**:
1. **行106-113**: `created`ライフサイクルフックで初期化
2. **行116-124**: `mounted`でエージェント取得とデータ初期化
3. **行130-133**: `initialize`メソッドでインボックス設定とアクティブ会話設定
4. **行163-186**: `setActiveChat`メソッドで会話選択処理

#### Step 3: 会話一覧コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | 会話一覧コンポーネント |
| 3-2 | ConversationItem.vue | `app/javascript/dashboard/components/ConversationItem.vue` | 会話アイテムコンポーネント |

**主要処理フロー**:
- **ChatList.vue 行573-576**: `fetchConversations`メソッドで会話取得
- **ChatList.vue 行594-607**: `loadMoreConversations`メソッドで追加読み込み
- **ChatList.vue 行620-629**: `updateAssigneeTab`メソッドでタブ切り替え

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

```
ConversationView.vue
    │
    ├─ ChatList.vue
    │      │
    │      ├─ ChatListHeader.vue
    │      │      └─ フィルターオプション
    │      │
    │      ├─ ChatTypeTabs.vue
    │      │      └─ 担当者タブ
    │      │
    │      ├─ DynamicScroller (vue-virtual-scroller)
    │      │      │
    │      │      └─ ConversationItem.vue
    │      │             └─ 会話アイテム表示
    │      │
    │      └─ ConversationBulkActions.vue
    │             └─ 一括操作
    │
    ├─ ConversationBox.vue
    │      │
    │      ├─ MessagesView.vue
    │      │      └─ メッセージ一覧
    │      │
    │      └─ ReplyBox.vue
    │             └─ 返信入力
    │
    └─ ConversationSidebar.vue
           └─ 連絡先情報
```

### データフロー図

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

フィルター条件         ──▶   ConversationView.vue        ──▶   会話一覧表示
担当者タブ選択               ChatList.vue
会話選択                         │
                                │
                                ▼
                          [Vuex Store]
                          conversations module
                                │
                    ┌───────────┼───────────┐
                    ▼           ▼           ▼
            fetchAllConversations  getters   mutations
                    │           │           │
                    ▼           ▼           ▼
            API呼び出し   会話一覧取得   状態更新
            GET /conversations
                    │
                    ▼
            [バーチャルスクロール]
            DynamicScroller
                    │
                    ▼
            [ConversationItem]
            会話アイテム表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ConversationView.vue | `app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue` | ソース | メイン画面コンポーネント |
| conversation.routes.js | `app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` | ソース | ルーティング定義 |
| ChatList.vue | `app/javascript/dashboard/components/ChatList.vue` | ソース | 会話一覧コンポーネント |
| ChatListHeader.vue | `app/javascript/dashboard/components/ChatListHeader.vue` | ソース | 一覧ヘッダーコンポーネント |
| ConversationItem.vue | `app/javascript/dashboard/components/ConversationItem.vue` | ソース | 会話アイテムコンポーネント |
| ConversationBox.vue | `app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue` | ソース | 会話詳細コンポーネント |
| ConversationSidebar.vue | `app/javascript/dashboard/components/widgets/conversation/ConversationSidebar.vue` | ソース | サイドバーコンポーネント |
| conversations/index.js | `app/javascript/dashboard/store/modules/conversations/index.js` | ソース | 会話Vuexモジュール |
| conversations/getters.js | `app/javascript/dashboard/store/modules/conversations/getters.js` | ソース | 会話getter |
| conversations/actions.js | `app/javascript/dashboard/store/modules/conversations/actions.js` | ソース | 会話actions |
| en.json | `app/javascript/dashboard/i18n/locale/en/chatList.json` | 設定 | i18n翻訳ファイル |
