Content
View differences
Updated by Alexander Coles 1 day ago
This work package tracks how we transition from Dragula to Pragmatic Drag and Drop across the application: rollout order, guardrails, and what each remaining consumer needs.
> **Note:** originally this WP was about *defining* the migration strategy and abstraction layer. Both now exist — this WP was rewritten on 2026-07-12 into the rollout tracker.
### Decisions so far
* **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).
* **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.
* **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).
### Rollout sequence
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** — decided gated on the decision in #DREAM-678 (2026-07-13): `DragAndDropService` rewrite on Pragmatic (#DREAM-756, children #DREAM-757 boards, #DREAM-758 WP table/card/grid, #DREAM-759 (boards, work-package table/card view, team planner, BIM BCF, #DREAM-760 BCF list, draggable autocompleter, grids widgets), plus direct migrations #DREAM-755 (draggable autocompleter) and #DREAM-761 (team planner) widgets)
5. **Remove the `dragula` npm dependency** once no consumer remains — #DREAM-762. remains.
### Guardrails
* No new Dragula consumers.
* One 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.)
* Accessibility and mobile expectations (WCAG 2.1, touch) apply to every migrated surface: a11y follow-ups #AGILE-323 / #AGILE-324, touch #AGILE-293.
* Same-list optimistic reordering on any new surface follows the #AGILE-322 response contract.
> **Note:** originally this WP was about *defining* the migration strategy and abstraction layer. Both now exist — this WP was rewritten on 2026-07-12 into the rollout tracker.
### Decisions so far
* **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).
* **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.
* **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).
### Rollout sequence
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** — decided
5. **Remove the `dragula` npm dependency** once no consumer remains — #DREAM-762.
### Guardrails
* No new Dragula consumers.
* One 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.)
* Accessibility and mobile expectations (WCAG 2.1, touch) apply to every migrated surface: a11y follow-ups #AGILE-323 / #AGILE-324, touch #AGILE-293.
* Same-list optimistic reordering on any new surface follows the #AGILE-322 response contract.