@aldabil/react-schedulerで予定の追加・編集・削除をできなくする

:::note info
Reach-Schedulerの
[@2.4.1](https://github.com/aldabil21/react-scheduler/releases/tag/2.4.0)で`editable`、`deletable`オプションが追加されたため、
オプション付与のみで対処できるようになり、不要なボタンも表示されなくなりました。
記録のため、記事の内容は残しておきますが、コード例は変更してあります。
:::

# react-schedulerとは

Material-UIとdate-fns をベースにしたReact用スケジュールコンポーネントです。

https://www.npmjs.com/package/@aldabil/react-scheduler

NPMのページ下の方にあるDemosを見てくれればなんとなくわかると思いますが、フロントでカレンダーを表示するためのコンポーネントです。

# 使おうと思った動機

カレンダーを表示させたいなーと思って笑

Reactにはカレンダーを表示するパッケージがいくつかあります。
しかし、**無料** で **複数日にまたがった予定を表示できる** パッケージはこれしかなかったので、使うことにしました。
（偶然Material-UIを使ったサイトでよかった...）

# 親切だけど...

このreact-scheduler、親切なことに、デフォルトで予定の新規登録・変更・削除機能が既についています。
便利なんですけど、僕が欲しいのは予定入りのカレンダーを表示させるだけのものでした。

ぱっとドキュメント見ても、新規登録をできないようにするOptionsはありませんでした。
GitHubのissueを探してみると一応こんなものが...

https://github.com/aldabil21/react-scheduler/issues/20

見てみると、「`cellRenderer`と`customEditor`、`onDelete`をいい感じに書けば実現できるよ」とは書いてありますが、その方法は書いてありません(´;ω;｀)

ということで、予定の追加・編集・削除をできないようします。

# コード

:::note info
下記のコードはアップデートにて対応した`editable`、`deletable`を使用したものになります。
元のコードは折り畳みからご覧ください。
:::

最終的なコードは以下のようになります。
`EVENTS`変数はあらかじめ宣言されているとします。

```jsx
<Scheduler
    events={EVENTS}
    selectedDate={new Date(2021, 4, 5)}
    resourceFields={{
      idField: "name",
      textField: "name",
      colorField: "color"
    }}
    month={{
      weekDays: [0, 1, 2, 3, 4, 5, 6],
      weekStartOn: 1,
      startHour: 0,
      endHour: 23,
      cellRenderer: () => <></>
    }}
    week={{
      weekDays: [0, 1, 2, 3, 4, 5, 6],
      weekStartOn: 1,
      startHour: 0,
      endHour: 23,
      step: 120,
      cellRenderer: () => <></>
    }}
    day={{
      startHour: 0,
      endHour: 23,
      step: 120,
      cellRenderer: () => <></>
    }}
    editable={false}
    deletable={false}
/>
```
<details><summary> editiable等の対応前のコードはこちら</summary>

https://codesandbox.io/s/inactive-react-scheduler-yhm5pd?file=/src/App.js

```jsx
<Scheduler
    events={EVENTS}
    selectedDate={new Date(2021, 4, 5)}
    customEditor={({ close }) => {
      close();
      return <></>;
    }}
    resourceFields={{
      idField: "name",
      textField: "name",
      colorField: "color"
    }}
    month={{
      weekDays: [0, 1, 2, 3, 4, 5, 6],
      weekStartOn: 1,
      startHour: 0,
      endHour: 23,
      cellRenderer: () => <></>
    }}
    week={{
      weekDays: [0, 1, 2, 3, 4, 5, 6],
      weekStartOn: 1,
      startHour: 0,
      endHour: 23,
      step: 120,
      cellRenderer: () => <></>
    }}
    day={{
      startHour: 0,
      endHour: 23,
      step: 120,
      cellRenderer: () => <></>
    }}
    onDelete={() => {
      return new Promise((resolve) => resolve());
    }}
/>
```

</details>

# 説明

## 新規追加をできなくする

新規追加をできなくするには、以下のように`cellRenderer`に何もしない関数を指定すればいいです。
3つのビュー（月、週、日）ごとに設定が必要です。
以下が月ビューの設定例です。（`weekDays`などは適当に設定してください。）

```jsx
month={{
    weekDays: [0, 1, 2, 3, 4, 5, 6],
    weekStartOn: 1,
    startHour: 0,
    endHour: 23,
    cellRenderer: () => <></>
}}
```

## 編集をできなくする

:::note info
v2.4.0からは`editable`オプションを`false`に設定するだけ
:::


編集画面をカスタマイズするには`customEditor`を使います。編集をできなくするんだから`cellRenderer`と同じように何もしない関数を返せばいいやと思っていたら...

```jsx
customEditor={() => <></>}
```

予定をクリックしたとき、右上に表示される編集ボタンを押したときに、全体がグレーになって何もできなくなってしまいました...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/38228afc-3b49-8ff3-3c4f-87faf85e8156.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/b6b6134b-46d8-c194-84b8-fe1578d8dced.png)

これには罠があって「ダイアログが閉じたよ」ということをコンポーネント側に教えてあげないといけないのです。

具体的には、以下のようにします。関数の引数にくるclose関数を呼び出します。

```jsx
customEditor={({ close }) => {
    close();
    return <></>;
}}
```

## 削除をできなくする

:::note info
v2.4.0からは`deletable`オプションを`false`に設定するだけ
:::

最後に予定の削除ができなくします。

`onDelete`関数を定義すればいいんですけれど、なぜかこの関数の返り値はPromiseじゃないといけないっぽい...
なので、何もしないPromiseを返してあげます。

```jsx
onDelete={() => {
    return new Promise((resolve) => resolve());
}}
```

# さいごに

react-schedulerで予定の追加・編集・削除をできなくするだけですが、結構苦労しました...
個人開発のパッケージ？っぽくメンテ性とかは少し心配ですが、とりあえず僕の要求を満たしてくれるパッケージだったので使ってみました。
（暇あったらPR送ってみようかな）

ちなみに、このパッケージを使って開発したページは、以下になります。
一部高専の予定表をiCalendar形式で配布しているのですが、その簡易ビューアを作りました。

https://www.kamekyame.com/contents/kosen-calendar

よかったらこの記事で高専カレンダーについて書いているので見てください！そして協力お願いします！？

https://qiita.com/SuzuTomo2001/items/0b9e55137c125de7154b