# 画面設計書 12-グループ一覧

## 概要

本ドキュメントは、GitLabダッシュボードのグループ一覧画面（Dashboard Groups Index）の画面設計を定義したものである。

### 本画面の処理概要

ログインユーザーが参加しているグループの一覧を表示し、グループへの迅速なアクセスを可能にするダッシュボード画面である。

**業務上の目的・背景**：GitLabではプロジェクトをグループ（組織単位）で管理することが推奨されており、ユーザーは複数のグループに所属することが一般的である。本画面は、ユーザーが所属するすべてのグループを一覧で確認し、目的のグループへ素早くアクセスするための起点となる。グループの構造（親子関係）や権限レベルも把握できる。

**画面へのアクセス方法**：ログイン後、サイドバーまたはトップナビゲーションから「Groups」メニューを選択。直接URLアクセスの場合は `/dashboard/groups` へアクセスする。

**主要な操作・処理内容**：
1. グループ一覧の表示（ツリー構造対応）
2. グループ名による検索・フィルタリング
3. ソート順の変更（名前順、作成日順など）
4. 各グループの詳細画面への遷移
5. 新規グループ作成画面への遷移
6. サブグループの展開・折りたたみ
7. グループのフィルタリング（Member、Inactiveなど）

**画面遷移**：
- 遷移元：ログイン画面、サイドバー、トップナビゲーション
- 遷移先：グループ詳細画面、グループ新規作成画面

**権限による表示制御**：ログインユーザーのみアクセス可能。表示されるグループはユーザーがメンバーとして参加しているグループ、または公開・内部公開グループに限定される。all_availableパラメータがfalseの場合、ユーザーが直接メンバーであるグループのみ表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 122 | グループダッシュボード | 主機能 | 参加グループの一覧表示 |

## 画面種別

一覧

## URL/ルーティング

| URL | HTTPメソッド | 説明 |
|-----|-------------|------|
| `/dashboard/groups` | GET | グループ一覧（HTML） |
| `/dashboard/groups.json` | GET | グループ一覧（JSON API） |
| `/dashboard/groups/member` | GET | メンバーのグループ一覧 |
| `/dashboard/groups/inactive` | GET | 非アクティブグループ一覧 |

## 入出力項目

### 入力項目（検索・フィルタ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| filter | string | No | フィルタ条件 |
| sort | string | No | ソート順（name_asc, name_desc, created_asc, created_desc等） |
| active | boolean | No | アクティブ状態フィルタ |
| page | integer | No | ページ番号 |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| groups | Array | グループ一覧（ツリー構造） |

## 表示項目

### グループ一覧

| 項目名 | 説明 | 備考 |
|--------|------|------|
| グループアバター | グループのアイコン画像 | |
| グループ名 | グループのフルパス | リンク |
| 説明 | グループの説明文 | 省略表示 |
| メンバー数 | グループに所属するメンバー数 | |
| プロジェクト数 | グループ配下のプロジェクト数 | |
| サブグループ数 | 子グループの数 | |
| 可視性アイコン | Public/Internal/Private | アイコン表示 |
| 展開/折りたたみボタン | サブグループの表示切替 | ツリー構造時 |

## イベント仕様

### 1-グループリストの読み込み

Vue.jsアプリケーション（`#js-your-work-groups-app`）がマウントされ、APIを通じてグループ一覧を取得する。

**処理フロー**：
1. ページ読み込み時にVueアプリケーションが初期化
2. `groups_list_with_filtered_search_app_data`からアプリケーション設定を取得
3. JSON APIを通じてグループ一覧を非同期取得
4. GroupTree機能によりツリー構造で表示

### 2-ソート順変更

ソート条件を変更すると、URLパラメータが更新され、グループ一覧が再取得される。

### 3-サブグループ展開

グループの展開ボタンをクリックすると、該当グループの子グループが読み込まれ表示される。

**処理フロー**：
1. 展開ボタンクリック
2. 子グループ取得APIへリクエスト
3. 成功時、子グループを親グループ配下に表示

### 4-検索・フィルタリング

