Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Redmineの画面をあなた好みにカスタマイズ - View customize pluginの紹介 - Redmine Japan 2020

Redmine Japan 2020 での発表資料です。

  • Be the first to comment

  • Be the first to like this

Redmineの画面をあなた好みにカスタマイズ - View customize pluginの紹介 - Redmine Japan 2020

  1. 1. Redmineの画面を あなた好みにカスタマイズ - View customize pluginの紹介 - 2020-09-18 Redmine Japan 2020 [B07] @onozaty
  2. 2. 自己紹介 • Hirokazu Onozato • 株式会社ユニスティ所属 • ソフトウエア開発者 • プログラムを書くのが好き • 個人でChrome/Firefoxの拡張機能や、ちょっとしたツールなど 作って公開 @onozaty https://github.com/onozaty
  3. 3. 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にチケットとして取り込む(新規、更新)するため のツール
  4. 4. View customize plugin
  5. 5. View customize plugin • Redmineの画面をカスタマイズするためのPlugin • 特定の画面に対して、JavaScript、CSSを埋め込む機能を提供 • ブラウザのUserScriptを、クライアントではなくサーバ側で設定し て、Redmineを使用する全ユーザに適用するイメージ • 再起動不要で、手軽にRedmineをカスタマイズできる
  6. 6. できること • JavaScriptとCSSを埋め込んで実行できるので、画面上に存在する情 報で完結することはたいていできる • 画面上に存在しない情報(ユーザのカスタムフィールドやAPIキーな ど)にアクセスする方法もプラグインとして提供しているので、それ らを組み合わせると、出来ることの幅はさらに広がる
  7. 7.
  8. 8. 例:バナーを表示
  9. 9. 例:プロジェクトによってヘッダの色を切り替え
  10. 10. 例:チケット一覧を装飾 適用前 適用後
  11. 11. 例:カスタムフィールドを連動 適用前 適用後
  12. 12. 例:子チケット作成時に親チケットの情報を引き継ぐ
  13. 13. 例:担当者の選択でインクリメンタルサーチ 適用前 適用後
  14. 14. 例:複数の子チケットをまとめて作成
  15. 15. 使い方
  16. 16. インストール方法 • 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 インストールがうまくいかなかったという問い合わせの 大半はこれが原因
  17. 17. 設定方法 管理 > 表示のカスタマイズ > 新しい表示のカスタマイズ で新規設定へ
  18. 18. 設定方法 実行対象の指定 実行するコード その他 設定画面
  19. 19. 設定画面:実行対象の指定 • パス(URL)とプロジェクト(識別子)を正規表現で入力することで、実 行対象とする画面を絞る ※プロジェクトは v2.7.0 から • コードの挿入位置を下記から選択 • 全ページのヘッダ • チケット入力欄の下 • チケット詳細の下
  20. 20. 設定画面:実行するコード • 種別は下記から選択 (種別によってコードの埋め込まれ方が変わる) • JavaScript (scriptタグで埋め込まれる) • CSS (styleタグで埋め込まれる) • HTML (そのままの状態で埋め込まれる) ※v2.1.0から
  21. 21. 設定画面:その他 • コメントは一覧上で表示される • 設定内容を表すものを入れておくことで、識別しやすくなる • 有効のチェックを外すと、設定を無効にできる • プライベートにチェックすると、作成者のみに適用できる
  22. 22. 実行 実行対象にコードが 埋め込まれて実行
  23. 23. 設定内容と実行結果の例 (JavaScript) チケット入力欄でステータスとして却下を 選んだ時に、期日が未入力ならば現在日を 期日として入れるように設定
  24. 24. 設定内容と実行結果の例 (CSS) プロジェクトaの場合に、ヘッダとトップ メニューの色が緑になるように設定
  25. 25. 設定に関するノウハウ
  26. 26. 実行対象の絞り込み方
  27. 27. 実行対象の絞り込み方:挿入位置 まずは挿入位置で対象を絞り込めるか考える • 全ページのヘッダ • すべての画面が対象になる • チケット入力欄の下 • チケット新規作成画面、チケット表示・編集画面が対象になる • チケット入力欄は、トラッカーやステータスを変えた際に再構築されるが、 再構築の際にも再度挿入される • チケット詳細の下 • チケット表示・編集画面が対象になる
  28. 28. 実行対象の絞り込み方:パスパターン 挿入位置だけで絞り込めない場合、パスを正規表現で指定することで、 さらに絞り込みを行う • URLでアプリケーション配下かつクエリパラメータを含まない部分 がパス • http://192.168.33.41/redmine/projects/a/issues?xxx=xx -> /projects/a/issues • View customizeでHTMLにパスをコメントとして埋め込んでいるの で、ブラウザのソース表示でみれば、その画面のパスが確認できる
  29. 29. 実行対象の絞り込み方:パスパターンの指定例 パスパターン 一致する画面 /issues$ チケット一覧 /issues/new$ チケットの新規作成画面 /issues/[0-9]+/copy$ チケットのコピーによる作成画面 /issues/gantt ガントチャート /projects$ プロジェクト一覧 /projects/.+/wiki Wiki v2.7.0 からパスパターンは任意となったため、パスパターンで絞り 込みたくない場合に .* を入れる必要が無くなった .*[]+$ といった文字は、正規表現におけるメタ文字(特殊な意味をもった文字)
  30. 30. 実行対象の絞り込み方:プロジェクトパターン 特定のプロジェクトのみで適用したい場合に、プロジェクト識別子を 正規表現で指定する ※v2.7.0 にて追加 • チケット表示画面だと、パスにプロジェクトの情報が入らないので、 v2.7.0より前だとJavaScriptのコードとして判断する必要があった • プロジェクト識別子は、プロジェクト配下の画面にアクセスすると、 URLからわかる URLが /projects/a なので、 プロジェクト識別子は a
  31. 31. CSSセレクタ
  32. 32. 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セレクタ」で検索を
  33. 33. RedmineとCSSセレクタ • Redmineでは、必要となるような要素へのid、class属性が適切に振 られている • 入力項目となるような要素へはid属性 • body要素やチケット一覧には、内容を表すようなclass属性も付与
  34. 34. 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
  35. 35. ViewCustomize.context
  36. 36. ViewCustomize.context ユーザやプロジェクトの情報にJavaScriptで簡単にアクセスできるよう に、ViewCustomize.context というオブジェクトが用意されている 分類 項目 ユーザ ユーザID、ログインID、管理者かどうか、姓名、最終ログイン日時、グループ、 APIキー、カスタムフィールド プロジェクト 識別子、名前、ロール、カスタムフィールド チケット チケットID
  37. 37. 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 } } }
  38. 38. 例:カスタムフィールドを使った制御 • ユーザのカスタムフィールド(真偽値)によって、スクリプトの適用 可否を判断 • 管理者ではなく、ユーザ側に選択権を持たせることができる
  39. 39. 例:カスタムフィールドを使った制御 $(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.'); });
  40. 40. 例: APIキーを使ってREST APIを呼び出し • ユーザのAPIキーを利用することで、Redmineの様々なREST APIを呼 び出し可能に • REST APIを使うと、各種情報の登録、更新なども行えるようになり、 自由度が高まる その分コードが複雑になっていくので、 ある程度覚悟を持ってやる必要あり
  41. 41. 例: 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を使って親チケットをクリアする部分の例
  42. 42. APIキーに関する注意事項 • 設定画面より「RESTによるWebサービスを 有効にする」にチェック • これをしないと、REST API自体が使えない • 各自で個人設定からAPIアクセスキーを1度 表示しておく • RedmineでのAPIキー払い出しが、最初に 表示したタイミングになっているため • これが面倒な場合は、プラグインの設定で「APIアクセスキーを自動的に作 成する」をチェックしておくと、自動的に作られるようになる
  43. 43. 外部JavaScriptの読み込み
  44. 44. 外部JavaScriptの読み込み • 種別としてHTMLを指定すると、HTMLをそのままで埋め込めるので、 外部JavaScriptの読み込みも簡単に指定できる • scriptタグのsrc属性で読み込むだけ • JavaScriptライブラリをCDNなどから読み込めば、やれることの幅 が広がる • JavaScriptライブラリを読み込んで、テキストエリアでの入力補完を実装し た例 https://blog.enjoyxstudy.com/entry/2019/03/22/000000
  45. 45. 外部JavaScriptの読み込み Redmine自体で既に使われているJavaScriptライブラリは、View customize側で読み込みをしなくても使える • jQuery • jQuery UI • Tribute.js ※4.1.0で追加された
  46. 46. ブラウザのDeveloper Toolの活用
  47. 47. ブラウザのDeveloper Toolの活用 いきなりView customizeでコードを書き始めるのではなく、ブラウザ のDeveloper Toolを使いながら、作成、確認をしていくと良い • 「DOMインスペクタ」を使って、変更したい箇所のHTML構造など を確認する • 「コンソール」上でコードを実行し、どういった結果になるか確認 • うまくいったら、View customizeとして設定する
  48. 48. DOMインスペクタ 選択した要素がHTML上でどういった構造になっているか確認できる ブラウザ上での選択箇所と Elementsパネルでの選択箇所が 連動することでHTMLの内容が 簡単に確認できる
  49. 49. コンソール 表示している画面でコードを実行し、動作を確認できる コードを入力し実行すると、 ブラウザ上にリアルタイムに 反映される
  50. 50. うまく動かないときの確認ポイント
  51. 51. 対象画面の指定があっているか • ブラウザ上でソース表示して、View customizeで指定したコードが 埋め込まれているか確認 • 埋め込まれていない場合には、挿入位置、パス、プロジェクトパ ターンのいずれかが間違えている
  52. 52. JavaScriptでエラーが発生していないか • Developer Toolでエラーメッセージが出力されていないか確認 • エラーメッセージが出力されていれば、エラー内容を元に修正
  53. 53. スタイルが上書きされていないか • 複数のスタイルが一致する場合、その要素に対してどのスタイルが 適用されるかは、優先度によって決まる • より詳細に指定している方が優先 • 型セレクタよりidセレクタの方が優先など • セレクタのレベルが同じならば、後から書かれたものが優先
  54. 54. スタイルが上書きされていないか • Developer Toolで見ると、どういった優先度で適用されているかわ かる 取り消し線がついているもの は、優先度の高いスタイルに よって上書きされたもの
  55. 55. Redmineでの試し方
  56. 56. 運用中のRedmine環境 • 運用中の環境で試す場合、いきなり全体に適用してしまうと想定通 りの動きをしなかった場合に影響が大きいので、まずは作成者のみ に適用されるように「プライベート」にチェックを付けて確認する
  57. 57. 別途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
  58. 58. 例: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
  59. 59. コードを書くのが大変?
  60. 60. コードを書くのが大変? • サンプルコードも公開されているので、それを参考にすれば大丈夫 • 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 • エンジニアではない人でも、サンプルコードを参考にながらカスタ マイズしている
  61. 61. おわりに • 困ったことや、わからないことがあれば、お気軽に @onozaty まで • Twitterでは新しいカスタマイズ例などのつぶやきも • こういったことできますか?といったような質問は、GitHubのIssue でもOK • https://github.com/onozaty/redmine-view-customize-scripts

×