REDMINE

ブログ

Redmineの最新ニュースと役に立つ情報をお伝えします。

Redmine4.2の「ウォッチャーの追加」ポップアップウィンドウで「ユーザ」と「グループ」を視覚的に区別できるようにJavaScriptで実装してみた

 

記事作成の背景

 

ANKOSOFTの山崎です。この記事は「Redmine Advent Calendar 2022」の12/2の記事として作成しています。毎年「Redmine Advent Calendar」が企画されていて、途切れることなく、バトンがつながっていましたが、今年(2022年)は12/1の23:30現在、まだ半分ぐらいが空いていて、何か一つでもと思い、記事の作成をしました。

 

1.前提状態

Redmine4.2から新しいチケットの作成ページや、チケット詳細ページで「ウォッチャーを検索して追加」や「ウォッチャーの追加」をクリックすると「ウォッチャーの追加」ポップアップウィンドウが表示されます。

「ユーザーの検索」欄にユーザー名やグループ名を入力すると部分一致で検索ができ、非常に便利にウォッチャーの追加が可能になります。

 

2.課題

2021年7/3に下記のように「りょうま」様のツイートを拝見しました。

 

確かに、下図のようなUIとなっており、どれがユーザーで、どれがグループなのかを視覚的に区別する方法がありません。

 

HTMLを調べてみても、ユーザーとグループを区別するクラスの付与は無いことが分かります。

 

ユーザーのHTMLの例

<label id="issue_watcher_user_ids_9" class="floating">

  <input type="checkbox" name="issue[watcher_user_ids][]" value="9">Tancred Isaiah

</label>

 

グループのHTMLの例

<label id="issue_watcher_user_ids_53" class="floating">

  <input type="checkbox" name="issue[watcher_user_ids][]" value="53">Development 1 team

</label>

 

3.解決方法

 

一番簡単で確実な方法は、rubyファイルを改変してウォッチャー欄のユーザーとグループを区別することができるようにクラスを追加することです。そのためには、Redmineの本体のソースを改変するか、もしくはプラグインを作成してrubyでviewを改変してクラスを追加する必要があります。かなりハードルは高くなります。

ruby以外の方法ではJavaScriptでの実装が可能です。今回は、JavaScriptで実装をしてみたいと思います。

「ウォッチャーを検索して追加」をクリックすると、下図のようにユーザーとグループがアイコンで区別されて表示されています。「新しいチケット」ページでは取得できないクラス情報が、「ウォッチャーを検索して追加」をクリックして表示されるポップアップウィンドウでは存在しているので、JavaScriptで「ウォッチャーを検索して追加」をクリックして該当ページからクラス情報を取得して、「新しいチケット」ページにクラスを追加する方法を実装したいと思います。

 

完成形の図です。

1)ユーザーとグループを区別するアイコンを挿入

2)ユーザーとグループの境界にセパレーターを入れて区分

をしました。

 

JavaScriptのソースは下記のとおりです。

コメントを入れていますので、詳しい説明は割愛します。

 

$(function () {

  if ($(".search_for_watchers > .icon-add-bullet").length == 1) {

 

    $.get($(".icon-add-bullet").attr("href"), function () {

      $(".ui-dialog-titlebar-close").click();

 

      //クラスを追加

      $("#users_for_watcher label").each(function (i, val) {

        $("#watchers_inputs").find("#issue_watcher_user_ids_" + $(val).find("input").val()).addClass($(val).find("span").attr("class"));

      });

      //改行とタイトルを挿入

      $("label:contains(" + $("#users_for_watcher .icon-group").first().parent().text() +")").first()

        .before('<label class="floating" style="clear: both;"> グループ名</label><hr>')

 

      $("#watchers_inputs label:first")

      .before('<label class="floating" style="clear: both;"> ユーザー名</label><hr>')

 

    });

  }

});

 

4.制限事項

 

「新しいチケット」を開いた直後の状態で上記のJavaScriptを実行する時だけ、正常に動作します。

下図のように「ウォッチャーを検索して追加」からユーザーを追加するとアイコンやセパレーターは正しく表示しません。

 

5.おまけ:「ウォッチャーを検索して追加」のUIの改善

 

いくつかのパターンを実施

5.1.ユーザーとグループの間に水平線を挿入

 

$(function () {

  // 監視ターゲットの取得

  const target = document.getElementById("ajax-modal");

 

  // オブザーバーの作成

  const observer = new MutationObserver(records => {

    $("#users_for_watcher .icon-group").first().parent().before("<hr>");

  });

 

  // 監視の開始

  observer.observe(target, {

    childList: true

  });

});

 

5.2.ユーザーとグループの間に水平線を挿入し、ユーザーとグループで背景色を変える

 

$(function () {

  // 監視ターゲットの取得

  const target = document.getElementById("ajax-modal");

 

  // オブザーバーの作成

  const observer = new MutationObserver(records => {

    $("#users_for_watcher .icon-group").first().parent().before("<hr>");

    $("#users_for_watcher .icon-group").parent().css("background-color", "gainsboro");

    $("#users_for_watcher .icon-user").parent().css("background-color", "aliceblue");

  });

 

  // 監視の開始

  observer.observe(target, {

    childList: true

  });

})

 

5.3.水平線は入れず、ユーザーとグループで背景色を変える

 

$(function () {

  // 監視ターゲットの取得

  const target = document.getElementById("ajax-modal");

 

  // オブザーバーの作成

  const observer = new MutationObserver(records => {

    $("#users_for_watcher .icon-group").parent().css("background-color", "gainsboro");

    $("#users_for_watcher .icon-user").parent().css("background-color", "aliceblue");

  });

 

  // 監視の開始

  observer.observe(target, {

    childList: true

  });

});

 

5.4.「ユーザーの検索」欄に文字列を入力すると検索がされますが、その際にも背景色が維持されます。

 

2022年12月2日午前1時に執筆をしました。ワールドカップで日本は無事にリーグ突破ができるのか?できないのか?午前4時から始まるとのことで残念ながら生中継は見れそうもないので、録画版で応援をしたいと思います。

少し早いですが、良いクリスマスを!Redmineの愛用者の皆様にメリークリスマス!

合計 12