# 画面設計書 28-タスク一覧画面

## 概要

本ドキュメントは、Fat Free CRMシステムにおけるタスク一覧画面の設計を記述する。タスクを期日・カテゴリ別にグループ化して一覧表示し、完了/未完了の切り替え、フィルタリング、CSV/XLSエクスポートなどの機能を提供する画面である。

### 本画面の処理概要

タスク一覧画面は、個人およびチームのタスク管理を行うための中核画面である。期日に基づいたバケット（グループ）でタスクを整理し、優先度の可視化を実現する。

**業務上の目的・背景**：営業担当者は日々多くのタスク（フォローアップ、提案書作成、顧客訪問等）を管理する必要がある。本画面により、タスクの期日別整理、優先順位の明確化、進捗管理を実現する。

**画面へのアクセス方法**：
- ナビゲーションバーの「Tasks」リンクをクリック
- ダッシュボードのタスクセクションから「すべて表示」をクリック
- URL直接アクセス（`/tasks`）

**主要な操作・処理内容**：
1. タスクの期日別グループ表示（Overdue, Today, Tomorrow, This Week, Next Week, Later, ASAP）
2. ビュー切り替え（Pending/Assigned/Completed）
3. カテゴリフィルタリング
4. タスクの完了/未完了切り替え
5. CSV/XLSエクスポート
6. 新規タスク作成フォームの表示
7. タスクの編集・削除

**画面遷移**：
- 遷移元：ダッシュボード、各エンティティ詳細画面
- 遷移先：タスク新規作成フォーム、タスク編集フォーム、関連エンティティ詳細画面

**権限による表示制御**：ユーザーは自分が作成したタスク、自分に割り当てられたタスクのみ表示可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 34 | タスク一覧表示 | 主機能 | タスクをグループ化して一覧表示、CSV/XLSエクスポート |
| 41 | タスクフィルタリング | 補助機能 | タスクのカテゴリ等によるフィルタリング |
| 38 | タスク削除 | 補助機能 | タスクの削除処理 |

## 画面種別

一覧画面

## URL/ルーティング

- URL: `/tasks`
- HTTPメソッド: GET
- コントローラ: `TasksController#index`
- フォーマット: HTML, JS, JSON, CSV, XLS, XML

### 関連URL

| URL | メソッド | アクション | 説明 |
|-----|---------|----------|------|
| /tasks/filter | POST | filter | フィルター適用 |
| /tasks/:id/complete | PUT | complete | タスク完了 |
| /tasks/:id/uncomplete | PUT | uncomplete | タスク未完了に戻す |

## 入出力項目

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| view | String | 任意 | ビュー種別（pending/assigned/completed） |
| filter | String | 任意 | フィルター条件 |

### 出力データ（インスタンス変数）

| 変数名 | 型 | 説明 |
|--------|-----|------|
| @tasks | Hash | バケット別タスク配列のハッシュ |
| @view | String | 現在のビュー種別 |
| @task_total | Hash | バケット別タスク件数 |

## 表示項目

### タイトルバー

| 項目名 | 説明 |
|--------|------|
| タイトル | ビューに応じたタイトル（Pending/Assigned/Completed Tasks） |
| 新規作成ボタン | タスク新規作成フォームを開く |
| ビュー切替タブ | Pending/Assigned/Completed切替 |

### タスクバケット（Pendingビュー）

| バケット名 | 説明 |
|-----------|------|
| Overdue | 期限切れタスク |
| Due ASAP | 至急タスク（期日なし） |
| Due Today | 本日期限 |
| Due Tomorrow | 明日期限 |
| Due This Week | 今週期限 |
| Due Next Week | 来週期限 |
| Due Later | それ以降 |

### タスクバケット（Completedビュー）

| バケット名 | 説明 |
|-----------|------|
| Completed Today | 本日完了 |
| Completed Yesterday | 昨日完了 |
| Completed This Week | 今週完了 |
| Completed Last Week | 先週完了 |
| Completed This Month | 今月完了 |
| Completed Last Month | 先月完了 |

### タスク項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| 完了チェックボックス | - | クリックで完了/未完了切替 |
| タスク名 | task.name | タスクの名称 |
| 関連エンティティ | task.asset | 関連する取引先/連絡先/商談等 |
| 担当者 | task.assignee | 割り当て先ユーザー |
| カテゴリ | task.category | タスクカテゴリ |
| 期日 | task.due_at | 期日・時刻 |

### サイドバー（フィルターパネル）

| 項目名 | 説明 |
|--------|------|
| All | 全件数と選択 |
| 各バケット | バケット別件数と選択/非選択 |

## イベント仕様

### 1-タスク完了チェック

- **トリガー**: タスクの完了チェックボックスをクリック
- **処理**:
  1. Ajax経由でcomplete/uncompleteアクション呼び出し
  2. タスクのcompleted_at, completed_byを更新
  3. バケットが空になった場合は非表示
  4. サイドバーの件数を更新
- **遷移先**: 同一画面（タスク状態更新）

### 2-新規作成ボタンクリック

- **トリガー**: 「Create Task」ボタンをクリック
- **処理**: Ajax経由で新規作成フォームを取得し表示
- **遷移先**: 同一画面内にフォーム表示

### 3-ビュー切替

- **トリガー**: Pending/Assigned/Completedタブをクリック
- **処理**: 選択したビューでタスク一覧を再取得
- **遷移先**: 同一画面（ビュー切替）

### 4-フィルター選択

