# 機能設計書 73-ヘッダー

## 概要

本ドキュメントは、Decap CMS管理画面のヘッダーコンポーネントの機能設計を記述する。

### 本機能の処理概要

本機能は、CMS管理画面の上部に固定表示されるヘッダーを提供する。サイト名/ロゴ、コレクションナビゲーション、メディアライブラリへのアクセス、ワークフロー画面へのリンク、新規エントリ作成のクイックアクセス、ユーザー設定ドロップダウンを含む。

**業務上の目的・背景**：CMS管理画面のナビゲーションハブとして、ユーザーが主要な機能（コンテンツ管理、ワークフロー、メディア管理）に素早くアクセスできるようにする。また、バックエンドの死活状態監視も担い、5分間隔でAPIの接続状態を確認する。

**機能の利用シーン**：CMS管理画面にログイン後、全画面の上部に常時表示される。コレクション一覧画面、コレクション検索結果画面、ワークフロー画面、メディアライブラリ画面からの各種ナビゲーションに使用される。

**主要な処理内容**：
1. **ナビゲーションリンク表示**: コンテンツ（コレクション一覧）とワークフロー画面へのNavLinkを表示。現在のパスに応じたアクティブスタイルを適用
2. **メディアライブラリボタン**: メディアライブラリのモーダルを開くボタンを表示（showMediaButton条件付き）
3. **新規エントリ作成ドロップダウン（Quick Add）**: create設定がtrueのコレクション一覧をドロップダウン表示し、選択されたコレクションの新規エントリ作成画面に遷移
4. **ロゴ表示**: logo設定のshow_in_headerがtrueかつsrcが指定されている場合にカスタムロゴを表示
5. **設定ドロップダウン（SettingsDropdown）**: サイトURL表示、ユーザーアバター表示、ログアウト機能を提供
6. **バックエンドステータス監視**: componentDidMountで5分間隔のcheckBackendStatusを設定し、APIの死活監視を行う

**関連システム・外部連携**：Redux（状態管理・アクションディスパッチ）、React Router（ナビゲーション）、react-polyglot（国際化）、decap-cms-ui-default（Icon、Dropdown等のUIコンポーネント）と連携する。

**権限による制御**：create設定がtrueのコレクションのみがQuick Addドロップダウンに表示される。ワークフロー画面へのリンクはhasWorkflowフラグで制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | コレクション一覧画面 | 主画面 | ヘッダーからのメディアライブラリオープン、新規エントリ作成、ワークフロー画面遷移、ログアウト |
| 4 | コレクション検索結果画面 | 参照画面 | ヘッダーナビゲーションによるコレクション一覧画面への遷移やメディアライブラリの操作 |
| 8 | ワークフロー画面 | 参照画面 | ヘッダーのワークフローリンクからの遷移。新規エントリ作成ドロップダウンの表示 |

## 機能種別

UIナビゲーション / 状態監視

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| user | object | Yes | ログインユーザー情報（avatar_url含む） | - |
| collections | ImmutableMap | Yes | コレクション定義のImmutableMap | - |
| onCreateEntryClick | function | Yes | 新規エントリ作成時のコールバック（collectionName引数） | - |
| onLogoutClick | function | Yes | ログアウトボタン押下時のコールバック | - |
| openMediaLibrary | function | Yes | メディアライブラリモーダルを開くコールバック | - |
| hasWorkflow | boolean | Yes | エディトリアルワークフローが有効か | - |
| displayUrl | string | No | 表示用サイトURL | - |
| logoUrl | string | No | ロゴ画像URL（非推奨: logo.srcに置換） | - |
| logo | object | No | ロゴ設定（src: string, show_in_header: boolean） | - |
| isTestRepo | boolean | No | テストリポジトリかどうか | - |
| showMediaButton | boolean | No | メディアボタンを表示するか | - |
| t | function | Yes | ローカライズ関数（react-polyglotのtranslate） | - |
| checkBackendStatus | function | Yes | バックエンドステータスチェック関数（mapDispatchToPropsから） | - |

### 入力データソース

- Reduxストア（collections、user、hasWorkflow、displayUrl等）
- CMS設定ファイル（config.yml: logo, display_url設定）
- mapDispatchToProps（checkBackendStatus）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| HeaderElement | JSX.Element | ヘッダーのDOM構造（AppHeader、ナビゲーション、アクション） |

