# 画面設計書 53-ラベル一覧画面

## 概要

本ドキュメントは、Chatwootのラベル一覧画面の設計書です。会話や連絡先に付与するラベルの作成・編集・削除を管理する画面です。

### 本画面の処理概要

ラベル（タグ）の一覧表示と管理を行う画面です。ラベルは会話や連絡先を分類・整理するために使用され、サイドバーでのフィルタリングにも活用されます。

**業務上の目的・背景**：カスタマーサポートでは、問い合わせの種類や優先度、ステータスなどをラベルで分類することで、効率的なワークフロー管理を実現します。チーム内での情報共有や、特定カテゴリの会話を素早く見つけるためにも重要な機能です。

**画面へのアクセス方法**：設定メニュー > ラベル

**主要な操作・処理内容**：
1. ラベル一覧の表示（名前、説明、色）
2. 新規ラベル作成（モーダル）
3. ラベル編集（モーダル）
4. ラベル削除（確認モーダル）

**画面遷移**：
- 遷移元: 設定ホーム画面
- 遷移先: なし（モーダル操作のみ）

**権限による表示制御**：管理者（administrator）のみがこの画面にアクセス可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 78 | ラベル作成・管理 | 主機能 | ラベルの一覧と管理 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/app/accounts/:accountId/settings/labels/list`
- ルート名: `labels_list`
- 権限: administrator

## 入出力項目

なし（一覧表示のみ、操作はモーダルで実行）

## 表示項目

| 項目名 | 型 | 説明 |
|--------|------|------|
| records | Array<Label> | ラベル一覧 |
| label.title | String | ラベル名 |
| label.description | String | ラベル説明 |
| label.color | String | ラベル色（HEXカラーコード） |

### テーブルヘッダー

| カラム名 | キー | 説明 |
|----------|------|------|
| 名前 | LABEL_MGMT.LIST.TABLE_HEADER.NAME | ラベル名 |
| 説明 | LABEL_MGMT.LIST.TABLE_HEADER.DESCRIPTION | ラベル説明 |
| 色 | LABEL_MGMT.LIST.TABLE_HEADER.COLOR | ラベル色 |

## イベント仕様

### 1-ラベル追加ボタン押下（openAddPopup）

**トリガー**: 「ラベル追加」ボタン押下

**処理フロー**:
1. `showAddPopup`をtrueに設定
2. AddLabelモーダルコンポーネントを表示

### 2-ラベル編集ボタン押下（openEditPopup）

**トリガー**: 各ラベル行の編集ボタン押下

**処理フロー**:
1. `showEditPopup`をtrueに設定
2. `selectedLabel`に対象ラベルオブジェクトを格納
3. EditLabelモーダルコンポーネントを表示

### 3-ラベル削除ボタン押下（openDeletePopup）

**トリガー**: 各ラベル行の削除ボタン押下

**処理フロー**:
1. `showDeleteConfirmationPopup`をtrueに設定
2. `selectedLabel`に対象ラベルオブジェクトを格納
3. 削除確認モーダルを表示

### 4-削除確認（confirmDeletion）

**トリガー**: 削除確認モーダルで「はい」押下

**処理フロー**:
1. `loading[selectedLabel.id]`をtrueに設定
2. モーダルを閉じる
3. `store.dispatch('labels/delete', id)`を実行
4. 成功時: 成功メッセージをアラート表示
5. 失敗時: エラーメッセージをアラート表示
6. `loading`をfalseに設定

### 5-ラベル作成（AddLabel内のaddLabel）

**トリガー**: 追加モーダルで「作成」ボタン押下

**処理フロー**:
1. `store.dispatch('labels/create', {...})`を実行
2. 成功時: 成功メッセージをアラート表示、モーダルを閉じる
3. 失敗時: エラーメッセージをアラート表示

### 6-ラベル更新（EditLabel内のeditLabel）

**トリガー**: 編集モーダルで「更新」ボタン押下

**処理フロー**:
1. `store.dispatch('labels/update', {...})`を実行
2. 成功時: 成功メッセージをアラート表示、モーダルを閉じる
3. 失敗時: エラーメッセージをアラート表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ラベル追加 | labels | INSERT | 新規ラベルを作成 |
| ラベル編集 | labels | UPDATE | 既存ラベルを更新 |
| ラベル削除 | labels | DELETE | ラベルを削除 |
| 画面表示 | labels | SELECT | ラベル一覧を取得 |

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

#### labels

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | title | フォーム入力値（小文字変換） | 必須、一意 |
| INSERT | description | フォーム入力値 | 任意 |
| INSERT | color | カラーピッカーで選択した値 | HEXカラーコード |
| INSERT | show_on_sidebar | チェックボックスの値 | デフォルトtrue |
| UPDATE | title | フォーム入力値（小文字変換） | 必須、一意 |
| UPDATE | description | フォーム入力値 | 任意 |
| UPDATE | color | カラーピッカーで選択した値 | HEXカラーコード |
| UPDATE | show_on_sidebar | チェックボックスの値 | |
| DELETE | id | 対象ラベルのID | 物理削除 |

## メッセージ仕様

| 種別 | キー | 表示条件 | メッセージ内容 |
|------|------|----------|--------------|
| 成功 | LABEL_MGMT.ADD.API.SUCCESS_MESSAGE | ラベル作成成功時 | ラベル作成成功 |
| エラー | LABEL_MGMT.ADD.API.ERROR_MESSAGE | ラベル作成失敗時 | ラベル作成エラー |
| 成功 | LABEL_MGMT.EDIT.API.SUCCESS_MESSAGE | ラベル更新成功時 | ラベル更新成功 |
| エラー | LABEL_MGMT.EDIT.API.ERROR_MESSAGE | ラベル更新失敗時 | ラベル更新エラー |
| 成功 | LABEL_MGMT.DELETE.API.SUCCESS_MESSAGE | ラベル削除成功時 | ラベル削除成功 |
| エラー | LABEL_MGMT.DELETE.API.ERROR_MESSAGE | ラベル削除失敗時 | ラベル削除エラー |
| 情報 | LABEL_MGMT.LOADING | 読み込み中 | 読み込み中メッセージ |
| 情報 | LABEL_MGMT.LIST.404 | ラベルなし | ラベルが見つかりません |

## 例外処理

| 例外状況 | 対応処理 |
|----------|----------|
| ラベル一覧が空 | 「ラベルが見つかりません」メッセージを表示 |
| API通信エラー | `useAlert()`でエラーメッセージをトースト表示 |
| バリデーションエラー | フォームにエラーメッセージを表示（タイトル必須など） |
| 権限不足 | ルートガードにより画面アクセス自体をブロック |

## 備考

- ラベル名は自動的に小文字に変換される
- 色はランダムに初期値が設定される（getRandomColor）
- show_on_sidebar がtrueのラベルはサイドバーに表示される
- SettingsLayoutコンポーネントでローディング状態と空状態を管理

---

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

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

### 推奨読解順序

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

ラベルのデータ構造とストア管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | labels.js | `app/javascript/dashboard/store/modules/labels.js` | Vuexストアの構造、CRUD操作 |
| 1-2 | labels.js | `app/javascript/dashboard/api/labels.js` | APIクライアント定義 |

**読解のコツ**: `CacheEnabledApiClient`を継承しており、キャッシュ機能付きのAPI通信を行う。

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

メインコンポーネントの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Index.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/Index.vue` | 一覧表示、モーダル制御 |

