You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
保存失敗時の復元が、後続のドラッグの結果を上書きする:保存 A の待機中にドラッグ B を始め、その後 A が失敗すると、A のドラッグ前の並びで B の結果を上書きする。B が保存済みなら、表示と DB がずれる。以前からある競合で、snapshot の修正では解消しない。保存の失敗と保存待ち中のドラッグが重なったときだけ起きるので、記録のみとした。直す場合は、保存が終わるまで次のドラッグを始められないようにするのが最小。
devcontainer で pnpm i が registry.npmjs.org からの取得で止まった場合は、sudo /usr/local/bin/init-firewall.sh で許可リストを作り直す。ファイアウォールは起動時に 1 回だけ DNS を引いて IP を許可するので、そのとき一部の IP しか返らないと、他の IP への接続が拒否される(推定。ipset の中身は未確認)。
dnd-kit 更新時の確認項目
ID
操作
期待
M1
列をまたいで移動(未分類 → グラフ)し、リロード
ドラッグ中に移動先の列が濃いグレー、掴んだカードが半透明になる。固まらない。リロード後も同じ
M2
同じ列の中で並べ替え、リロード
挿入位置が正しく、リロード後も同じ
M3
カードの余白(ラベル付近)を掴み、別カードのタイトル上で離す
離した直後に問題集の詳細ページへ移動しない
M4
タイトルリンクを普通にクリック
詳細ページへ移動する
M5
動かしたカードを続けて再ドラッグ(往復、3 回以上)
カードがポインターに追従し、位置がずれない。挿入位置が正しい
M6
キーボード:Tab でフォーカス → Space / Enter で掴む → 矢印で移動 → Space / Enter で確定
Activity
KATO-Hiro commentedon Oct 18, 2026
dnd-kit 0.5.1 の Kanban 実操作確認とドラッグ終了処理の修正
概要
管理画面 Kanban(
src/routes/(admin)/workbooks/order/)について、次の 2 つを行った。#4183)で扱う。状況(2026-10-18 時点)
resolveDragEndActionに切り出し、テストを先行KanbanBoard.svelteへの組み込み不具合と原因
onDragOverがmove()でアプリの状態を書き換えるため、dnd-kit はキャンセル時の DOM 復元を行わない(@dnd-kit/domのsortable.jsの dragend 監視で、hasChangedが真なら何もせず return する。0.5.0・0.5.1 とも同じ)。さらに旧onDragEndはevent.canceledを見ずに差分を保存していた。onDragEndは target が無いと何もせず return したが、表示はonDragOverの時点ですでに移動後の並びになっていた。finallyで null にしていた。保存待ちの間に次のドラッグを始めると、前のドラッグのfinallyが新しい snapshot を消す。次の保存はreCalcPriorities({}, …)になってタブ内の全カードを更新し、失敗しても元に戻せない。意思決定
canceled: booleanにする。 テストで dnd-kit のクラスを偽装せずに済み、util が dnd-kit の型に依存しない。却下した案
if (event.canceled)を足すだけにする:分岐をテストで固定できない。onDragOverでcanceledを見る:move()はキャンセル時に items をそのまま返すので意味がない(@dnd-kit/helpersのmutate)。move()をonDragEndだけで呼び、snapshot と復元をなくす:理由は 2 つ。1 つ目は、{#each}の DOM とOptimisticSortingPluginが食い違って固まること(2026-02-28 のメモ「@dnd-kit/svelte 実装上の注意点」)。2 つ目は C2 が悪化すること。列の外で離すと target が無くmove()は何もしないが、dnd-kit はキャンセル時しか DOM を戻さないので、画面だけ移動後の並びになる。既知の課題(#4183 では扱わない)
レビュー(2026-10-18)
solutionColumnsGraphSwappedに切り出した。Efficiency・Altitude は指摘なし。Altitude の補足を受けて、「move()をonDragEndだけで呼ぶ」案を却下理由とともに追記した。手動確認
自動テストで代替できない理由
.github/workflows/ci.ymlのTODO: Run integration test)。e2e/workbook_order.spec.tsは並べ替えを API への直接 POST で検証しており、ドラッグを通らない。getBoundingClientRectが 0 を返す)ので、dnd-kit の重なり判定や並び位置の計算を動かせない。環境
pnpm db:seedで placement が作られる。未配置の問題集があれば、画面の初期化ボタンで作る。カードが 2 枚以上ある列と、スクロールが出るほどカードの多い列が必要。pnpm iが registry.npmjs.org からの取得で止まった場合は、sudo /usr/local/bin/init-firewall.shで許可リストを作り直す。ファイアウォールは起動時に 1 回だけ DNS を引いて IP を許可するので、そのとき一部の IP しか返らないと、他の IP への接続が拒否される(推定。ipset の中身は未確認)。dnd-kit 更新時の確認項目
0.5.1 で M1〜M9 を選んだ根拠は、上流の変更との対応である。M1・M2 は #2135(Svelte 版の状態購読)、M3・M4 は #2152(ドロップ直後のクリック)、M5 は #2149・#2142、M6 は #2094(キー判定を
event.keyへ変更)、M7 は #2142、M8 は #2126、M9 は #2151 に対応する。NG が出たら旧バージョンでも同じ操作を行い、退行かどうかを切り分ける。回避用のコードは足さない。#4183 の確認項目(Phase 4)
確認結果
修正前の M1〜M9 は、0.5.1(#4165)でローカルで確認した。この表に無い M3・M4・M6〜M9 も同じ確認に含まれる。
修正後の確認は、#4183 のブランチでローカルで行った。
確認日:2026-10-18
Merge pull request #4184 from AtCoder-NoviSteps/#4183