Redmineのプラグイン「view customize plugin」のカスタマイズ例

# はじめに

Redmineのプラグイン「view customize plugin」について、
自チームで利用している設定例を紹介します。

カスタマイズ性の高いプラグインなのでアイデア次第で様々なことが可能になります。
このページの設定例をそのまま利用するだけでなく、
「あれもできるかも？」と考えてどんどん応用してみてください。

# view customize plugin

Redmineの画面にCSS/Javascriptを差し込んでカスタマイズするプラグインです。
詳細な内容やインストール方法は作者ページをご覧ください。

ブログ紹介ページ
http://blog.enjoyxstudy.com/entry/2014/06/30/003443
github
https://github.com/onozaty/redmine-view-customize

# 動作環境

以下の環境で動作検証を行っています。

## サーバ

- Windows 10
- bitnami-redmine-3.2.2-0

## クライアント

- Windows 10
- Chrome 50

# 設定例

## 一覧

- 入力欄拡大
- 検索ボックスの結果を新しいウインドウで開く
- チケット編集時のエンターキー誤送信防止
- チケット作成時のカスタマイズ
- チケットコピー時のカスタマイズ
- ステータス変更と連動して進捗率を変更
- 終了したバージョンを非表示にする

## 入力欄拡大

プラグインのコード入力欄を拡大しています。

```css
/*
「view costomize plugin」のコード入力欄拡大
Path pattern: /view_customizes/*
Type: StyleSheet
*/
#view_customize_code {
	height: 400px;
}
```

## 検索ボックスの結果を新しいウインドウで開く

タイトルそのままです。
ふと検索したいと思ったときに現在のページを残したい場合が多いため愛用しています。
チームには受け入れられなかったのでプライベートで運用しています。

```javascript
/*
検索ボックスの結果を新しいウインドウで開く
Path pattern: .*
Type: JavaScript
*/
$(function(){

	$('#quick-search form').attr('target', '_blank');
});
```

## チケット編集時のエンターキー誤送信防止

チケット編集時のテキストボックス上で、エンターキーでのSubmitをキャンセルしています。
地味に「開始日」などでも発生するため、全てのテキストボックスを対象としています。

トラッカー操作時にDOMが書き換わり、設定したイベントが破棄されてしまう問題があったため、
「document」へのイベント設定としました。
※プラグイン作者様に教えていただきました。

```javascript
/*
チケット編集時のエンターキー誤送信防止
Path pattern: /issues
Type: JavaScript
*/
$(function(){

	// form内のエンターキー入力を無視
	// トラッカー・ステータス操作時のDOM操作で破棄されないようdocumentにイベントを設定
	$(document).on('keypress', '#issue-form input[type="text"]', function(event) {
		if(event.keyCode == 13) {
			return false;
		}
	});
});
```

## チケット作成時のカスタマイズ

チケット作成時に以下を実行しています。

- トラッカーの初期値を変更
- 担当者に「自分」を設定

※トラッカー設定時に「val()」でうまくいかなかったため違うやり方にしています。
もっとスマートな解決方法があれば教えてください。

```javascript
/*
チケット作成時のカスタマイズ
Path pattern: /issues/new$
Type: JavaScript
*/
$(function(){

	// トラッカー変更
	// val()ではうまくいかない。プルダウン変更時のイベントが関係している？
	// 2行目の「value=?」部分でカスタマイズ
	$('#issue_tracker_id option').removeAttr('selected');
	$('#issue_tracker_id option[value=6]').attr('selected', true).trigger('change');

	// 担当者　⇒　自分
	$('#issue_assigned_to_id option:contains("自分")').attr('selected', true);

});
```

## チケットコピー時のカスタマイズ

チケットコピー時に以下を実行しています。

- ステータスを「新規」に変更
- 開始日に「当日」を入力
- 完了日をクリア
- 進捗率を「クリア
- 「添付ファイルをコピー」のチェックを外す
- 「チケットのウォッチャー」の全てにチェックを入れる

新規作成時とは違い、プロジェクトごとの個性が出る部分です。
コピー時のURLには「プロジェクトID」が含まれているため、
それをパターンやif条件に使えばさらに細かいカスタマイズが可能です。

