AtCoderNoviSteps icon indicating copy to clipboard operation
AtCoderNoviSteps copied to clipboard

問題集の作成・編集をするときに、問題の順番を指定して登録・保存・表示できるようにしましょう

Open KATO-Hiro opened this issue 1 year ago • 7 comments

WHY

  • 問題集の並び順を動的に更新したい

WHAT

  • [x] 要件を列挙
  • [ ] 上記を満たすライブラリを調べる
  • [ ] ライブラリをサンプルプロジェクトなどで試してみる
  • [x] 並び順を変更した後に,DBと連携する方法を調べる
  • [ ] 上記の内容を実装
  • [x] 例外処理

KATO-Hiro avatar Apr 25 '24 13:04 KATO-Hiro

https://github.com/isaacHagoel/svelte-dnd-action https://svelte.dev/repl/17119a1dc7a2447695ad1ea40027ee54?version=3.42.1

https://reffect.co.jp/svelte/svelte-table-re-order

KATO-Hiro avatar Apr 25 '24 13:04 KATO-Hiro

問題集内の並びに関してはorder属性があり、並び替えのタイミングで番号を振り直すだけで良さそうです。 DBに対して特別な操作は現時点では不要と認識しています。

KATO-Hiro avatar Aug 10 '24 07:08 KATO-Hiro

実装を進めていますが、以下のバグが消えず途方に暮れています。

  • 再現手順

    • リアクティブなテーブルの行を一つ選択して入れ替える
    • 内部的には選択した問題のコピーが発生しており、入れ替えそのものができない
    • 選択状態を解除すると、選択していた問題が見かけ上消える(DBには残っているため、リロードをすると表示される) (+ その後、別のテーブルを表示しようとすると、表示がバグっている)
  • 確認できているエラー

// See: issues/520 and 595
TypeError: Cannot read properties of undefined (reading 'getBoundingClientRect')
  • 考えられる原因

    • 同じ問題が一時的とはいえ2つ発生しているので、ライブラリで一意に識別できない
    • DNDライブラリを入れた後から、開発環境がとても重くなった気がする?
      • リロードが有意に遅くなっている
  • 対処方法(いずれも失敗)

    • CSSで選択した行を一時的に表示しないようにする
    • 選択した問題を一時的に削除して、配置するときに登録

KATO-Hiro avatar Aug 10 '24 12:08 KATO-Hiro

問題集内の入れ替えは、問題の削除で擬似的に対応できることと、上記のバグが消えないためpending状態です。

KATO-Hiro avatar Aug 10 '24 12:08 KATO-Hiro

  import { dndzone } from 'svelte-dnd-action';

    // テーブルの行を動的に並び替えるために必要
  $: workBookTasksForTable = workBookTasksForTable.map((task, index) => ({
    ...task,
    id: index + 1,
  }));

  function handleReorder(event: CustomEvent) {
    const { items } = event.detail;

    if (!Array.isArray(items)) {
      console.error('items are expected to be an array.');
      return;
    }

    let newWorkBookTasksForTable = items.map((item, index: number) => {
      if (!item || typeof item !== 'object') {
        console.error('Invalid item format.');
        return null;
      }

      return { ...item, priority: index + 1, id: index + 1 };
    });

    if (newWorkBookTasksForTable.includes(null)) {
      console.error('Error during reorder: One or more items were invalid.');
      return;
    }

    workBookTasksForTable = newWorkBookTasksForTable;
    console.log('after: workBookTasksForTable', workBookTasksForTable);
  }

KATO-Hiro avatar Aug 10 '24 12:08 KATO-Hiro

    <!-- See: -->
    <!-- https://github.com/isaacHagoel/svelte-dnd-action -->
    <!-- Note: dndzoneは、HTML要素に対して使用されることを前提としているため、TableBodyのようなコンポーネントは利用できない -->
    <tbody
      use:dndzone={{ items: workBookTasksForTable, flipDurationMs: 300 }}
      on:consider={handleReorder}
      on:finalize={handleReorder}
      class="divide-y"
    >    
    </tbody>

KATO-Hiro avatar Aug 10 '24 12:08 KATO-Hiro

他のライブラリも試してみましょう

https://sortablejs.github.io/Sortable/#simple-list

https://github.com/tarb/svelte-dnd-list

KATO-Hiro avatar Aug 10 '24 23:08 KATO-Hiro

仕様を変更: 問題の追加順を指定できるようにし、実装のコストを少しだけ低減

Solved by #1174

KATO-Hiro avatar Aug 28 '24 04:08 KATO-Hiro