- **トリガー**: サイドバーのバケットチェックボックスを変更
- **処理**:
  1. Ajax経由でフィルター適用
  2. セッションにフィルター状態を保存
  3. 一覧を再描画
- **遷移先**: 同一画面（フィルター反映）

### 5-タスク削除

- **トリガー**: 削除リンクをクリック
- **処理**:
  1. Ajax経由で削除実行
  2. 一覧から該当タスクを削除
  3. バケットが空になった場合は非表示
  4. サイドバーの件数を更新
- **遷移先**: 同一画面（一覧更新）

### 6-CSV/XLSエクスポート

- **トリガー**: CSV/XLSリンクをクリック
- **処理**: 現在のビュー・フィルター条件で全件エクスポート
- **レスポンス**: ファイルダウンロード

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | tasks | SELECT | タスク一覧取得 |
| 完了切替 | tasks | UPDATE | completed_at, completed_by更新 |
| 削除実行 | tasks | UPDATE | deleted_at設定（論理削除） |

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

#### tasks（完了時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | completed_at | Time.now | 完了日時 |
| UPDATE | completed_by | current_user.id | 完了操作ユーザー |

#### tasks（未完了に戻す時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | completed_at | nil | 完了日時クリア |
| UPDATE | completed_by | nil | 完了操作ユーザークリア |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 |
|------|---------------|---------|
| 情報 | - | タスクが0件の場合「No tasks」等のメッセージ |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 許可されていないビュー | デフォルトビュー（pending）にフォールバック |
| 権限なしタスクへのアクセス | 一覧から除外（表示されない） |

## 備考

- タスクは3つのビューで切替可能（Pending/Assigned/Completed）
- Pendingビュー: 自分が作成したタスクまたは自分に割り当てられた未完了タスク
- Assignedビュー: 自分が作成し他者に割り当てた未完了タスク
- Completedビュー: 完了済みタスク
- バケット設定はSetting.task_bucket/task_completedで定義
- フィルター状態はセッションに保存

---

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

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

### 推奨読解順序

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

タスクエンティティのデータ構造とスコープを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | task.rb | `app/models/polymorphic/task.rb` | スコープ定義（46-108行目）、特にmy, assigned_by, tracked_by |
| 1-2 | task.rb | `app/models/polymorphic/task.rb` | find_all_grouped（177-186行目）、bucket_empty?（189-199行目）、totals（202-212行目） |

**読解のコツ**: `ALLOWED_VIEWS`定数（35行目）で許可されるビューを確認。各due_*スコープで期日ベースのフィルタリングを理解する。

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

コントローラーのindexアクションを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tasks_controller.rb | `app/controllers/tasks_controller.rb` | indexアクション（14-23行目）、viewメソッド（222-226行目）、update_sidebar（197-218行目） |

**主要処理フロー**:
1. **15行目**: `@view = view` でビュー種別を取得（デフォルト: pending）
2. **16行目**: `Task.find_all_grouped(current_user, @view)` でバケット別タスク取得
3. **before_action**: `update_sidebar`でサイドバーデータ更新

#### Step 3: ビューテンプレートを理解する

一覧画面の構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/tasks/index.html.haml` | ページ構造、バケット別レンダリング |

**主要処理フロー**:
- **3-10行目**: ビューに応じたバケット設定の取得
- **13-16行目**: バケットごとのタスクレンダリング

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

```
TasksController#index
    │
    ├─ before_action :set_current_tab
    │
    ├─ before_action :update_sidebar
    │      ├─ @view = view
    │      ├─ @task_total = Task.totals(current_user, @view)
    │      └─ セッション更新
    │
    ├─ @view = view
    │      └─ ALLOWED_VIEWS check (pending/assigned/completed)
    │
    ├─ @tasks = Task.find_all_grouped(current_user, @view)
    │      │
    │      ├─ Setting.task_bucket / task_completed
    │      │
    │      └─ Hash[settings.map { |key, _| [key, scope.send(key)] }]
    │             ├─ my(user) / assigned_by(user)
    │             ├─ due_asap / overdue / due_today / ...
    │             └─ pending / completed
    │
    └─ respond_with(@tasks)
           ├─ format.html → index.html.haml
           │      ├─ _title.html.haml
           │      ├─ バケットごとの_pending / _completed
           │      └─ _empty.html.haml
           ├─ format.csv → CSV出力
           └─ format.xls → XLS出力
```

### データフロー図

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

Request
/tasks?view=pending ───▶ TasksController#index
                              │
                              ├──▶ view validation
                              │
                              ├──▶ Task.find_all_grouped
                              │         │
                              │         ├──▶ Task.my(user) / assigned_by(user)
                              │         │
                              │         ├──▶ 各due_*スコープ
                              │         │
                              │         └──▶ [tasks] SELECT
                              │
                              ├──▶ Task.totals
                              │         │
                              │         └──▶ バケット別COUNT
                              │
                              └────────────────────────▶ HTML/CSV/XLS
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| task.rb | `app/models/polymorphic/task.rb` | モデル | タスクエンティティ、スコープ |
| tasks_controller.rb | `app/controllers/tasks_controller.rb` | コントローラ | 一覧表示処理 |
| index.html.haml | `app/views/tasks/index.html.haml` | テンプレート | 一覧画面メインビュー |
| _title.html.haml | `app/views/tasks/_title.html.haml` | テンプレート | タイトルバー |
| _pending.html.haml | `app/views/tasks/_pending.html.haml` | テンプレート | 未完了タスク表示 |
| _completed.html.haml | `app/views/tasks/_completed.html.haml` | テンプレート | 完了タスク表示 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（144-153行目） |
