# 画面設計書 266-ラベル編集

## 概要

本ドキュメントは、GitLab管理者エリアにおける「ラベル編集」画面の設計を記載したものです。既存のテンプレートラベルの設定を変更するための画面です。

### 本画面の処理概要

**業務上の目的・背景**：組織のラベル体系は時間とともに進化します。管理者は、既存のテンプレートラベルの名前、説明、色を変更して、組織のニーズに合わせた課題分類体系を維持する必要があります。本画面は、既存のテンプレートラベルを編集するためのインターフェースを提供します。

**画面へのアクセス方法**：管理者エリア > ラベル一覧 > 対象ラベルの編集ボタン、または `/admin/labels/:id/edit` に直接アクセスします。管理者権限が必要です。

**主要な操作・処理内容**：
1. 既存のラベル情報の表示
2. ラベル名の変更
3. ラベルの説明文の変更
4. ラベルの背景色の変更
5. ラベルの削除
6. 変更の保存

**画面遷移**：
- 遷移元：ラベル一覧画面
- 遷移先：ラベル一覧画面（更新成功後）、同一画面（バリデーションエラー時）

**権限による表示制御**：管理者権限を持つユーザーのみがアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 120 | ラベル管理 | 主機能 | システムラベルの編集・削除 |
| 40 | ラベル管理 | 補助機能 | ラベルの基本機能 |

## 画面種別

編集

## URL/ルーティング

- URL: `/admin/labels/:id/edit`
- HTTPメソッド: GET（フォーム表示）、PATCH/PUT（更新実行）、DELETE（削除）
- コントローラー: `Admin::LabelsController#edit`, `Admin::LabelsController#update`, `Admin::LabelsController#destroy`

## 入出力項目

### 入力項目

| 項目名 | 物理名 | 型 | 必須 | 最大長 | 説明 |
|--------|--------|-----|------|--------|------|
| タイトル | title | String | 必須 | 255 | ラベルの表示名 |
| 説明 | description | Text | - | 512KB | ラベルの説明文 |
| 背景色 | color | String | 必須 | 7 | HEX形式の色コード（例：#428BCA） |

## 表示項目

### フォーム構成

| セクション | 内容 |
|-----------|------|
| ページヘッダー | "Edit label" |
| タイトル入力 | 既存値が設定されたテキストフィールド |
| 説明入力 | 既存値が設定されたテキストエリア |
| 色選択 | 既存色が選択されたカラーピッカー + プリセット色 |
| アクション | 「Save changes」ボタン、「Cancel」ボタン、「Delete」ボタン |

### アーカイブ警告（該当時）

| 条件 | 表示内容 |
|------|----------|
| ラベルがアーカイブ済み | 警告アラート + アーカイブ解除ボタン |

## イベント仕様

### 1-ラベル更新

**トリガー**: 「Save changes」ボタン押下

**処理フロー**:
1. フォームデータをPATCH/PUTで `/admin/labels/:id` に送信
2. `Labels::UpdateService` でラベルを更新
3. バリデーション実行
4. 成功時：成功メッセージをフラッシュに設定し、ラベル一覧にリダイレクト
5. 失敗時：エラーメッセージを表示し、フォームを再表示

### 2-ラベル削除

**トリガー**: 「Delete」ボタン押下

**処理フロー**:
1. 確認モーダル表示（JavaScriptで実装）
2. 確認後、DELETEリクエストを `/admin/labels/:id` に送信
3. 成功時：成功メッセージをフラッシュに設定し、ラベル一覧にリダイレクト
4. 失敗時：エラーメッセージをフラッシュに設定し、ラベル一覧にリダイレクト

### 3-アーカイブ解除

**トリガー**: 「Unarchive label」ボタン押下（アーカイブ済みラベルのみ）

**処理フロー**:
1. `archived: false` を設定したPATCHリクエストを送信
2. ラベルのアーカイブ状態を解除

### 4-キャンセル

**トリガー**: 「Cancel」ボタン押下

**処理フロー**:
1. ラベル一覧画面（`/admin/labels`）にリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ラベル更新 | labels | UPDATE | ラベル情報を更新 |
| ラベル削除 | labels | DELETE | ラベルレコードを削除 |
| アーカイブ解除 | labels | UPDATE | archivedフラグを更新 |

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

