Redmine: チケット編集時の送信ボタンにショートカットキーを割り当てる(View customize plugin)

チケット編集画面で送信ボタンに対するショートカットキーがあれば、、というのを見かけたので、View customize pluginで実装してみました。

accesskeyを設定するだけの簡単な変更です。

View customize の設定内容

Path pattern

チケット画面を対象とします。

/issues

Code

Type:JavaScriptとして、チケット作成/編集時の作成/送信ボタンに対してaccesskeyを追加するコードを設定します。

$(function() {
  $('#issue-form input[name="commit"]').attr('accesskey', 's');
});

これでAlt+Shift+sで送信ボタンが押下できます。(WindowsのFirefoxで確認)

accesskeyを起動する方法は、OS、ブラウザによって異なるので、詳しくは下記をご参照ください。

Redmine: 子チケットの一覧にボタンを追加して、REST API経由で親子関係を外す(View customize plugin)

ということで、サンプルとして「子チケットの一覧にボタンを追加して、REST API経由で親子関係を外す」ということをやってみました。

REST APIの認証は、APIキーを払い出したものをヘッダにX-Redmine-API-Keyとして設定する方法にしています。他にもいろいろ認証方式があるので、用途に応じて使い分けるのが良いかと思います。

View customize の設定内容

Path pattern

チケット画面を対象にします。

/issues/[0-9]+$

Code

Type:JavaScriptとして下記を設定します。APIキーは適宜変更してください。

$(function() {

  // REST APIのキー
  var apiKey = '払い出したAPIキー';

  // 子チケット一覧を対象に
  $('tr.child').each(function() {
    var target = $(this);

    // チケットIDを取得
    var issueUrl = target.find('td.subject > a').attr('href');
    var issueId = issueUrl .substr(issueUrl .lastIndexOf('/') + 1);

    // ボタンを追加して、ボタン押下時にチケットを更新
    var button = $('<input type="button" value="親子関係を外す">');
    button.on('click', function() {

      $.ajax({
          type: 'PUT',
          url: '/issues/' + issueId + '.json',
          headers: {
            'X-Redmine-API-Key': apiKey
          },
          // 更新時はレスポンスのコンテンツが無く
          // jsonだとエラーとなるのでtextにしておく
          dataType: 'text',
          data: {
            'issue': {
              'parent_issue_id': '' // 親チケットIDをクリア
            }
          }
      }).done(function(data) {
        // 成功したらリロード
        location.reload();
      }).fail(function(data) {
        alert('失敗しました');
      });

    });

    target.append($('<td>').append(button));
  });
})

画面イメージ

下記のように子チケット一覧部分にボタンが追加され、ボタン押下で親子が外れます。

f:id:onozaty:20170723002608p:plain

REST APIについて

今回はチケットの更新を行いましたが、REST APIでは他にもいろいろできますので、ぜひ下記のドキュメントを参照してみてください。

Redmine 3.4.0、3.4.1 がリリースされました

Redmine 3.4.0、3.4.1 がリリースされました。(3.4.0が7月2日、バグフィックスで3.4.1が7月9日)

View Customizeだけは動作確認済みですが、他のプラグインも後ほど確認します。

いつもどおりVagrantのboxもあげておきました。

Redmine: チケット一覧でカスタムフィールドの値に応じて行のフォントを太字に変える(View customize plugin)

カスタムフィールドの値に応じて行を装飾する方法について問い合わせをいただいたので、「カスタムフィールド1の値が'A'の場合には、行のフォントを太字に変える」をView customizeで行ってみます。

チケットの優先度など、デフォルトで存在するフィールドについては、もとからclassが振られているのでCSSで装飾しやすいですが、カスタムフィールドだとclassが振られていないので、CSSだけではできません。 そのためJavaScriptにて値を判定して、スタイルを設定することによって対応します。

View customize の設定内容

Path pattern

チケット一覧を対象にします。

/issues$

Code

Type:JavaScriptとして下記を設定します。cf_1の部分は、該当のカスタムフィールドに応じて変更してください。

$(function() {
  $('table.issues td.cf_1')
    .filter(function() {
      return $(this).text() == 'A';
    })
    .parent()
    .css('color', 'red');
});

設定後のイメージ

