Redmineのプロジェクト一覧ページを並べ替える

<h1>概要</h1>
<p>Redmineでプロジェクトをいくつか作ってからプロジェクトの並び順を指定したいと思ったら該当するキーがなかった。プラグインを検索してみたが、それらしきものはなくて難儀しているようだ。</p>

<h1>解決策</h1>
<p>
検索するとRedmine View Customize Plugin(<a href="https://github.com/onozaty/redmine-view-customize-scripts">https://github.com/onozaty/redmine-view-customize-scripts</a>)というものがあり、任意のページでjavascriptとcssを設定できるようだ。こいつを使ってゴリ押ししてみよう。
</p>

<h1>例題</h1>
以下の様なプロジェクトがあったとして、[食事][金融][掃除][住居]の順に並べ替えたいとする。
![before.png](https://qiita-image-store.s3.amazonaws.com/0/133885/e5aafcce-3817-6549-11f4-7419f9625322.png)

ここのHTMLは以下のようになっている。

```HTML
<div id="projects-index">
  <ul class='projects root'>
    <li class='root'><div><a href="/projects/chat">Chat</a><div><p>チャット用のプロジェクトです。</p></div></div></li>
    <li class='root'><div><a href="/projects/event">イベント</a><div><p>イベントの日程管理を行うプロジェクトです。</p></div></div>
```

これを見ると、ulにdisplay: flex; flex-direction: column; を指定してやり、
liにorder指定すれば目的は達成できそうである。
<h4>コード</h4>

```Javascript:/projects$
var flex_root = {
  "display" : "flex",
  "flex-direction" : "column"
}
var flex_child = {
  "margin-bottom" : "0"
}
function orderProject(projectLink, order) {
  $("#projects-index>ul>li").each(function(index, element){
    if ($(element).find('a').attr('href') === projectLink) {
      $(element).css("order", order);
      return;
    }
  });
}
$(document).ready(function(){
  $("#projects-index>ul").css(flex_root);
  $("#projects-index>ul>li").css(flex_child);
  orderProject("/projects/chat", "0");
  orderProject("/projects/clean", "4");
  orderProject("/projects/food", "2");
  orderProject("/projects/event", "1");
  orderProject("/projects/house", "5");
  orderProject("/projects/finance", "3");
  orderProject("/projects/hobby", "6");
});
```

このコードではプロジェクトのリンク先をキーとしてjQuaryで無理矢理対象のDOMを引っ張ってきてインラインcssを付与しています。
<h4>結果</h4>
![after1.png](https://qiita-image-store.s3.amazonaws.com/0/133885/8845859e-90f8-2f99-ca4f-366a488301eb.png)
<h4>折りたたみもやってみた</h4>

```Javascript:/projects$
var flex_root = {
  "display" : "flex",
  "flex-direction" : "column"
}
var flex_child = {
  "margin-bottom" : "0"
}

function orderProject(projectLink, order) {
  $("#projects-index>ul>li").each(function(index, element){
    if ($(element).find('a').attr('href') === projectLink) {
      $(element).css("order", order);
      return;
    }
  });
}

function enableAccordion(projectLink) {
  $("#projects-index>ul>li").find('a').each(function(index, element){
    if ($(element).attr('href') === projectLink) {
      $(element).parent().addClass("btn");
      $(element).parent().parent().children('ul').addClass("open");
      return;
    }
  });
}

$(document).ready(function(){
  $("#projects-index>ul").css(flex_root);
  $("#projects-index>ul>li").css(flex_child);
  orderProject("/projects/chat", "0");
  orderProject("/projects/clean", "4");
  orderProject("/projects/food", "2");
  orderProject("/projects/event", "1");
  orderProject("/projects/house", "5");
  orderProject("/projects/finance", "3");
  orderProject("/projects/hobby", "6");
  enableAccordion("/projects/anime");

  $('.open').each(function(){
    $(this).css("height",$(this).height()+"px");
  });
  $('.open').hide();
  $('.btn').click(function () {
    $(this).next('.open').slideToggle('slow');
    $(this).toggleClass('active');
  });
});
```

```CSS:/projects$
.btn{
    background: #e0f2fe;
    border-style: solid;
    border-color: #8080de;
    border-radius: 8px;
    transition: all  0.3s ease;
}
.btn:hover{
    background: #fee0c0;
}
.btn::before {
    content: "▼";
    margin-left: 4px;
    margin-right: 8px;
    color: #f93010;
}
.btn.active::before {
    content: "▲";
    margin-left: 4px;
    margin-right: 8px;
    color: #f93010;
}

.open{
    border-bottom: 1px dotted #a9a9a9;
    cursor: pointer;
    margin: 0;
}
```

enableAccordion()に折りたたみたいプロジェクトのリンク先を入れて実行するとトグルボタン化します。cssは適当に設定。これでプロジェクトが増えても一覧性を損ないませんね。

![after2.png](https://qiita-image-store.s3.amazonaws.com/0/133885/cca75a9e-34b3-8b86-75f1-2c03c7104410.png)