検索ボックスに入力またはフィルタを選択すると、条件に合致するグループのみ表示される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | namespaces | SELECT | ユーザーが参加しているグループを取得 |
| ページ表示 | members | SELECT | メンバーシップ確認 |

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

#### namespaces（type='Group'）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, path, parent_id, visibility_level, description | GroupsFinder経由でユーザーがアクセス可能なグループ | |

#### members

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | user_id, source_id, source_type, access_level | user_id = current_user.id | グループメンバーシップ確認 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 情報 | "You don't have access to any groups." | グループが存在しない場合 |
| MSG-002 | 情報 | "No groups found" | 検索結果が0件の場合 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 未ログイン | ログイン画面へリダイレクト | - |
| API通信エラー | エラーメッセージ表示 | "Something went wrong. Please try again." |

## 備考

- Vue.jsベースのSPA実装（`#js-your-work-groups-app`）
- GroupTreeモジュールによるツリー構造表示のサポート
- Ultimate Trial広告の表示機能あり
- Current.organizationによる組織スコープのフィルタリング

---

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

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

### 推奨読解順序

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

まず、グループのデータ構造とFinderパターンを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | group.rb | `app/models/group.rb` | Groupモデルの定義、Namespaceからの継承、アソシエーション |
| 1-2 | groups_finder.rb | `app/finders/groups_finder.rb` | グループ検索ロジック、all_availableフラグ |

**読解のコツ**: GroupはNamespaceを継承しており、STI（Single Table Inheritance）パターンを使用している。

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

処理の起点となるコントローラを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_controller.rb | `app/controllers/dashboard/groups_controller.rb` | indexアクション、GroupTree concern |

**主要処理フロー**:
1. **Line 4**: `include GroupTree`でツリー表示機能を取り込む
2. **Line 12-20**: `index`アクションでGroupsFinderを使用
3. **Line 15-17**: all_available: falseでメンバーのグループのみ取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/dashboard/groups/index.html.haml` | HAMLテンプレート、Vue.jsアプリのマウントポイント |

**主要処理フロー**:
- **Line 6**: `_groups_head`パーシャルのレンダリング
- **Line 7**: Vue.jsアプリのマウント、`groups_list_with_filtered_search_app_data`の利用

#### Step 4: GroupTreeモジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | group_tree.rb | `app/controllers/concerns/group_tree.rb` | render_group_treeメソッド、ツリー構造レンダリング |

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

```
Dashboard::GroupsController#index
    |
    +-- GroupsFinder.new(current_user, all_available: false, organization: Current.organization)
    |       |
    |       +-- execute
    |              |
    |              +-- filtered_groups
    |              +-- by_organization
    |              +-- by_active
    |
    +-- render_group_tree(groups) [from GroupTree concern]
           |
           +-- render 'dashboard/groups/index'
                  |
                  +-- render 'dashboard/groups_head'
                  |
                  +-- #js-your-work-groups-app (Vue.js)
```

### データフロー図

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

URLパラメータ ───▶ Dashboard::GroupsController ───▶ HTMLレスポンス
(sort, active等)         |                           (Vue.jsアプリ)
                         |
                         v
                    GroupsFinder
                         |
                         v
                    Group (Model)
                    Namespace (STI)
                         |
                         v
                    PostgreSQL
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_controller.rb | `app/controllers/dashboard/groups_controller.rb` | コントローラ | リクエスト処理 |
| index.html.haml | `app/views/dashboard/groups/index.html.haml` | ビュー | 画面テンプレート |
| groups_finder.rb | `app/finders/groups_finder.rb` | ファインダー | グループ検索ロジック |
| group.rb | `app/models/group.rb` | モデル | グループデータ定義 |
| namespace.rb | `app/models/namespace.rb` | モデル | 名前空間基底クラス |
| group_tree.rb | `app/controllers/concerns/group_tree.rb` | Concern | ツリー表示機能 |
| groups_helper.rb | `app/helpers/groups_helper.rb` | ヘルパー | ビューヘルパー関数 |
| dashboard.rb | `config/routes/dashboard.rb` | ルート | URL定義 |
