## Handsontableライブラリの更新時に気をつけるべきこと

<div class="alert alert-warning"> v7.0.0 以降 MIT ライセンスではなくなったので、GROWI は v6.2.2 に留まり、以降のバージョンアップは諦める -- 2019.08.17 Yuki Takei
</div>

- 以下の[今の仕様](#今の仕様)に影響を与えていないかチェック.

- [現在の仕様に関連したウォッチするべきHandsontableのIssue](#現在の仕様に関連したウォッチするべきHandsontableのIssue)がfixされていなかチェック. fixされた場合コードの不要コードの削除や改修が必要になる可能性がある. 

相談はSlackで@utsushiiroにメンションください.

## 今の仕様

### Context Menu について

Context Menuは右クリックしたときにでてくるやつ.

全部で7項目あるが, 以下の6項目はHandsontableが提供している機能をそのまま使っている. 各種操作による動作はそれぞれ名前の通り.
- insert row above
- insert row below
- insert column left
- insert column right
- remove row
- remove column

`Align columns`については自作. これによって現在選択しているセルが含まれる各カラムについてのアラインメントを一括変更できる.

### アラインメントについて

- 新規テーブル作成時は指定なし(左揃え)になっている. 
- 既存のテーブルを読み込んで起動した場合は, 既存のアラインメントが反映された状態で表示される.
- カラムをドラッグによって移動させてもアラインメントは保持される
- Context Menuによって選択セルが含まれるカラムのアラインメントを変更できる
- ツールバーにあるボタンによって選択セルが含まれるカラムのアラインメントを変更できる
- Context Menuにあるinsert rowで挿入したrowの各セルのアラインメントはそのセルのカラムのアラインメントとは**同期されず, 必ず左揃えで**表示される. ただしsaveすると反映される. 
 
### カラムとローの移動について

- カラムのヘッダー部分を選択して左右にドラッグさせることでカラムの位置を変更できる
- ローのヘッダー部分を選択して上下にドラッグさせることでローの位置を変更できる

カラムの移動については, 移動を行ったあとにImport機能でテーブルデータをインポートするとインポートしたデータのカラムの並びがインポート前の移動操作の影響を受けて並び変えられてしまう.

以下のようなテーブルを
| col1 | col2 | col3 |
| ---- | ---- | ---- |
| 1    | 2    | 3    |

次のように2列目, 3列目を入れ替えた上で
| col1 | col3 | col2 |
| ---- | ---- | ---- |
| 1    | 3    | 2    |


以下のようなテーブル(ここではcsv)をImportで読み込ませると
```
col1, col2, col3
a, b, c
```

このようにはならずに
| col1 | col2 | col3 |
| ---- | ---- | ---- |
| a    | b    | c    |


こうなる
| col1 | col3 | col2 |
| ---- | ---- | ---- |
| a    | c    | b    |

### Import機能について
ツールバーのImport Dataを押すとアコーディオンでImportゾーンがでてくる. CSV, TSV, HTML形式で表現されるデータを読み取れる.

### サイズ調整について
デフォルトでは各カラムのサイズ(width)、各ローのサイズは(height)は内容に応じて自動調節される. ただし自動調節ではwidthは80px ~ 400pxの値に制限される.

各カラムやローのヘッダーの境界線部分を左右にドラッグすることによりサイズ調節することができる. これによってサイズを調節したカラムは以後サイズの自動調節がオフになる. ただし, カラムの移動を行った場合, すべてのカラムについて再度自動調節がオンになる.

### リセットボタンの挙動について
モーダル右下にあるResetボタンによってテーブルのデータをもとに戻すことができる. ただし, 以下の点に注意.

- テーブルデータをImport機能でImportして上書きした場合, 以降のResetではそのImportしたデータに戻る
- ドラッグによるカラムとローの移動を行った場合, それらの操作による位置関係の変更はリセットされない

後者の例としては, 以下のようなテーブルを
| col1 | col2 | col3 |
| ---- | ---- | ---- |
| 1    | 2    | 3    |


次のように2列目, 3列目を入れ替えた上で値を一部変更する
| col1 | col3 | col2 |
| ---- | ---- | ---- |
| 1    | 3    | 222  |

ここでResetすると以下のようにはならずに
| col1 | col2 | col3 |
| ---- | ---- | ---- |
| 1    | 2    | 3    |

このようになる
| col1 | col3 | col2 |
| ---- | ---- | ---- |
| 1    | 3    | 2    |

## 現在の仕様に関連したウォッチするべきHandsontableのIssue

### beforeColumnResizeHandlerの引数バグのIssue
https://github.com/handsontable/handsontable/issues/3328

これは[カラムとローの移動について](#カラムとローの移動について)の実装に影響を与えている. このIssueにあるようにbeforeColumnResizeHandlerに正しい情報(操作しているカラムインデックス)がわたってこないため, 代わりにafterColumnResizeHandlerを利用している. このIssueがfixされると, 処理をbeforeColumnResizeHandlerにうつして, おそらくforce re-renderしている処理を消しても動くようになる.
```javascript:HandsonModal.jsxから抜粋
  beforeColumnResizeHandler(currentColumn) {
    /*
     * The following bug disturbs to use 'beforeColumnResizeHandler' to store column index -- 2018.10.23 Yuki Takei
     * https://github.com/handsontable/handsontable/issues/3328
     *
     * At the moment, using 'afterColumnResizeHandler' instead.
     */

    // store column index
    // this.manuallyResizedColumnIndicesSet.add(currentColumn);
  }

  afterColumnResizeHandler(currentColumn) {
    /*
     * The following bug disturbs to use 'beforeColumnResizeHandler' to store column index -- 2018.10.23 Yuki Takei
     * https://github.com/handsontable/handsontable/issues/3328
     *
     * At the moment, using 'afterColumnResizeHandler' instead.
     */

    // store column index
    this.manuallyResizedColumnIndicesSet.add(currentColumn);
    // force re-render
    const hotInstance = this.hotTable.hotInstance;
    hotInstance.render();
  }
```
### manualColumnMoveの仕様についてのIssue
https://github.com/handsontable/handsontable/issues/5591

これは[カラムとローの移動について](#カラムとローの移動について)と[リセットボタンの挙動について](#リセットボタンの挙動について)の仕様に影響を与えている. 具体的には, 

> カラムの移動については, 移動を行ったあとにImport機能でテーブルデータをインポートするとインポートしたデータのカラムの並びがインポート前の移動操作の影響を受けて並び変えられてしまう.

と

> ドラッグによるカラムとローの移動を行った場合, それらの操作による位置関係の変更はリセットされない

なお, このIssueがfixされる, つまり`loadData` の仕様が変わる場合内部実装の大部分に影響を与えると思われるので要注意. たぶん下に書いているようにほぼ作り直す必要がでてくる.

## 内部仕様について
基本的にHandsontableModal.jsxにめちゃ詳しくコメント書いてあるので読んで. 読めばわかる.

現状HandsontableModal(React)側で管理している値(ステート)とHandsontableの内部の値を各種操作時にできる限り同期させているが, ReactのライフサイクルとHandsontable内部のライフサイクルがあまりうまく同期させれない & ちょくちょくHandsontableのフック周りにバグがあったりで正直起動時と保存時だけ同期するようにしちゃった方がいい気がする.

---

## Page Navigation

- Canonical URL: https://dev.growi.org/資料/内部仕様/Handsontable統合メモ
- Permalink: https://dev.growi.org/5cc99eac30890b003fe9093b
- Parent: [内部仕様](/5cc1c93a973c65003eeca8c9.md)
- Children: 0 total
- Total descendants: 0
- Siblings: 48 total
  - [AWS・メーラー周りの改善](/5d02003202145d003e1babf6.md)
  - [Audit Log Bulk Export](/68b96f7fcde220ddd8dad822.md)
  - [ConfigManager](/5cc9975f30890b003fe90935.md)
  - [ElasticSearchのインデックスリビルド](/5e3ff13564387500480619a1.md)
  - [Elasticsearchから取得できるPagesに関するデータ](/614aad9c0043a10051e15701.md)
  - [EmojiPicker](/6333fb298e520dbb752dc0cd.md)
  - [EventEmitterの利用](/61391728d5f8360051fd4942.md)
  - [G2G Transfer](/6346a2e0e4791185c5e88285.md)
  - [GROWI Bot](/62a71cdfb1519362cc276234.md)
  - [HackMD連携](/5d27efd443f7f50048a78e0a.md)
  - [InAppNotificationにニュースを配信する](/69ab8eb7659066cd59ddb618.md)
  - [LDAPグループ同期](/646d5f73d184d74b40517c3e.md)
  - [Packagesのエラーハンドリングアーキテクチャ](/60e6727cf04bf00049b9d514.md)
  - [Page Bulk Export](/655834752aa37f82842a2034.md)
  - [PageOperation](/62010f2f16bc406c1b5e291b.md)
  - [SAML RoleとGrowiの権限の連携](/5d25e82feeb1f9003ee9b64c.md)
  - [SMTP設定に関する仕様](/5f4ef239cff9700048251c9a.md)
  - [SWR Utilities](/63735c96c29dff4657eb78ca.md)
  - [Sidebar](/5edacd0e3512890048ddc19f.md)
  - [Slack Command Handling](/60ee432f4a58890049d183cd.md)
  - [WebpackAssetsのHTMLへの注入](/5e3ee633ccdb6f0048e8c124.md)
  - [apiv3仕様](/5cf494d4aa8c91003eb0b481.md)
  - [audit-log](/62a1639c028badd4ac23f533.md)
  - [growi-database-plugin](/634784794b3568aa883bfca6.md)
  - [skipSSR](/64bf8e68a1e72e1b846d02fd.md)
  - [socket.io room 機能を使った通知設計](/6137540af2060f00510d56bb.md)
  - [v5.0.0～v7.0.15 でのRevisionデータマイグレーションバグ](/69301054963f68dfcf2b7111.md)
  - [お知らせ機能](/650d5e741647c0285cbb8a33.md)
  - [アンケート機能](/6385911e1632aa30f4dae6a4.md)
  - [インストールプロセス](/6009091dd3b38b00486b4ba5.md)
  - [インラインコメント機能](/650154e4a3498dcb94e91b36.md)
  - [ショートカットキー](/5cc1cb12973c65003eeca8cc.md)
  - [スケルトン表示ガイドライン](/62d7ca7fb18c4bec89d81a12.md)
  - [タグに関する仕様](/6171077c700078147672e3e0.md)
  - [ビルトインエディタでの同時多人数編集](/6524a63e46f2d6a2691e430a.md)
  - [ファイルアップロードのシーケンス図](/5fd8424f2271ae00481ed2e8.md)
  - [ファイルアップロード設定](/5f55a6af28951e0048d61398.md)
  - [プレゼンテーション](/63ea366fdc96eb0ef7657f53.md)
  - [ページ&ユーザーグループv5](/61b2cdd6aa330ce7d8152a4e.md)
  - [ページの子孫数](/62ac00a1c395c23b7a8c86dc.md)
  - [ページの移動・リネーム](/62149d019311629d4ecd91cf.md)
  - [ページ同時編集時のコンフリクト解消に関する仕様](/615d4a77c0ac5081f05d9d57.md)
  - [ログイン時の挙動](/63eee058c9d7133b414ba205.md)
  - [ワークフロー機能](/64e6b3d5e28cb1aa7ee4197f.md)
  - [検索v5](/61975a974027a1fa01947059.md)
  - [検索結果ページのコメント表示](/621caadad9a9f09266ad21c3.md)
  - [権限修正が可能なページのアラート](/626a263645af0b779a282145.md)
  - [空ページ](/62b2f5b3f442e6078d890a8b.md)
- Last updated: 2019-08-17T09:33:00.142Z by yuki
- Full page listing (all children regardless of count): https://dev.growi.org/_api/v3/page-listing/children?id=5cc99eac30890b003fe9093b