```javascript
/*
チケットコピー時のカスタマイズ
Path pattern: /issues/[0-9]+/copy$
Type: JavaScript
*/
$(function(){

	// ステータス　⇒　新規
	// val()ではうまくいかない。プルダウン変更時のイベントが関係している？
	$('#issue_status_id option').removeAttr('selected');
	$('#issue_status_id option[value=1]').attr('selected', true).trigger('change');

	// 開始日　⇒　今日
	$('#issue_start_date').val(getToday());
	// 完了日
	$('#issue_due_date').val('');
	// 進捗率
	$('#issue_done_ratio').val('0');

	// 添付ファイルをコピー　⇒　チェックを外す
	$('#copy_attachments').removeAttr('checked');
	// チケットのウォッチャー　⇒　すべてチェックを入れる
	$('#watchers_inputs input[type=checkbox]').attr('checked', true);

});

/* 当日文字列を習得　「YYYY-MM-DD」 */
function getToday() {

	var now = new Date();
	return yyyymmdd = now.getFullYear() + '-' +
		( "0"+(now.getMonth() + 1)).slice(-2) + '-' +
		( "0"+now.getDate() ).slice(-2);
}
```

## ステータス変更と連動して進捗率を変更

チケットステータス変更と連動して進捗率を変更しています。

- 新規　⇒　0
- 終了　⇒　100
- 却下　⇒　100

終了・却下時の進捗率更新忘れ対策です。

```javascript
/*
ステータス変更と連動して進捗率を変更
Path pattern: /issues/[0-9]+
Type: JavaScript
*/
$(function(){

	// ステータス変更後のajaxイベント終了後
	$(document).ajaxComplete(function(){
		// ステータスと進捗率の組み合わせ
		var statusMap = {
				'1' : '0',	/* 新規 */
				'5' : '100',	/* 終了 */
				'6' : '100'	/* 却下 */
		};
		var ratio = statusMap[$('#issue_status_id option:selected').val()];
		if(ratio) {
			$('#issue_done_ratio').val(ratio);
		}
	});
});
```

## 終了したバージョンを非表示にする

「設定タブ⇒バージョンタブ」のバージョン一覧から終了したバージョンを非表示にしています。
デフォルトでは非表示にしたうえで、全表示もできるようにしています。

「期日」の昇順で表示されるため、終了済過去バージョンが画面を占有してしまう問題への対策です。![redmine_version_toggle.gif](https://qiita-image-store.s3.amazonaws.com/0/45370/544a3639-0401-6fd9-400f-2dd28d61f1c7.gif)

```javascript
/*
設定画面のバージョンタブで終了したバージョンの表示・非表示を切り替えるリンク追加
Path pattern: /projects/[\S]+/settings/*
Type: JavaScript
*/
// 定数定義
var showAllStr = '全て表示';
var hideEndStr = '進行中のみ表示';
var versionContentSelector = '#tab-content-versions';

// メイン処理
$(function(){
	// リンク文字列作成
	var toggleLink = '<a href="#" onclick="javascript:toggleVersions(this);">' +
		'<span class="icon icon-checked">' + showAllStr + '</a>';
	// バージョン情報テーブル上部にリンク挿入
	$(versionContentSelector).prepend(toggleLink);
	// 初期状態として非表示にする
	hideEndVersions();
});

// 現在の状態に応じて表示・非表示を切り替える
function toggleVersions(content) {
	$(function(){
		// リンク文字列を比較して状態を判定する
		if($(content).text() == showAllStr) {
			// 非表示　⇒　表示
			showAllVersions();
			$(content).children().first().text(hideEndStr);
		} else {
			// 表示　⇒　非表示
			hideEndVersions();
			$(content).children().first().text(showAllStr);
		}
	});
}

// 非表示にする
function hideEndVersions() {
	$(function(){
		// 終了したバージョンは「closed」クラスが付与されている
		$(versionContentSelector).find('table tbody tr.closed').hide();
	});
}

// 全て表示する
function showAllVersions() {
	$(function(){
		$(versionContentSelector).find('table tbody tr').show();
	});
}
```

# その他カスタマイズ例

プラグイン作者のgithubやスライドでカスタマイズ例が公開されています。

github
https://github.com/onozaty/redmine-view-customize-scripts
スライド
http://www.slideshare.net/onozaty/view-customize-plugin