f:id:onozaty:20170530000920p:plain

一覧に該当のカスタムフィールドが表示されていないと判定ができないので、ご注意ください。

その他

複数の属性を指定するような場合だと、JavaScriptだと面倒かと思います。そういった場合には、JavaScript側ではclassを追加するだけで、そのclassに応じたCSSを別途定義しておくような形がよいかと思います。

MyBatis にて size というパラメータ名を使うとintとしてマッピングされてしまう

追記@2017-07-02

下記Issueで既に対応していただいています。次のバージョン(3.4.5)に入る予定です。


MyBatisのSQLへのパラメータ埋め込みで、sizeという名前を使うと、JavaTypeがintとなってしまうようです。

現象を確認したのは、mybatis-spring-boot-starterの1.3.0(MyBatis自体のバージョンは3.4.4)です。

問題となるコード

下記のようなMapperを作ります。sizeという名前で、long型の引数をマッピングします。

package com.example.demo;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface TestRepository {

    @Insert("INSERT INTO test(number, size) VALUES(#{number}, #{size})")
    public void insert(@Param("number") long number, @Param("size") long size);
}

上記のメソッドを呼び出すと、下記のようなエラーが発生します。

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='size', mode=IN, javaType=int, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #2 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

なぜかsizeがintとしてマッピングされようとしてClassCastExceptionが発生しています。LongTypeHandlerが使われるべきなのに、IntTypeHandlerが使用されてしまっているようです。

試しに下記のように別の名前に変えるとうまく動作します。

    @Insert("INSERT INTO test(number, size) VALUES(#{number}, #{size2})")
    public void insert2(@Param("number") long number, @Param("size2") long size);

sizeという名前は、何か特別なものとして使われていて、それと競合することによっておきてしまっているのかもしれません。

Redmineでニュースの参照可否を制御する(patch適用)

Redmine 3.3時点では、ニュースの参照に関する権限が無く、一部のユーザにニュースを見せないということが出来ません。

それをつぶやいたところ、前田さんにRedmine本家のFeatureにあがっていて、3.4.0で入るかもといった情報を頂いたので、先行してパッチを当てて試してみました。

パッチの内容

現時点のパッチは下記になっています。

軽微な変更だったのと、最新じゃないバージョンに当てたかったので、手作業で差分当てました。下記の3ファイル(合計3行)さえ直せば、すぐに試せます。(日本語の表示確認してなくて良ければ、ja.ymlもいらないです)

  • config/locales/en.yml
diff --git a/config/locales/en.yml b/config/locales/en.yml
index a8eca2dfe..f2a8cbc0b 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -497,6 +497,7 @@ en:
   permission_view_time_entries: View spent time
   permission_edit_time_entries: Edit time logs
   permission_edit_own_time_entries: Edit own time logs
+  permission_view_news: View news
   permission_manage_news: Manage news
   permission_comment_news: Comment news
   permission_view_documents: View documents
  • config/locales/ja.yml
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index a018e7240..8d1ae6ce1 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -427,6 +427,7 @@ ja:
   permission_edit_time_entries: 作業時間の編集
   permission_edit_own_time_entries: 自身が記入した作業時間の編集
   permission_manage_project_activities: 作業分類 (時間管理) の管理
+  permission_view_news: ニュースの閲覧
   permission_manage_news: ニュースの管理
   permission_comment_news: ニュースへのコメント
   permission_view_documents: 文書の閲覧
  • lib/redmine.rb
diff --git a/lib/redmine.rb b/lib/redmine.rb
index e3ff60fd1..204429cc6 100644
--- a/lib/redmine.rb
+++ b/lib/redmine.rb
@@ -131,7 +131,7 @@ Redmine::AccessControl.map do |map|
   end
 
   map.project_module :news do |map|
-    map.permission :view_news, {:news => [:index, :show]}, :public => true, :read => true
+    map.permission :view_news, {:news => [:index, :show]}, :read => true
     map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy], :attachments => :upload}, :require => :member
     map.permission :comment_news, {:comments => :create}
   end

対応後の画面

ロールの編集画面に「ニュースの閲覧」という権限が追加されて、制御可能になりました。実際のニュースの表示もばっちりです。

f:id:onozaty:20170514004703p:plain