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
180
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
130
情報を表現するときのポイント
onozaty
0
15
チームで開発するための環境を整える
onozaty
1
130
Selenium入門(2023年版)
onozaty
1
150
40歳過ぎてもエンジニアでいるためにやっていること
onozaty
0
34
Java8から17へ
onozaty
0
14
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
0
91
Redmine issue assign notice plugin の紹介
onozaty
0
110
最近作ったもの
onozaty
0
19
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
40
2.4k
A Philosophy of Restraint
colly
203
16k
Automating Front-end Workflow
addyosmani
1366
200k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
850
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
17k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
How GitHub (no longer) Works
holman
310
140k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
0
140
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