**主要処理フロー**:
1. **L78-80**: `onBeforeMount`でラベル一覧を取得
2. **L23**: `records`でソート済みラベル一覧を取得
3. **L51-62**: `deleteLabel()`で削除処理
4. **L64-68**: `confirmDeletion()`で削除確認

#### Step 3: モーダルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AddLabel.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/AddLabel.vue` | ラベル作成フォーム |
| 3-2 | EditLabel.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/EditLabel.vue` | ラベル編集フォーム |
| 3-3 | validations.js | `app/javascript/dashboard/routes/dashboard/settings/labels/validations.js` | バリデーションルール |

**主要処理フロー**:
- **AddLabel L50-65**: `addLabel()`で新規作成
- **EditLabel L59-75**: `editLabel()`で更新

#### Step 4: ルーティング設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | labels.routes.js | `app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js` | ルート定義 |

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

```
Index.vue (コンポーネント)
    │
    ├─ onBeforeMount()
    │      └─ store.dispatch('labels/get')
    │             └─ LabelsAPI.get()
    │
    ├─ openAddPopup()
    │      └─ AddLabel.vue (モーダル)
    │             └─ addLabel()
    │                    └─ store.dispatch('labels/create', {...})
    │                           └─ LabelsAPI.create()
    │
    ├─ openEditPopup(label)
    │      └─ EditLabel.vue (モーダル)
    │             └─ editLabel()
    │                    └─ store.dispatch('labels/update', {...})
    │                           └─ LabelsAPI.update()
    │
    └─ openDeletePopup(label)
           └─ woot-delete-modal
                  └─ confirmDeletion()
                         └─ deleteLabel(id)
                                └─ store.dispatch('labels/delete', id)
                                       └─ LabelsAPI.delete()
```

### データフロー図

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

                    ┌──▶ store.dispatch('labels/get')
onBeforeMount() ────┤         │
                    │         ▼
                    │    LabelsAPI.get() ──────────────▶ labels (Vuex Store)
                    │                                         │
                    └──▶ getters['labels/getLabels'] ◀────────┘
                                │
                                ▼
                          records (computed)
                                │
                                ▼
                          テーブル表示

[CRUD操作]
                    ┌──▶ labels/create ──▶ LabelsAPI.create() ──▶ ADD_LABEL
ユーザー操作 ───────┼──▶ labels/update ──▶ LabelsAPI.update() ──▶ EDIT_LABEL
                    └──▶ labels/delete ──▶ LabelsAPI.delete() ──▶ DELETE_LABEL
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Index.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/Index.vue` | ソース | メインコンポーネント |
| AddLabel.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/AddLabel.vue` | ソース | 追加モーダル |
| EditLabel.vue | `app/javascript/dashboard/routes/dashboard/settings/labels/EditLabel.vue` | ソース | 編集モーダル |
| validations.js | `app/javascript/dashboard/routes/dashboard/settings/labels/validations.js` | ソース | バリデーション定義 |
| labels.routes.js | `app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js` | ソース | ルーティング定義 |
| labels.js | `app/javascript/dashboard/store/modules/labels.js` | ソース | Vuexストア |
| labels.js | `app/javascript/dashboard/api/labels.js` | ソース | APIクライアント |
| SettingsLayout.vue | `app/javascript/dashboard/routes/dashboard/settings/SettingsLayout.vue` | ソース | レイアウトコンポーネント |
| BaseSettingsHeader.vue | `app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue` | ソース | ヘッダーコンポーネント |
