# 通知設計書 23-エクスポート無効通知

## 概要

本ドキュメントは、Etherpadにおいて特定のファイル形式（PDF、Microsoft Word、OpenDocument）へのエクスポートが無効化されている場合に表示される通知の設計について記載する。

### 本通知の処理概要

この通知は、ユーザーが無効化されているファイル形式でエクスポートしようとした際に、alertダイアログとして表示されるメッセージである。サーバー設定でAbiWordまたはLibreOfficeが未設定の場合、特定の形式へのエクスポートリンクが無効化され、クリック時に本通知が表示される。

**業務上の目的・背景**：PDF、Microsoft Word、OpenDocument形式へのエクスポートには、サーバーにAbiWordまたはLibreOfficeがインストールされている必要がある。これらのツールが未設定の場合、ユーザーに対して明確なエラーメッセージを表示し、システム管理者への問い合わせを促すことで、ユーザーの混乱を防ぎ、適切な対応へ導く。

**通知の送信タイミング**：ユーザーが無効化されたエクスポートリンク（disabledexportクラスが付与されたリンク）をクリックした時点で、クライアントサイドのJavaScriptによって即座に表示される。

**通知の受信者**：エクスポートリンクをクリックしたブラウザセッションのユーザー。操作を行った本人のみが受信する。

**通知内容の概要**：「{形式名}としてエクスポートすることは無効化されています。詳細については、システム管理者に連絡してください。」という趣旨のメッセージが表示される。

**期待されるアクション**：ユーザーは代替のエクスポート形式（HTML、プレーンテキスト、Etherpad形式）を使用するか、システム管理者に連絡してPDF/Word/ODFエクスポート機能の有効化を依頼することが期待される。

## 通知種別

アプリ内通知（alertダイアログ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（クライアントサイド処理） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

エクスポートリンクをクリックしたユーザーに対してのみ、ブラウザのalertダイアログとして表示する。完全にクライアントサイドで処理される。

## 通知テンプレート

### アラートダイアログ

| 項目 | 内容 |
|-----|------|
| 表示方式 | ブラウザのalert()ダイアログ |
| ブロッキング | あり（ユーザーがOKを押すまで） |

### 本文テンプレート

```
Exporting as {{type}} format is disabled. Please contact your system administrator for details.
```

日本語（参考）:
```
{{type}}形式でのエクスポートは無効化されています。詳細については、システム管理者に連絡してください。
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | エクスポート形式名（PDF/Microsoft Word/OpenDocument） | クリックされたリンクのクラス名から判定 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | エクスポートリンクのクリック | リンクにdisabledexportクラスが付与されている | 無効化されたエクスポート形式のリンククリック |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| clientVars.exportAvailable !== 'no' | サーバーでエクスポートが有効な場合はリンクが有効になる |
| clientVars.exportAvailable === 'withoutPDF' | PDFのみ無効、Word/ODFは有効 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[pad_impexp.init実行] --> B{clientVars.exportAvailable?}
    B -->|'no'| C[Word/PDF/ODFリンクを削除]
    B -->|'withoutPDF'| D[PDFリンクのみ削除]
    B -->|それ以外| E[全形式エクスポート有効]
    C --> F[disabledexportクラスのリンクにイベント設定]
    D --> F
    F --> G[ユーザーが無効リンクをクリック]
    G --> H[cantExport関数呼び出し]
    H --> I[リンクのクラスからエクスポート形式を判定]
    I --> J[html10n.getでメッセージ取得]
    J --> K[alertダイアログ表示]
    K --> L[return falseでリンク遷移を防止]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（クライアントサイドのみの処理）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| エクスポート無効 | AbiWord/LibreOffice未設定 | alertメッセージを表示しリンク遷移を防止 |

### リトライ仕様

該当なし

## 配信設定

### レート制限

該当なし（クライアントサイド処理のため）

### 配信時間帯

制限なし（24時間対応）

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

- alertメッセージには機密情報を含まない
- エクスポートが無効な理由（サーバー設定）の詳細は表示しない
- クロスサイトスクリプティング対策としてメッセージはhtml10nライブラリで処理される

## 備考

- exportAvailableの値はサーバーからclientVarsとして送信される
- 'no': AbiWord/LibreOffice両方とも未設定
- 'withoutPDF': LibreOfficeが設定されているがPDF出力が無効
- それ以外: 全形式エクスポート可能
- 常に利用可能な形式: HTML、プレーンテキスト、Etherpad

---

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

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

### 推奨読解順序

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

クライアント変数（clientVars）とエクスポート可否の判定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pad_impexp.ts | `src/static/js/pad_impexp.ts` | clientVars.exportAvailableの値によるリンク制御（148-166行目） |

**読解のコツ**: exportAvailableの3つの値（'no', 'withoutPDF', その他）によって異なるリンク構成を確認する。

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

エクスポート無効通知のトリガーとなる処理を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pad_impexp.ts | `src/static/js/pad_impexp.ts` | init関数（129-172行目）でエクスポートリンクの設定 |
| 2-2 | pad_impexp.ts | `src/static/js/pad_impexp.ts` | cantExport関数（112-125行目）でアラート表示 |

**主要処理フロー**:
1. **148-166行目**: clientVars.exportAvailableの値に応じてリンクを削除または設定
2. **171行目**: disabledexportクラスにcantExportイベントを設定
3. **112-125行目**: cantExport関数でクリックされたリンクの種類を判定しアラート表示

#### Step 3: 通知表示ロジックを理解する

メッセージの生成と表示処理を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pad_impexp.ts | `src/static/js/pad_impexp.ts` | cantExport関数（112-125行目） |

**主要処理フロー**:
- **112-113行目**: クリックされた要素を取得
- **114-122行目**: クラス名からエクスポート形式を判定（PDF/Word/ODF）
- **123行目**: html10n.getでローカライズされたメッセージを取得しalert表示
- **124行目**: return falseでデフォルト動作（リンク遷移）を防止

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

```
[Client] pad_impexp.ts
    │
    ├─ init() [129行目]
    │      │
    │      ├─ clientVars.exportAvailable チェック [148行目]
    │      │      │
    │      │      ├─ 'no' → Word/PDF/ODFリンクを削除 [149-151行目]
    │      │      │
    │      │      └─ 'withoutPDF' → PDFリンクを削除 [154-155行目]
    │      │
    │      └─ $('.disabledexport').on('click', cantExport) [171行目]
    │
    └─ cantExport() [112行目]
           │
           ├─ リンククラスからエクスポート形式を判定 [114-122行目]
           │
           ├─ html10n.get('pad.impexp.exportdisabled', {type}) [123行目]
           │
           └─ alert() + return false [123-124行目]
```

### データフロー図

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

clientVars.exportAvailable ───▶ init() ───▶ リンク有効/無効設定
                                    │
                                    ▼
ユーザークリック ───────────▶ cantExport() ───▶ alertダイアログ
                                    │
                                    ├─ クラス名判定
                                    │
                                    ├─ html10n.get()
                                    │
                                    └─ alert()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pad_impexp.ts | `src/static/js/pad_impexp.ts` | ソース | エクスポート/インポート機能とUI制御 |
| en.json | `src/locales/en.json` | 設定 | 国際化メッセージ定義（208行目: pad.impexp.exportdisabled） |
| html10n.ts | `src/static/js/vendors/html10n.ts` | ソース | 国際化ライブラリ |
| Settings.ts | `src/node/utils/Settings.ts` | ソース | abiword/soffice設定の読み込み |
