Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Redmineの画面をあなた好みにカスタマイズ - View customize plugin...
Search
onozaty
September 18, 2020
0
370
Redmineの画面をあなた好みにカスタマイズ - View customize pluginの紹介 - Redmine Japan 2020
Redmine Japan 2020 での発表資料です。
onozaty
September 18, 2020
Tweet
Share
More Decks by onozaty
See All by onozaty
リモートワーク中に買って良かったものベスト3
onozaty
0
180
情報を表現するときのポイント
onozaty
0
22
チームで開発するための環境を整える
onozaty
1
200
Selenium入門(2023年版)
onozaty
1
170
40歳過ぎてもエンジニアでいるためにやっていること
onozaty
0
55
Java8から17へ
onozaty
0
18
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
0
190
Redmine issue assign notice plugin の紹介
onozaty
0
160
最近作ったもの
onozaty
0
26
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
299
21k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.6k
Navigating Team Friction
lara
187
15k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
Typedesign – Prime Four
hannesfritz
42
2.7k
Making Projects Easy
brettharned
116
6.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Fireside Chat
paigeccino
37
3.5k
Agile that works and the tools we love
rasmusluckow
329
21k
The World Runs on Bad Software
bkeepers
PRO
70
11k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
Optimizing for Happiness
mojombo
379
70k
Transcript
Redmineの画面を あなた好みにカスタマイズ - View customize pluginの紹介 - 2020-09-18 Redmine Japan
2020 [B07] @onozaty
自己紹介 • Hirokazu Onozato • 株式会社ユニスティ所属 • ソフトウエア開発者 • プログラムを書くのが好き
• 個人でChrome/Firefoxの拡張機能や、ちょっとしたツールなど 作って公開 @onozaty https://github.com/onozaty
Redmineとの関わり • Redmine歴は11年くらい • 主にアプリケーション開発のタスク管理に利用 • Redmineに関連して作ったもの (今もメンテナンスしているもの) • View
customize plugin https://github.com/onozaty/redmine-view-customize • 本日詳しく紹介 • Redmine issue loader https://github.com/onozaty/redmine-issue-loader • CSVを読み込んでRedmineにチケットとして取り込む(新規、更新)するため のツール
View customize plugin
View customize plugin • Redmineの画面をカスタマイズするためのPlugin • 特定の画面に対して、JavaScript、CSSを埋め込む機能を提供 • ブラウザのUserScriptを、クライアントではなくサーバ側で設定し て、Redmineを使用する全ユーザに適用するイメージ
• 再起動不要で、手軽にRedmineをカスタマイズできる
できること • JavaScriptとCSSを埋め込んで実行できるので、画面上に存在する情 報で完結することはたいていできる • 画面上に存在しない情報(ユーザのカスタムフィールドやAPIキーな ど)にアクセスする方法もプラグインとして提供しているので、それ らを組み合わせると、出来ることの幅はさらに広がる
例
例:バナーを表示
例:プロジェクトによってヘッダの色を切り替え
例:チケット一覧を装飾 適用前 適用後
例:カスタムフィールドを連動 適用前 適用後
例:子チケット作成時に親チケットの情報を引き継ぐ
例:担当者の選択でインクリメンタルサーチ 適用前 適用後
例:複数の子チケットをまとめて作成
使い方
インストール方法 • Redmineのpluginsディレクトリにファイルを配置して、bundle installとmigrateを実施して、Redmineを再起動 • ディレクトリ名は view_customize としてください cd {RAILS_ROOT}/plugins
git clone https://github.com/onozaty/redmine-view-customize.git view_customize cd ../ bundle install --without development test bundle exec rake redmine:plugins:migrate RAILS_ENV=production インストールがうまくいかなかったという問い合わせの 大半はこれが原因
設定方法 管理 > 表示のカスタマイズ > 新しい表示のカスタマイズ で新規設定へ
設定方法 実行対象の指定 実行するコード その他 設定画面
設定画面:実行対象の指定 • パス(URL)とプロジェクト(識別子)を正規表現で入力することで、実 行対象とする画面を絞る ※プロジェクトは v2.7.0 から • コードの挿入位置を下記から選択 •
全ページのヘッダ • チケット入力欄の下 • チケット詳細の下
設定画面:実行するコード • 種別は下記から選択 (種別によってコードの埋め込まれ方が変わる) • JavaScript (scriptタグで埋め込まれる) • CSS (styleタグで埋め込まれる)
• HTML (そのままの状態で埋め込まれる) ※v2.1.0から
設定画面:その他 • コメントは一覧上で表示される • 設定内容を表すものを入れておくことで、識別しやすくなる • 有効のチェックを外すと、設定を無効にできる • プライベートにチェックすると、作成者のみに適用できる
実行 実行対象にコードが 埋め込まれて実行
設定内容と実行結果の例 (JavaScript) チケット入力欄でステータスとして却下を 選んだ時に、期日が未入力ならば現在日を 期日として入れるように設定
設定内容と実行結果の例 (CSS) プロジェクトaの場合に、ヘッダとトップ メニューの色が緑になるように設定
設定に関するノウハウ
実行対象の絞り込み方
実行対象の絞り込み方:挿入位置 まずは挿入位置で対象を絞り込めるか考える • 全ページのヘッダ • すべての画面が対象になる • チケット入力欄の下 • チケット新規作成画面、チケット表示・編集画面が対象になる
• チケット入力欄は、トラッカーやステータスを変えた際に再構築されるが、 再構築の際にも再度挿入される • チケット詳細の下 • チケット表示・編集画面が対象になる
実行対象の絞り込み方:パスパターン 挿入位置だけで絞り込めない場合、パスを正規表現で指定することで、 さらに絞り込みを行う • URLでアプリケーション配下かつクエリパラメータを含まない部分 がパス • http://192.168.33.41/redmine/projects/a/issues?xxx=xx -> /projects/a/issues
• View customizeでHTMLにパスをコメントとして埋め込んでいるの で、ブラウザのソース表示でみれば、その画面のパスが確認できる
実行対象の絞り込み方:パスパターンの指定例 パスパターン 一致する画面 /issues$ チケット一覧 /issues/new$ チケットの新規作成画面 /issues/[0-9]+/copy$ チケットのコピーによる作成画面 /issues/gantt
ガントチャート /projects$ プロジェクト一覧 /projects/.+/wiki Wiki v2.7.0 からパスパターンは任意となったため、パスパターンで絞り 込みたくない場合に .* を入れる必要が無くなった .*[]+$ といった文字は、正規表現におけるメタ文字(特殊な意味をもった文字)
実行対象の絞り込み方:プロジェクトパターン 特定のプロジェクトのみで適用したい場合に、プロジェクト識別子を 正規表現で指定する ※v2.7.0 にて追加 • チケット表示画面だと、パスにプロジェクトの情報が入らないので、 v2.7.0より前だとJavaScriptのコードとして判断する必要があった • プロジェクト識別子は、プロジェクト配下の画面にアクセスすると、
URLからわかる URLが /projects/a なので、 プロジェクト識別子は a
CSSセレクタ
CSSセレクタ • CSSセレクタとは、CSSでスタイルを適用する対象を示すもの • CSSを書く場合だけでなく、JavaScriptで対象要素を操作するのにも、 CSSセレクタが重要 セレクタ名 書式 対象 型セレクタ
E E要素 idセレクタ E#myid id属性がmyidのE要素 classセレクタ E.warning class属性がwarinigのE要素 子孫セレクタ E F E要素の子孫にあたるF要素 子セレクタ E > F E要素の子にあたるF要素 (子孫セレクタは、E要素の配下ならば、どこにあって も良いが、子セレクタは、1階層下のみが対象) 【良く使うセレクタ】 ※セレクタは他にもいろいろあるので、詳しく知りたい方は「CSSセレクタ」で検索を
RedmineとCSSセレクタ • Redmineでは、必要となるような要素へのid、class属性が適切に振 られている • 入力項目となるような要素へはid属性 • body要素やチケット一覧には、内容を表すようなclass属性も付与
class属性 • body要素 • チケット一覧の各行 • project-{プロジェクト識別子} • controller-{コントローラ名} •
action-{アクション名} • tracker-{トラッカーID} • status-{ステータスID} • priority-{優先度ID} • created-by-me • assigned-to-me 参考:Redmineの画面で振られているclass属性について https://blog.enjoyxstudy.com/entry/2014/10/11/000000
ViewCustomize.context
ViewCustomize.context ユーザやプロジェクトの情報にJavaScriptで簡単にアクセスできるよう に、ViewCustomize.context というオブジェクトが用意されている 分類 項目 ユーザ ユーザID、ログインID、管理者かどうか、姓名、最終ログイン日時、グループ、 APIキー、カスタムフィールド プロジェクト
識別子、名前、ロール、カスタムフィールド チケット チケットID
ViewCustomize.context ViewCustomize = { "context": { "user": { "id": 1,
"login": "admin", "admin": true, "firstname": "Redmine", "lastname": "Admin", "lastLoginOn": "2019-09-22T14:44:53Z", "groups": [{"id": 5, "name": "Group1"}], "apiKey": "3dd35b5ad8456d90d21ef882f7aea651d367a9d8", "customFields": [{"id": 1, "name": "[Custom field] Text", "value": "text"}] }, "project": { "identifier": "project-a", "name": "Project A", "roles": [{"id": 6, "name": "RoleX"}], "customFields": [{"id": 4, "name": "[Project Custom field] Text", "value": "text"}] }, "issue": { "id": 1 } } }
例:カスタムフィールドを使った制御 • ユーザのカスタムフィールド(真偽値)によって、スクリプトの適用 可否を判断 • 管理者ではなく、ユーザ側に選択権を持たせることができる
例:カスタムフィールドを使った制御 $(function() { const isEnabled = ViewCustomize.context.user.customFields .some(function(customField) { //
チェックしたいカスタムフィールドのIDと値でチェック ("1"がtrue) return customField.id == 1 && customField.value == '1'; }); if (!isEnabled) { // 無効の場合は処理終了 return; } // 以降実際に実行したいスクリプト console.log('execute script.'); });
例: APIキーを使ってREST APIを呼び出し • ユーザのAPIキーを利用することで、Redmineの様々なREST APIを呼 び出し可能に • REST APIを使うと、各種情報の登録、更新なども行えるようになり、
自由度が高まる その分コードが複雑になっていくので、 ある程度覚悟を持ってやる必要あり
例: APIキーを使ってREST APIを呼び出し $.ajax({ type: 'PUT', url: '/issues/' + issueId
+ '.json', headers: { 'X-Redmine-API-Key': ViewCustomize.context.user.apiKey // APIキー取得 }, // 更新時はレスポンスのコンテンツが無く、jsonだとエラーとなるのでtextにしておく dataType: 'text', contentType: 'application/json', data: JSON.stringify({ 'issue': { 'parent_issue_id': '' // 親チケットIDをクリア } }) }) .done(function(data) { // 成功したらリロード location.reload(); }) .fail(function(data) { alert('失敗しました'); }); REST APIを使って親チケットをクリアする部分の例
APIキーに関する注意事項 • 設定画面より「RESTによるWebサービスを 有効にする」にチェック • これをしないと、REST API自体が使えない • 各自で個人設定からAPIアクセスキーを1度 表示しておく
• RedmineでのAPIキー払い出しが、最初に 表示したタイミングになっているため • これが面倒な場合は、プラグインの設定で「APIアクセスキーを自動的に作 成する」をチェックしておくと、自動的に作られるようになる
外部JavaScriptの読み込み
外部JavaScriptの読み込み • 種別としてHTMLを指定すると、HTMLをそのままで埋め込めるので、 外部JavaScriptの読み込みも簡単に指定できる • scriptタグのsrc属性で読み込むだけ • JavaScriptライブラリをCDNなどから読み込めば、やれることの幅 が広がる •
JavaScriptライブラリを読み込んで、テキストエリアでの入力補完を実装し た例 https://blog.enjoyxstudy.com/entry/2019/03/22/000000
外部JavaScriptの読み込み Redmine自体で既に使われているJavaScriptライブラリは、View customize側で読み込みをしなくても使える • jQuery • jQuery UI • Tribute.js
※4.1.0で追加された
ブラウザのDeveloper Toolの活用
ブラウザのDeveloper Toolの活用 いきなりView customizeでコードを書き始めるのではなく、ブラウザ のDeveloper Toolを使いながら、作成、確認をしていくと良い • 「DOMインスペクタ」を使って、変更したい箇所のHTML構造など を確認する •
「コンソール」上でコードを実行し、どういった結果になるか確認 • うまくいったら、View customizeとして設定する
DOMインスペクタ 選択した要素がHTML上でどういった構造になっているか確認できる ブラウザ上での選択箇所と Elementsパネルでの選択箇所が 連動することでHTMLの内容が 簡単に確認できる
コンソール 表示している画面でコードを実行し、動作を確認できる コードを入力し実行すると、 ブラウザ上にリアルタイムに 反映される
うまく動かないときの確認ポイント
対象画面の指定があっているか • ブラウザ上でソース表示して、View customizeで指定したコードが 埋め込まれているか確認 • 埋め込まれていない場合には、挿入位置、パス、プロジェクトパ ターンのいずれかが間違えている
JavaScriptでエラーが発生していないか • Developer Toolでエラーメッセージが出力されていないか確認 • エラーメッセージが出力されていれば、エラー内容を元に修正
スタイルが上書きされていないか • 複数のスタイルが一致する場合、その要素に対してどのスタイルが 適用されるかは、優先度によって決まる • より詳細に指定している方が優先 • 型セレクタよりidセレクタの方が優先など • セレクタのレベルが同じならば、後から書かれたものが優先
スタイルが上書きされていないか • Developer Toolで見ると、どういった優先度で適用されているかわ かる 取り消し線がついているもの は、優先度の高いスタイルに よって上書きされたもの
Redmineでの試し方
運用中のRedmine環境 • 運用中の環境で試す場合、いきなり全体に適用してしまうと想定通 りの動きをしなかった場合に影響が大きいので、まずは作成者のみ に適用されるように「プライベート」にチェックを付けて確認する
別途Redmine環境を用意 • Redmineを試すにあたって様々な構築方法が用意されているので、 それを利用して動作環境を作る • Ansible • https://github.com/farend/redmine-centos-ansible • Docker
• https://hub.docker.com/_/redmine • Vagrant • https://app.vagrantup.com/onozaty/boxes/redmine-4.1
例:Vagrant Vagrantがインストールされている状態で、コマンド2つでRedmineの 環境を立ち上げられる View customizeがインストール済みのboxもあるので、View customize を試すときは、それを使うとプラグインのインストールも不要 ※Vagrantfileでネットワークの設定は適宜 vagrant init
onozaty/redmine-4.1 vagrant up vagrant init onozaty/redmine-viewcustomize vagrant up
コードを書くのが大変?
コードを書くのが大変? • サンプルコードも公開されているので、それを参考にすれば大丈夫 • onozaty/redmine-view-customize-scripts https://github.com/onozaty/redmine-view-customize-scripts • farend/redmine-view-customize-examples: Redmineのプラグイン「View customize」を利用したRedmineカスタマイズ集
https://github.com/farend/redmine-view-customize-examples • 「redmine view customize」の検索結果 - Qiita https://qiita.com/search?sort=&q=redmine+view+customize • エンジニアではない人でも、サンプルコードを参考にながらカスタ マイズしている
おわりに • 困ったことや、わからないことがあれば、お気軽に @onozaty まで • Twitterでは新しいカスタマイズ例などのつぶやきも • こういったことできますか?といったような質問は、GitHubのIssue でもOK
• https://github.com/onozaty/redmine-view-customize-scripts