#### labels

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | title | フォーム入力値 | 一意性チェック |
| UPDATE | description | フォーム入力値 | |
| UPDATE | color | フォーム入力値 | HEX形式 |
| UPDATE | archived | false | アーカイブ解除時 |
| UPDATE | updated_at | 現在時刻 | |
| DELETE | id | 指定されたID | 関連レコードも連動削除 |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|----------|
| 成功 | ラベル更新成功 | "Label was successfully updated." |
| 成功 | ラベル削除成功 | "{label_name} was removed" |
| エラー | バリデーションエラー | 各項目のエラーメッセージ |
| 警告 | アーカイブ済み | "This label is archived and not available for use. Unarchive to use it again." |

## 例外処理

| 状態 | 処理 |
|------|------|
| ラベルが見つからない | 404エラー画面を表示 |
| バリデーションエラー | エラーメッセージを表示し、フォームを再表示 |
| 権限不足 | アクセス拒否画面にリダイレクト |
| 削除失敗 | エラーメッセージを表示し、ラベル一覧にリダイレクト |

## 備考

- ラベルフォームは `shared/labels/_form.html.haml` を共有
- `Labels::UpdateService` を使用してラベルを更新
- 削除確認はJavaScriptモーダルで実装（`js-delete-label-modal-button`）
- `labels_archive` フィーチャーフラグが有効な場合のみアーカイブ警告を表示
- ページ固有スタイル `page_bundles/labels` を使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | label.rb | `app/models/label.rb` | Labelモデルの属性、バリデーション |
| 1-2 | base_label.rb | `app/models/concerns/base_label.rb` | 共通ラベル機能 |

**読解のコツ**: `validates`メソッドでバリデーションルールを確認。`archived`属性でアーカイブ状態を管理。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | labels_controller.rb | `app/controllers/admin/labels_controller.rb` | edit、update、destroyアクション |

**主要処理フロー**:
1. **行19**: `edit` - 既存ラベルの表示
2. **行31-39**: `update` - UpdateServiceを使用してラベルを更新
3. **行41-57**: `destroy` - ラベルの削除処理
4. **行61-63**: `set_label` - before_actionでラベルを取得

#### Step 3: ビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.haml | `app/views/admin/labels/edit.html.haml` | 編集画面のレイアウト |
| 3-2 | _form.html.haml | `app/views/shared/labels/_form.html.haml` | 共有フォームコンポーネント |

**主要処理フロー**:
- **行6-7**: ページヘッダーとフォームのレンダリング
- フォーム：既存値の表示、更新、削除ボタン

#### Step 4: サービスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | update_service.rb | `app/services/labels/update_service.rb` | ラベル更新ロジック |

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

```
Admin::LabelsController#edit
    │
    └─ set_label (before_action)
           └─ Label.in_organization.templates.find(id)

Admin::LabelsController#update
    │
    ├─ set_label (before_action)
    │
    └─ Labels::UpdateService.new(label_params)
           │
           └─ execute(@label)
                  │
                  └─ @label.update(params)

Admin::LabelsController#destroy
    │
    ├─ set_label (before_action)
    │
    └─ @label.destroy
           ├─ label_links.destroy_all
           ├─ label_priorities.destroy_all
           └─ lists.destroy_all
```

### データフロー図

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

label_id ───────────────▶ Label.find ──────────────▶ @label (edit表示)

フォーム入力 ───────────▶ label_params ──────────────▶ UpdateService
                              │
                              └─ title, description, color

UpdateService ─────────▶ @label.update ────────────▶ 更新済み@label
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| labels_controller.rb | `app/controllers/admin/labels_controller.rb` | コントローラー | リクエスト処理 |
| edit.html.haml | `app/views/admin/labels/edit.html.haml` | テンプレート | 画面表示 |
| _form.html.haml | `app/views/shared/labels/_form.html.haml` | パーシャル | フォームコンポーネント |
| label.rb | `app/models/label.rb` | モデル | ラベルデータモデル |
| update_service.rb | `app/services/labels/update_service.rb` | サービス | 更新ロジック |
| admin.rb | `config/routes/admin.rb` | ルーティング | URL定義 |
| labels.scss | `app/assets/stylesheets/page_bundles/labels.scss` | スタイル | ラベル表示用CSS |
