Content
View differences
Updated by Alexander Coles about 17 hours ago
This work package tracks how we transition from Dragula to Pragmatic Drag and Drop a new DnD solution across the application: rollout order, guardrails, and what each remaining consumer needs. application.
> **Note:** originally this WP was about *defining* the Focus:
* avoid fragmentation across libraries
* define a shared abstraction layer
* enable gradual migration strategy and
### Scope
* Define a **DnD abstraction layer. Both now exist — this WP was rewritten on 2026-07-12 into the layer**
* Standardize interaction patterns:
* list sorting
* cross-container moves
* multi-select behavior
* Ensure compatibility with:
* Stimulus controllers
* Turbo/morphing updates
* Define rollout tracker.
plan:
* backlog → boards → other features
### Decisions so far Key considerations
* **Library**: Atlassian Pragmatic Drag and Drop, selected via the weighted evaluation in #PT-139. Evaluations: #DREAM-673 (dnd-kit — not selected), #DREAM-674 (Pragmatic — selected), #DREAM-675 (extend Dragula — rejected), #DREAM-676 (SortableJS — rejected).
Avoid direct coupling to any single library
* **Abstraction layer**: the reusable `sortable-lists` Stimulus suite — root/list/item controllers, pure drop-intent resolution (`drag-and-drop.ts`), a DnD-agnostic DOM contract (`list-dom.ts`), and a Turbo morph guard (`pragmatic-dnd-morph-attributes.ts`). Shape decided in #AGILE-292, implemented in https://github.com/opf/openproject/pull/23218.
Ensure:
* **Optimistic update contract**: successful same-list reorders answer with an event-only turbo-stream (no frame re-render) carrying `WORK_PACKAGE_MOVED_EVENT`; failures and cross-list moves keep the full frame reload. Decided in #AGILE-322 / https://github.com/opf/openproject/pull/24157 (a bare `204 No Content` was rejected — no body to carry the event).
accessibility support
* mobile compatibility
* extensibility
### Rollout sequence Current assessment
1. **Backlogs** — in review. #AGILE-291 (implementation: #AGILE-251, #AGILE-284, #AGILE-322; PRs https://github.com/opf/openproject/pull/23218, https://github.com/opf/openproject/pull/24157)
2. **Shared `generic-drag-and-drop.controller.ts` consumers** — #DREAM-671 (admin/settings sortable lists, work-package type export templates, meetings subclass)
3. **Independent Dragula Stimulus controllers** — `reporting/page.controller.ts`, `admin/type-form-configuration/rows-drag-and-drop.controller.ts`, `admin/custom-fields.controller.ts`
4. **Angular surfaces** — gated on the decision in #DREAM-678 (boards, work-package table/card view, team planner, BIM BCF list, draggable autocompleter, grids widgets)
5. **Remove the `dragula` npm dependency** once no consumer remains. ⚠️ **Critical path work**
### Guardrails Without this:
* No new Dragula consumers.
migration will fragment
* One multiple DnD foundation: new work builds on the `sortable-lists` primitives; avoid per-feature forks. (Angular CDK drag-drop usages are out of scope and stay on CDK until those surfaces are rewritten — see #DREAM-678.)
implementations will coexist
* Accessibility and mobile expectations (WCAG 2.1, touch) apply long-term maintenance cost will increase
### Decision status
➡️ Must be completed before full migration
### Linked PRs
* (links to every migrated surface: a11y follow-ups #AGILE-323 / #AGILE-324, touch #AGILE-293.
be added as implementation progresses)
* Same-list optimistic reordering on any new surface follows the #AGILE-322 response contract. references:
* dnd-kit experiments (WP #74176)
* Pragmatic DnD experiments (WP #74175)
* Dragula extensions (WP #74174)
> **Note:** originally this WP was about *defining* the
* avoid fragmentation across libraries
* define a shared abstraction layer
* enable gradual
### Scope
* Define a **DnD
* Standardize interaction patterns:
* list sorting
* cross-container moves
* multi-select behavior
* Ensure compatibility with:
* Stimulus controllers
* Turbo/morphing updates
* Define
* backlog → boards → other features
* **Library**: Atlassian Pragmatic Drag and Drop, selected via the weighted evaluation in #PT-139. Evaluations: #DREAM-673 (dnd-kit — not selected), #DREAM-674 (Pragmatic — selected), #DREAM-675 (extend Dragula — rejected), #DREAM-676 (SortableJS — rejected).
* mobile compatibility
* extensibility
1. **Backlogs** — in review. #AGILE-291 (implementation: #AGILE-251, #AGILE-284, #AGILE-322; PRs https://github.com/opf/openproject/pull/23218, https://github.com/opf/openproject/pull/24157)
2. **Shared `generic-drag-and-drop.controller.ts` consumers** — #DREAM-671 (admin/settings sortable lists, work-package type export templates, meetings subclass)
3. **Independent Dragula Stimulus controllers** — `reporting/page.controller.ts`, `admin/type-form-configuration/rows-drag-and-drop.controller.ts`, `admin/custom-fields.controller.ts`
4. **Angular surfaces** — gated on the decision in #DREAM-678 (boards, work-package table/card view, team planner, BIM BCF list, draggable autocompleter, grids widgets)
5. **Remove the `dragula` npm dependency** once no consumer remains.
### Guardrails
* No new Dragula consumers.
### Decision status
➡️ Must be completed before full migration
### Linked PRs
* (links
* dnd-kit experiments (WP #74176)
* Pragmatic DnD experiments (WP #74175)
* Dragula extensions (WP #74174)