kintoneポータルカスタマイズで絶対に忘れないタスク管理を作ってみた

* [kintone Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kintone) の17日目の記事です。
# はじめに
kintoneを使っていて便利だけどちょっと物足りない！と個人的に感じる機能がリマインダーです。
タスクとしてやるべきことを自動で通知してくれる素敵な機能の反面、通知が来て「あ！やらなくちゃ！」と思っても、別のことをしているうちにリマインドすら忘れてしまうことがしばしば…。

期限間近だよ！ちゃんとタスクやれよ！のアピールがもっと欲しいんだということで、作ってみました。

# 概要
kintoneのタスク管理アプリ上で管理しているタスクがポータル画面とスペースのポータル画面上部に流れて表示される、というカスタマイズを作成してみようと思います。

流れるメッセージのイメージはこんな感じ。
「"タスク名"の締め切りまであと○日！」


他のことをしていても常に期限間近のタスクが画面に出ていれば忘れないですね！

# タスク管理アプリ
タスクのタイトルと期限のみを管理するシンプルなアプリを作成しました。
![スクリーンショット 2022-12-17 23.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952606/a6df1eca-6a6f-4b36-a1b2-a8add65cbaec.png)
タスクが完了したら完了チェックを入れられるようにチェックボックスも配置しています。

# ポータル画面上でタスク管理アプリのレコードを取得する
今回はポータル上部とスペースのポータルの上部のスペース部分を利用して、タスク管理アプリの情報が表示されるようにしていきたいと思います。

ポータル画面が表示された時にタスク管理アプリの情報を取ってくる中で、今回は「期限が3日前までのレコード」かつ「完了チェックが入っていないレコード」を取ってくるようにしてみました。

```javascript 
kintone.events.on([
  'space.portal.show',
  'portal.show'
], (event) => {
    var portalSpace
    if(event.type === "portal.show"){
      portalSpace = kintone.portal.getContentSpaceElement();
     } else if (event.type === "space.portal.show") {
      portalSpace = kintone.space.portal.getContentSpaceElement();
     }

    const query = '期限 < FROM_TODAY(3, DAYS) and 完了チェック not in ("完了！")';
    const body = {
      'app': 107,
      "query": query
    };
    kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', body, (resp) => {
      console.log(resp.records);
      if(resp.records.length !== 0){
        const array = resp.records.map(record => {
          console.log(record);
        };
      }
    });
    return event;
});
```


# 期限日の取得
期限日まであと何日かを出す場合、「期限フィールドの日付 - 今日の日付」で計算することができますが、kintoneの日付フィールドに入っている日付のデータは文字列のため、new Date();で現在の日付を取得してもうまく計算できません。

そこで今回は、JavaScriptの日付操作ライブラリであるDay.jsを用いて日付の計算を行いました。

> Day.js
> https://day.js.org/en/

```javascript 
// 日付の差分を取る
const deadlineDate = dayjs(record.期限.value);
const today = dayjs();
var diffDate = deadlineDate.diff(today, 'day');
```

# メッセージを生成
取得したレコードデータと計算したタスク期限の残り日数を組み合わせて表示するメッセージを生成します。

```javascript 
var massege

if(diffDate >= 0) {
  diffDate++;
  massege = `<a href="${recordURL}" id="taskname">🦌${record.タイトル.value}の締切まであと${diffDate}日🦌</a>`
} else {
  massege = `<a href="${recordURL}" id="taskname">🦌${record.タイトル.value}は期限切れ！🦌</a>`
}
return massege
});
taskElement.innerHTML = array.join('&nbsp&nbsp&nbsp');
} else {
  taskElement.textContent = "🦌✨Merry Christmas!✨🦌"
}
```
ポイントは、計算した日付の差分が0以上であれば+1を加算している部分です。
day.js();で取得できるデータは現在の日付と時刻なのですが、dayjs(record.期限.value);で取得した期限フィールドのデータでは、時刻は00:00:00で取得されます。
![スクリーンショット 2022-12-18 0.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952606/49bbd4fa-71d9-b1dd-bd24-818a8bcc9df8.png)

Day.jsのdiffは時間で計算されるため、日付の表示上は明日でも24時間以内であれば0日と出てしまい、日付のズレが発生してしまいます。
このズレを修正するため、0以上であれば+1を加算するという処理を加えました。

ここまでの処理を読み込ませると…
![4B2D30D4-7FD6-4647-85D1-D03CE2F408E5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952606/f079ba69-efaa-24cb-4c48-3b06267f9ea3.png)

ポータルのスペース部分に表示されました！

# 文字を横に流す処理
レコードのデータを表示することができたので、文字を流す処理を追加します。
今回はCSSのアニメーションで実装しています。

```css
#textelement{
  font-size: 23px; 
  color:#ff0000 ; 
  font-family: 'Kaisei Decol', serif;
  animation: flowing 15s linear infinite; 
  transform: translateX(100%);
}
@keyframes flowing {
  100% {
    transform: translateX(-100%);
  }
}
```
また、せっかくのアドベントカレンダーなのでポータルをクリスマス仕様に色々カスタマイズしてみました。


# 完成したもの

![アドベントカレンダーGIF.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952606/2897c4c1-c7ff-7bc2-87d9-f8dda817b7b3.gif)

やるべきタスクが流れている！これならタスクを忘れないぞ！
ちなみに…タスクタイトルには該当レコードに飛べるURLを埋め込んでいます笑

![アドベントカレンダー_完了チェック.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952606/c30f6aa5-9756-e5e9-65f0-6894026512cd.gif)


クリスマス仕様にするために変更したのは
* フォント
* 背景色

あたりです。
フォントはGoogle FontsのKaisei Decolをあててみました。

> Kaisei Decol
> https://fonts.google.com/specimen/Kaisei+Decol?subset=japanese&noto.script=Jpan

# おわりに
やりたいことを全部詰め込んだ結果、かなり鬱陶しい画面になってしまいましたが、このくらい主張が激しければタスクを忘れることはないのでしょうか！

タスクを消費して楽しいクリスマスを過ごしましょう(^_^)✨