### 出力先

画面表示（DOMへのレンダリング、position: sticky、z-index: 300）

## 処理フロー

### 処理シーケンス

```
1. コンポーネントマウント
   └─ componentDidMountで5分間隔のcheckBackendStatus設定
2. ナビゲーション描画
   └─ コンテンツリンク（常時）、ワークフローリンク（hasWorkflow時）、メディアボタン（showMediaButton時）
3. Quick Addドロップダウン描画
   └─ creatableCollectionsをフィルタリングし、ドロップダウンメニューとして表示
4. SettingsDropdown描画
   └─ ユーザーアバター、サイトURL、ログアウトボタンを表示
5. コンポーネントアンマウント
   └─ componentWillUnmountでsetIntervalをクリア
```

### フローチャート

```mermaid
flowchart TD
    A[Header マウント] --> B[5分間隔 checkBackendStatus 設定]
    B --> C[ナビゲーション描画]
    C --> D{hasWorkflow?}
    D -->|Yes| E[ワークフローリンク表示]
    D -->|No| F[スキップ]
    E --> G{showMediaButton?}
    F --> G
    G -->|Yes| H[メディアボタン表示]
    G -->|No| I[スキップ]
    H --> J{creatableCollections > 0?}
    I --> J
    J -->|Yes| K[Quick Add ドロップダウン表示]
    J -->|No| L[スキップ]
    K --> M[SettingsDropdown 表示]
    L --> M
    M --> N[ヘッダー描画完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | バックエンド監視間隔 | 5分（300,000ms）間隔でcheckBackendStatusを実行する | コンポーネントマウント時 |
| BR-73-02 | コレクションフィルタ | Quick Addにはcreate設定がtrueのコレクションのみ表示される | 常時 |
| BR-73-03 | コレクションラベル | Quick Addのドロップダウンにはlabel_singularを優先、未設定時はlabelを表示する | 常時 |
| BR-73-04 | ロゴ表示条件 | logo.show_in_headerがtrueかつlogo.srcが指定されている場合にロゴを表示する | logo設定存在時 |
| BR-73-05 | アクティブリンク判定 | コンテンツリンクはlocation.pathnameが'/collections/'で始まる場合にアクティブ表示される | ナビゲーション時 |

### 計算ロジック

特になし。

## データベース操作仕様

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

本機能はUIコンポーネントであり、直接的なデータベース操作は行わない。checkBackendStatusを通じたAPIアクセスのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バックエンドエラー | checkBackendStatusでAPIアクセス失敗 | statusアクション側でエラー通知を処理 |

### リトライ仕様

checkBackendStatusは5分間隔で継続的に実行されるため、エラー発生後も次回実行時にリトライされる。

## トランザクション仕様

トランザクションは存在しない。

## パフォーマンス要件

- ヘッダーはposition: stickyで固定表示されるため、スクロール時のリペイント負荷が最小限であること
- checkBackendStatusは5分間隔であり、過度なAPIアクセスを防止している

## セキュリティ考慮事項

- ユーザーアバターURLはuser.avatar_urlから取得され、img要素のsrc属性として使用される
- ロゴURLはCMS設定から取得されるため、管理者が制御する値である
- ログアウト機能はSettingsDropdown経由で提供される

## 備考

- logoUrlプロパティは非推奨（Deprecated）であり、logo.srcに置換される予定
- ヘッダーの最小幅は800px、最大幅は1440pxに設定されている
- ヘッダーの高さはlengths.topBarHeight（56px）で統一されている
- Headerコンポーネントはconnect(null, mapDispatchToProps)とtranslate()でラップされている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Header.js | `packages/decap-cms-core/src/components/App/Header.js` | propTypesの定義でコンポーネントが受け取るデータ構造を理解する |

**読解のコツ**: ImmutablePropTypes.mapで定義されているcollectionsはImmutable.jsのMapオブジェクトである。get()メソッドでプロパティアクセスする点に注意。

**主要処理フロー**:
- **131-147行目**: propTypes定義。user, collections, onCreateEntryClick, onLogoutClick, openMediaLibrary, hasWorkflow, displayUrl, logoUrl, logo, isTestRepo, t, checkBackendStatus

#### Step 2: ライフサイクルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Header.js | `packages/decap-cms-core/src/components/App/Header.js` | componentDidMount/componentWillUnmountでのバックエンド監視タイマー管理 |

**主要処理フロー**:
- **151-158行目**: componentDidMount - PropTypesの手動検証と5分間隔のcheckBackendStatus設定
- **160-162行目**: componentWillUnmount - setIntervalのクリーンアップ
- **164-169行目**: handleCreatePostClick - onCreateEntryClickにcollectionNameを渡す

#### Step 3: レンダリングロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Header.js | `packages/decap-cms-core/src/components/App/Header.js` | render()メソッドの条件分岐とコンポーネント構成 |

**主要処理フロー**:
- **186-188行目**: creatableCollections - collection.get('create')でフィルタリング
- **190行目**: shouldShowLogo - logo.show_in_headerとlogo.srcの両方がtruthyの場合
- **196-228行目**: ナビゲーションリスト（ロゴ、コンテンツリンク、ワークフローリンク、メディアボタン）
- **203-210行目**: コンテンツリンク - NavLinkのisActiveでpathname判定
- **212-218行目**: ワークフローリンク - hasWorkflow条件付き
- **220-227行目**: メディアボタン - showMediaButton条件付き
- **230-248行目**: アクション領域（Quick Addドロップダウン、SettingsDropdown）
- **262-264行目**: mapDispatchToProps - checkBackendStatusのバインド
- **266行目**: connect(null, mapDispatchToProps)(translate()(Header)) - HOCでラップ

#### Step 4: スタイル定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Header.js | `packages/decap-cms-core/src/components/App/Header.js` | styled-componentsによるレイアウト定義 |

**主要処理フロー**:
- **30-45行目**: AppHeader - position: sticky、z-index: 300、高さ56px
- **47-54行目**: AppHeaderContent - flexbox、min-width: 800px、max-width: 1440px
- **56-91行目**: AppHeaderButton - ナビゲーションボタンスタイル。ホバー/アクティブ時のカラー変更
- **93行目**: AppHeaderNavLink - AppHeaderButtonをNavLinkに変換

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

```
App.js
    |
    +-- Header.js (connect + translate HOC)
            |
            +-- AppHeader (styled header)
            |       +-- AppHeaderContent (styled div)
            |               +-- nav > AppHeaderNavList (styled ul)
            |               |       +-- AppHeaderLogo (条件付き img)
            |               |       +-- AppHeaderNavLink ("/" コンテンツ)
            |               |       +-- AppHeaderNavLink ("/workflow" 条件付き)
            |               |       +-- AppHeaderButton (メディア 条件付き)
            |               |
            |               +-- AppHeaderActions (styled div)
            |                       +-- Dropdown (Quick Add 条件付き)
            |                       |       +-- AppHeaderQuickNewButton
            |                       |       +-- DropdownItem (creatableCollections)
            |                       |
            |                       +-- SettingsDropdown
            |
            +-- checkBackendStatus (5分間隔)
