Skip to content

feat: add drag-to-reorder for kanban and task-list views#1619

Open
ac8318740 wants to merge 3 commits intocallumalpass:mainfrom
ac8318740:feat/drag-to-reorder
Open

feat: add drag-to-reorder for kanban and task-list views#1619
ac8318740 wants to merge 3 commits intocallumalpass:mainfrom
ac8318740:feat/drag-to-reorder

Conversation

@ac8318740
Copy link

@ac8318740 ac8318740 commented Feb 17, 2026

Summary

Adds drag-to-reorder for both kanban and task-list views using a sort_order frontmatter 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

  • Kanban view: card-level drag-and-drop reordering within columns, midpoint insertion algorithm, collision handling (renumbers when neighbours share identical values)
  • Task-list view: drag-to-reorder within groups, plus cross-group dragging (updates both sort_order and the group property)
  • Shared sortOrderUtils.ts: extracted free functions (computeSortOrder, getGroupTasks, renumberAndInsert, etc.) so both views use the same algorithm
  • FieldMapper / types: sortOrder field in TaskInfo, default field mapping, read/write support
  • CSS: drop indicator pseudo-elements for visual feedback, simplified drag styling to fix hit-test issues
  • Configurable property name: the frontmatter property used for sort order is configurable via Settings > Task Properties > Metadata Properties > Sort Order (defaults to sort_order)

Configurable sort order property

The sort order property name is wired through the existing FieldMapping system, the same system used by every other property (status, priority, due, etc.). This means:

  • Default behaviour is unchanged - the default mapping is sort_order, so existing users are unaffected
  • Users can customise it in Settings > Task Properties, in the Metadata Properties section, via a "Sort Order" property card

Design notes

  • Midpoint insertion: new_value = floor((above + below) / 2) gives O(1) placement without rewriting the whole list
  • Vault-wide neighbour lookup so filtered/hidden tasks are still considered (prevents collisions)
  • Container-level drag event delegation so it works with both normal and virtual-scrolling rendering
  • Deferred re-render during drag to prevent DOM destruction mid-drop

Test plan

  • Existing unit tests pass (FieldMapper, bases)
  • Drag a card within a kanban column, verify order persists after reload
  • Drag a card in a grouped task-list, verify it stays in position
  • Drag a card between groups in task-list, verify the group property updates
  • Rapidly reorder many cards to trigger collision renumbering, verify no duplicate sort_order values
  • Change the sort order field mapping in settings to a custom name, confirm drag-to-reorder reads/writes the custom property
  • Confirm drag-to-reorder only activates when the view is sorted by the configured property name

ac8318740 and others added 3 commits February 16, 2026 04:46
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>
@callumalpass
Copy link
Owner

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:

  • When most notes don’t already have sort_order, reordering is pretty buggy and can land notes in unexpected places.
  • Kanban drag/reorder in swimlane mode is unreliable
  • There are still paths where writes look hardcoded to sort_order, which breaks custom mappings.

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants