操作
機能 #291
未完了WebUI連携: テンプレート選択機能のRedmine UI統合
ステータス:
新規
優先度:
通常
担当者:
-
開始日:
2025-06-06
期日:
進捗率:
0%
予定工数:
説明
開発タスク起票テンプレート¶
1. 前回開発進捗確認¶
- 関連チケット番号:#287(MCPツール改修: チケット起票テンプレート機能の実装)
- 前回の達成状況:コマンドラインからのテンプレート機能実装完了
- 残された課題:WebUI連携機能の実装
2. 切り戻し準備¶
- 最新バックアップ日時:2025-06-07 00:42:00
- バックアップ場所:/root/redmine-mcp (feature/ticket-templates ブランチ)
- 復元手順の確認:完了 [x]
3. ゴール確認¶
- 実装する機能:RedmineのWebUIからテンプレートを選択してチケットを作成する機能
- 期待される成果:
- Webブラウザからのテンプレート選択と適用
- 直感的なインターフェースによる作業効率向上
- 完了条件:RedmineのWebUIでチケット作成時にテンプレートを選択できるようになる
4. 前提確認¶
インフラ構成¶
- VPS-root構成状態:Ubuntu 24.04.2 LTS
- 動作中コンテナ:redmine-mcp, redmine-prod
- ネットワーク構成:DockerCompose+Nginx+SNI方式のマルチドメイン
バージョン管理¶
- Gitリポジトリ:/root/redmine-mcp
- ブランチ戦略:feature/ticket-templates から feature/template-webui に分岐
- 現在のブランチ:feature/ticket-templates
関連リソース¶
5. 開発方針¶
- アプローチ方法:
- RedmineのWebUIにテンプレート選択機能を追加
- テンプレート選択時に内容をフォームに自動挿入する機能を実装
- 使用技術・フレームワーク:
- JavaScript
- jQuery
- Redmine API
- 開発環境構築手順:
- feature/ticket-templates ブランチをベースに新ブランチを作成
- RedmineのWebインターフェース拡張用のJavaScriptを開発
6. 設計¶
機能設計¶
- 実装する機能の詳細:
- チケット作成画面にテンプレート選択ドロップダウンを追加
- テンプレート選択時に内容を説明フィールドに自動挿入
- テンプレート一覧を取得するAPIエンドポイントの実装
- 処理フロー:
- ユーザーがチケット作成画面を開く
- テンプレート一覧を取得して選択肢として表示
- テンプレートを選択すると内容が自動挿入される
関数定義¶
関数名:loadTemplates
入力:なし
出力:テンプレート一覧
処理内容:利用可能なテンプレート一覧をAPIから取得
関数名:applyTemplate
入力:テンプレートID
出力:なし
処理内容:選択されたテンプレートをチケットの説明フィールドに適用
データベース¶
- テーブル定義:変更なし
- スキーマ変更:なし
7. 詳細設計¶
- 実装方法:
- テンプレート一覧を提供するAPIエンドポイントの実装
- チケット作成フォームを拡張するJavaScriptの開発
- 対象ファイル:
- /root/redmine-mcp/mcp-redmine/webui/template-selector.js
- /root/redmine-mcp/mcp-redmine/webui/api-endpoint.rb
- 作成・更新箇所:
- 新規ファイルの作成
- Redmine設定へのJavaScriptインクルード追加
- コード構造:
- API:テンプレート一覧取得とテンプレート内容取得
- JavaScript:UI要素の追加と選択イベントの処理
8. 試験仕様¶
- ユースケース:
- WebUIからチケット作成画面を開く
- テンプレートを選択して内容が自動挿入されることを確認
- テストデータ:
- 既存のテンプレートファイル
- テストパターン:
- 各テンプレートを選択して正しく内容が挿入されることを確認
- テンプレート未選択時の動作確認
- 異なるブラウザでの動作確認
- 実施方法:
- Redmine WebUIでの手動テスト
- 異なるブラウザ環境でのテスト
- 期待結果:
- テンプレート選択UIが表示される
- テンプレート選択時に内容が自動挿入される
- クロスブラウザで動作する
9. デプロイ方法¶
- デプロイ手順:
- 開発したJavaScriptとAPI実装をデプロイ
- Redmine設定にJavaScriptを追加
- サービスを再起動
- 必要な環境変更:Redmine設定の更新
- ロールバック手順:
- JavaScriptの追加設定を削除
- サービスを再起動
10. 成果物と残課題¶
- 作成する成果物リスト:
- template-selector.js
- api-endpoint.rb
- 設定手順書
- 仕様書更新箇所:README.mdにWebUI機能の説明を追加
- 残課題と対応方法:
- テンプレート編集機能(別チケットで対応)
- 次タスクの開発指示:
- テンプレートカスタマイズ機能の開発
タスク管理¶
- 担当者:システム管理者
- 優先度:中
- 開始予定日:2025-06-15
- 完了予定日:2025-06-20
- 工数見積:3人日
コミュニケーション¶
- 進捗報告方法:Redmineチケットへのコメント
- レビュアー:開発チーム
- 関係者:開発チーム全員、エンドユーザー
Redmine Admin さんが1日前に更新
作業指示:WebUI連携機能の実装¶
RedmineのWebUIからテンプレートを選択してチケットを作成する機能を実装する作業を進めてください。この作業は、テンプレート拡充作業(#290)の完了後に開始することを推奨します。
前提条件¶
- 基本的なテンプレート機能の実装(#287)が完了していること
- テンプレート拡充(#290)が完了していること
- RedmineのWebUI拡張の知識があること
作業手順¶
-
新ブランチの作成
cd /root/redmine-mcp git checkout feature/additional-templates # テンプレート拡充が完了した後のブランチ git pull git checkout -b feature/template-webui
-
テンプレート一覧取得APIの実装
-
/root/redmine-mcp/mcp-redmine/webui/api-endpoint.rb
ファイルを作成 - テンプレート一覧を取得するエンドポイントを実装
- テンプレート内容を取得するエンドポイントを実装
- ミドルウェアとしてSinatraまたはRackを使用することを検討
-
-
WebUI拡張用JavaScriptの作成
-
/root/redmine-mcp/mcp-redmine/webui/template-selector.js
ファイルを作成 - チケット作成画面を検出するロジックを実装
- テンプレート選択ドロップダウンを追加する機能を実装
- 選択したテンプレートを説明フィールドに挿入する機能を実装
- jQuery互換性を確保(Redmineで使用されているため)
-
-
Redmine設定への統合
- RedmineのカスタムJavaScriptを追加する設定を行う
-
/root/redmine-prod/config/additional_environment.rb
または同等の設定ファイルを修正 - または、プラグインとして実装することも検討
-
デプロイスクリプトの作成
-
/root/redmine-mcp/mcp-redmine/webui/deploy.sh
スクリプトを作成 - APIエンドポイントのセットアップ
- JavaScriptファイルのデプロイ
- 必要な設定変更の自動化
-
-
READMEの更新
-
/root/redmine-mcp/mcp-redmine/README.md
を更新し、WebUI機能の説明と使用方法を追加
-
-
テスト
- 異なるブラウザ(Chrome, Firefox, Safari)でのテスト
- テンプレート選択と適用が正常に動作することを確認
- エラー処理が適切に機能することを確認
-
変更のコミット
git add . git commit -m 'WebUI連携: テンプレート選択機能のRedmine UI統合 (#291)' git push origin feature/template-webui
実装のポイント¶
- 非侵襲的な実装: Redmineのコアコードを変更せず、JavaScriptによる拡張に留める
- 互換性: 既存のRedmine機能と干渉しないようにする
- ユーザー体験: 直感的で使いやすいインターフェースを設計する
- エラー処理: ネットワークエラーや例外を適切に処理する
- パフォーマンス: テンプレート読み込みが高速であることを確認する
WebUI実装の技術的アプローチ¶
APIエンドポイント実装例¶
# api-endpoint.rb
require 'sinatra'
require 'json'
require 'yaml'
set :bind, '0.0.0.0'
set :port, 3010
# テンプレートディレクトリの設定
TEMPLATE_DIR = '/path/to/templates'
# CORSヘッダー設定
before do
content_type :json
headers 'Access-Control-Allow-Origin' => '*'
headers 'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS'
end
# テンプレート一覧を取得
get '/templates' do
templates = Dir.glob(File.join(TEMPLATE_DIR, '*.md')).map do |file|
name = File.basename(file)
description = File.open(file, 'r:utf-8') { |f| f.readline.strip rescue "説明なし" }
{ id: name, name: name, description: description.gsub(/^#\s*/, '') }
end
JSON.generate(templates)
end
# テンプレート内容を取得
get '/templates/:id' do
template_path = File.join(TEMPLATE_DIR, params[:id])
if File.exist?(template_path)
content = File.read(template_path, encoding: 'utf-8')
JSON.generate({ id: params[:id], content: content })
else
status 404
JSON.generate({ error: "Template not found" })
end
end
フロントエンド実装例¶
// template-selector.js
$(document).ready(function() {
// チケット作成/編集画面かどうかを確認
if ($('form#issue-form').length > 0) {
// テンプレート選択UIを追加
addTemplateSelector();
// テンプレート一覧を取得
loadTemplates();
}
});
// テンプレート選択UIの追加
function addTemplateSelector() {
const selectorHtml = `
<div class="template-selector">
<label for="template-select">テンプレートを選択:</label>
<select id="template-select">
<option value="">-- テンプレートを選択 --</option>
</select>
<button type="button" id="apply-template">適用</button>
</div>
`;
// 説明フィールドの前に挿入
$('#issue_description_and_toolbar').before(selectorHtml);
// 適用ボタンのイベントハンドラを設定
$('#apply-template').click(function() {
const templateId = $('#template-select').val();
if (templateId) {
applyTemplate(templateId);
}
});
}
// テンプレート一覧の取得
function loadTemplates() {
$.getJSON('http://localhost:3010/templates', function(data) {
const select = $('#template-select');
// テンプレート一覧をドロップダウンに追加
data.forEach(function(template) {
select.append(`<option value="${template.id}">${template.name}: ${template.description}</option>`);
});
}).fail(function(error) {
console.error('テンプレート一覧の取得に失敗しました', error);
});
}
// テンプレートの適用
function applyTemplate(templateId) {
$.getJSON(`http://localhost:3010/templates/${templateId}`, function(data) {
// 説明フィールドにテンプレート内容を設定
$('#issue_description').val(data.content);
}).fail(function(error) {
console.error('テンプレートの取得に失敗しました', error);
});
}
完了条件¶
- WebUIからテンプレートを選択・適用できる
- すべてのテンプレートが正しく表示・適用される
- 複数のブラウザで正常に動作する
- エラー処理が適切に実装されている
- READMEに使用方法が記載されている
- 変更がGitにコミットされている
注意事項¶
- Redmineの既存機能と干渉しないように注意する
- セキュリティを考慮してAPIアクセス制限を実装する
- ブラウザの互換性を確保する
- ユーザー体験を考慮した設計にする
完了したら、このチケットにコメントを追加し、スクリーンショットなどを含めて報告してください。
操作