```

### データフロー図

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

Redux store                -->  Header コンポーネント           -->  ヘッダーDOM
  (collections, user,            |
   hasWorkflow, displayUrl)      +-- creatableCollections        -->  Quick Add ドロップダウン
                                 |    フィルタリング
config.yml                 -->   +-- logo 表示判定               -->  ロゴ画像
  (logo, display_url)            |
                                 +-- 5分間隔                     -->  checkBackendStatus
                                      タイマー                        API呼び出し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Header.js | `packages/decap-cms-core/src/components/App/Header.js` | ソース | ヘッダーメインコンポーネント |
| status.ts | `packages/decap-cms-core/src/actions/status.ts` | ソース | checkBackendStatusアクション |
| SettingsDropdown | `packages/decap-cms-core/src/components/UI/SettingsDropdown.js` | ソース | 設定ドロップダウンコンポーネント |
| App.js | `packages/decap-cms-core/src/components/App/App.js` | ソース | Headerコンポーネントの配置先 |
| styles.js | `packages/decap-cms-ui-default/src/styles.js` | ソース | colors, lengths, shadows等のスタイル定数 |
| Icon.js | `packages/decap-cms-ui-default/src/Icon.js` | ソース | アイコンコンポーネント |
| Dropdown.js | `packages/decap-cms-ui-default/src/Dropdown.js` | ソース | ドロップダウンコンポーネント |
