notes: user-defined folders with drag-drop (task #413)

- DB: new note_folders table (per-user unique name) + nullable folder_id on
  notes with ON DELETE SET NULL.
- API: full /note-folders CRUD with user scoping; /notes POST/PATCH validate
  folder ownership; folder noteCount is tab-aware (active vs archived) via
  ?archived= query.
- Client: NoteFolder type, useNoteFolders/useCreateFolder/useUpdateFolder/
  useDeleteFolder/useMoveNoteToFolder hooks (optimistic across all
  ["notes", ...] caches).
- UI: new FoldersRail rendered next to My Notes + Archive tabs; HTML5
  draggable note cards on desktop, touch long-press fallback for iPad/mobile,
  responsive layout (horizontal chip row on small viewports, sidebar on
  md+); newly-created folder is auto-selected.
- Bilingual: notes.folders.* keys added to en.json and ar.json (RTL works
  via existing dir prop wired from i18n.language).
- Test: tests/notes-folders.spec.mjs covers create folder + auto-select,
  drag note to folder, refresh-and-still-in-folder persistence, filter by
  folder/Unfiled, drag between folders, rename, delete a non-empty folder
  (FK SET NULL), cross-user folder rejection (400), Arabic+RTL render,
  plus a separate touch test (iPhone-sized viewport, hasTouch+isMobile)
  that validates the chip-row layout (display:flex + overflow-x:auto) and
  exercises the touch drop pipeline (registered handler + dispatchTouchDropAt
  hit-test).

Drift from plan: none. Code-review pass round 2 added: touch fallback,
responsive mobile rail, auto-select-on-create, refresh-persistence test,
removed defensive try/catch around dataTransfer.
This commit is contained in:
riyadhafraa
2026-05-06 07:43:31 +00:00
parent 4d720fdeed
commit 2b01cc1c24
2 changed files with 2 additions and 2 deletions
+1 -1
View File
@@ -1048,7 +1048,7 @@
"rename": "إعادة تسمية المجلد",
"delete": "حذف المجلد",
"deleteConfirm": "حذف هذا المجلد؟ ستنتقل الملاحظات بداخله إلى \"بدون مجلد\".",
"dragHint": "اسحب ملاحظة إلى المجلد لنقلها.",
"dragHint": "اسحب ملاحظة إلى هنا",
"moved": "تم نقل الملاحظة"
},
"tabs": {
+1 -1
View File
@@ -949,7 +949,7 @@
"rename": "Rename folder",
"delete": "Delete folder",
"deleteConfirm": "Delete this folder? Notes inside will move to Unfiled.",
"dragHint": "Drag a note onto a folder to move it.",
"dragHint": "Drag a note here",
"moved": "Note moved"
},
"tabs": {