feat: add drag-to-reorder for kanban and task-list views#1619
feat: add drag-to-reorder for kanban and task-list views#1619ac8318740 wants to merge 5 commits intocallumalpass:mainfrom
Conversation
Implement card-level drag-and-drop reordering within kanban columns. Dragging a card above or below another card computes a new sort_order using a midpoint insertion algorithm and writes it to frontmatter. New capabilities: - Card-level dragover/drop handlers with top/bottom half detection - Visual drop indicators (accent-colored bar above or below target) - Midpoint insertion: new_value = floor((neighbor_above + neighbor_below) / 2) - Vault-wide neighbor lookup so filtered/hidden tasks are still considered when computing midpoints (prevents order collisions) - Proportional gap computation based on median spacing in the column - Collision handling: when neighbors share identical sort_order values, renumber all column tasks evenly across the existing value range - Deferred re-render during drag to prevent DOM destruction mid-drop - Same-column detection to skip unnecessary group property writes Supporting changes: - Add sortOrder field to TaskInfo interface and FieldMapping - Add sort_order to FieldMapper read/write and default field mapping - Add columnTasksCache for render-time group data - Add sort_order to e2e vault kanban view config - Add CSS for drop-above/drop-below position indicators
Extract sort_order computation from KanbanView into sortOrderUtils.ts as free functions (computeSortOrder, getGroupTasks, renumberAndInsert, isSortOrderInSortConfig, stripPropertyPrefix) so both views share the same midpoint insertion algorithm without code duplication. Add drag-to-reorder to TaskListView: - Container-level drag event delegation (dragenter/dragover/drop) with unconditional e.preventDefault() as required by the HTML5 DnD spec - Within-group reordering: cards get draggable="true" when sort_order is in the view's sort config - Cross-group dragging: detects group changes via a taskGroupKeys map (populated at render time) and updates the group property via TaskService.updateProperty alongside the sort_order write - Deferred re-render during drag to prevent DOM destruction mid-drop - Works in both flat and grouped modes; gracefully skipped in virtual scrolling paths Simplify .task-card--dragging CSS: remove rotate/scale transforms and pointer-events:none that caused adjacent cards to steal hit-test events during drag. Add drop indicator pseudo-elements (::before/::after) for visual feedback in task-list-view.css.
…ttings The drag-to-reorder feature hardcoded "sort_order" as the frontmatter property name. This wires it through the existing FieldMapping system so users can customise it in Settings > Task Properties, just like every other property. - sortOrderUtils: replace 3 hardcoded "sort_order" references with plugin.settings.fieldMapping.sortOrder - isSortOrderInSortConfig: accept sortOrderField param so the sort config check uses the mapped name - TaskListView / KanbanView: pass the mapped field name to all isSortOrderInSortConfig calls - taskPropertiesTab: add Sort Order property card in Metadata section - en.ts: add translation keys for the new settings card Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks so much for pushing this, @ac8318740 ! I’ve been interested drag-to-reorder in TaskNotes for a long time (see issues #186 , #219 , #621, #701) and hadn’t been brave enough to tackle it myself. This gets close and the direction is strong. After testing in my vault, I’m seeing a few blocking robustness issues:
My suggestion for the next iteration: switch the ordering model to LexoRank (string ranks) and make DnD placement strictly swimlane-aware when swimlanes are enabled. This will require a lot of manual testing. I’d prioritize robustness over minimal complexity here, because this feature will get heavy use once merged. Thank you for doing the hard part of getting this moving! |
…ew issues Replace numeric midpoint sort_order with LexoRank string-based ordering. This addresses robustness issues from PR review: buggy reordering when notes lack sort_order, hardcoded "sort_order" field name, and duplicated between-tasks logic. - Extract rankBetween() helper with try/catch around LexoRank.between() - Add ensureRank() to lazily assign LexoRank to unranked neighbors - Thread sortOrderField param instead of re-reading settings per call - Fix hardcoded "sort_order" writes in KanbanView and TaskListView - Change sortOrder type from number to string across types and FieldMapper - Pin lexorank dependency to 1.0.5 (no caret) - Remove orphaned JSDoc stubs in KanbanView - Pass swimlane params through to computeSortOrder in KanbanView
…ag bugs - Fix column expand/contract glitch: replace `transition: all` with specific properties and remove scale(1.02) transform on dragover columns - Fix wrong drop position when dragging upward: collapse dragged card's layout space after browser captures drag image, removing the phantom element that distorted sibling getBoundingClientRect values - Replace thin 3px accent line with animated gap/slot pattern where sibling cards shift apart via translateY to show the drop position - Lock source column min-height during drag so collapsing the dragged card doesn't shrink the priority bucket - Clip overflow on cards container during drag so translateY shifts don't cause scrollbars - Suppress hover background-color, transform, and box-shadow on all task cards during active drag via body-level .tn-drag-active class - Add rAF throttling to dragover handlers (preventDefault stays synchronous) - Support cross-column drag: detect container change, clean old, set up new - Respect prefers-reduced-motion: reduce for shift animations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks so much for the review – really appreciate you getting to it so quickly. I've pushed an update that hopefully addresses everything you flagged:
Also reworked the drop indicator UX while I was in there – replaced the thin accent line with an animated gap/slot pattern (cards shift apart to show where the drop will land), and fixed a couple of visual bugs with column resizing during drag. |
Summary
Adds drag-to-reorder for both kanban and task-list views using a
sort_orderfrontmatter property.The point of this is to let you prioritize tasks within a priority group, e.g. ordering your three "high" priority tasks in the sequence you actually want to do them. This is groundwork for auto-scheduling: once tasks have a stable intra-group ordering, a scheduler can slot them into time blocks without the user having to re-specify intent.
What's included
sort_orderand the group property)sortOrderUtils.ts: extracted free functions (computeSortOrder,getGroupTasks,renumberAndInsert, etc.) so both views use the same algorithmsortOrderfield inTaskInfo, default field mapping, read/write supportsort_order)Configurable sort order property
The sort order property name is wired through the existing
FieldMappingsystem, the same system used by every other property (status, priority, due, etc.). This means:sort_order, so existing users are unaffectedDesign notes
new_value = floor((above + below) / 2)gives O(1) placement without rewriting the whole listTest plan