# Feature AGILE-291 - Foundations for improved Drag and Drop, gesture support

Project: Stream agile
Status: closed
URL: https://community.openproject.org/work_packages/AGILE-291

## Planning

| Attribute | Value |
| --- | --- |
| Date |  |
| Priority | Medium |
| Target versions | 17.7.0 |
| Sprint | Sprint 7 |
| Backlog bucket |  |
| Votes |  |
| List | a11y report 2026 |
| Roadmap |  |
| Relevance |  |

## OPEN POINTS / FEEDBACK

| ID | Subject | Status | Decision |
| --- | --- | --- | --- |
| AGILE-292 | Decide shape of Stimulus sortable-lists controller | decided |  |

## Features and Chunks

| ID | Subject | Type | Status | Assignee | Target versions | Spent time |
| --- | --- | --- | --- | --- | --- | --- |
| AGILE-251 | Migrate Backlogs to Pragmatic DnD | Implementation | closed |  | 17.7.0 |  |
| AGILE-284 | Implement support for optimistic reordering | Implementation | closed |  | 17.7.0 |  |
| AGILE-322 | Implement server support for optimistic reordering | Implementation | closed |  | 17.7.0 |  |
| AGILE-323 | Keyboard and screen-reader follow-ups | Implementation | closed |  | 17.7.0 |  |
| AGILE-324 | Implement live-region announcements | Implementation | closed |  | 17.7.0 |  |
| AGILE-343 | Extract a generic Turbo frame reload probe for feature specs | Implementation | closed |  | 17.7.0 |  |

## Bugs and other work packages

| ID | Type | Subject | Status | Assignee | Target versions | Spent time | Module |
| --- | --- | --- | --- | --- | --- | --- | --- |
| AGILE-358 | Bug | Work packages are shuffled when dragging a work package to it's original position. | closed |  | 17.7.0 |  | Modules and project features / Backlogs, Frontend components and Primer design system |
| AGILE-365 | Bug | [iPadOS/Safari] User sees a 'submit for again' warning when reloading page after re-ordering WPs + re-submitting shows 404 | rejected |  | 17.7.0 |  | Native apps / Mobile, Modules and project features / Backlogs, Frontend components and Primer design system |
| AGILE-366 | Bug | Backlogs: autoscroll doesn't work on DnD on Chrome/Android | needs clarification | Alexander Coles | Product Backlog |  | Modules and project features / Backlogs |
| AGILE-261 | Task | Illustrate different states of a backlog/sprint work package card  | closed | Parimal Satyal |  |  |  |

## Technical Details

| Attribute | Value |
| --- | --- |
| Module | Modules and project features / Backlogs, Frontend components and Primer design system |
| Feature Flag |  |
| Requires doc change | Yes |
| Enterprise plan |  |

## Details

| Attribute | Value |
| --- | --- |
| Pull preview |  |
| Mockups |  |
| Accessibility | Yes |

## People

| Attribute | Value |
| --- | --- |
| Assignee |  |
| Accountable |  |
| Product manager |  |
| Developers | OP Dev Polaris Team |
| Designer | Parimal Satyal |
| Ordered by |  |
| Signed off by |  |
| Interest by |  |

## Estimates and progress

| Attribute | Value |
| --- | --- |
| PD (min) |  |
| PD (max) |  |
| Work |  |
| Labor costs |  |

## Description

**As** a user of OpenProject's Backlogs module
**I want to** use drag and drop to move items
**so that** I can manage my backlogs, buckets and sprints effectively.

### Preamble

#### Supported browsers

  - All evergreen desktop browsers (tested in Chrome, Firefox, Edge, Safari)

  - Safari and Webkit-based browsers (including Firefox, Edge) on latest iOS, iPadOS

  - Chrome on Android

#### Unsupported browsers

  - Firefox on Android (see <https://caniuse.com/dragndrop>)

#### Platform note: drag preview

The floating drag preview is rendered natively by the browser/OS and cannot be fully styled. Its appearance (transparency, scaling, offset from the pointer) differs between Chrome, Firefox, Safari and Edge, and again on touch devices (iOS/iPadOS render their own lift preview). Scenarios describing the preview are indicative - QA should not expect pixel-identical rendering across platforms (however, do file a bug if you consider the platform/browser-specific behavior presents a usability issue).

### Acceptance Criteria (Refined)

#### Scenario 1: Reordering within the same list

  - **Given** a user with "manage backlog/sprint items" permissions

  - **When** they drag a Work Package card up or down within its current list

  - **Then** a visual drop indicator (highlighted gap) appears at valid drop positions.

  - **And When** they drop the card

  - **Then** the card *instantly* moves to the new position (optimistic update).

  - **And** the new order is persisted to the server.

  - **And** refreshing the page confirms the new order.

#### Scenario 2: Moving between lists

  - **Given** a user with "manage backlog/sprint items" permissions

  - **When** they drag a card from an Inbox backlog

  - **And** hover over an empty Sprint list

  - **Then** the empty Sprint list visually indicates (blue outline, "Drop here" message) it can accept the drop

  - **When** they drop the card

  - **Then** the card instantly appears in the Sprint list.

  - **And** the move is persisted to the server.

  - **And** refreshing the page confirms the move.

#### Scenario 3: Missing Permissions

  - **Given** a user **without** "manage backlog/sprint items" permissions

  - **When** they attempt to click and drag a Work Package card

  - **Then** the card cannot be picked up (no drag state is initiated).

#### Scenario 4: Optimistic Update Failure (Server Error)

*N.B. for QA – it may be difficult to simulate a failure on QA instance.*

  - **Given** a user drags and drops a card to a new position

  - **When** the server returns an error (e.g., network failure or concurrent edit)

  - **Then** the card reverts to its original position.

  - **And** an error flash notice is displayed explaining the failure.

  - **And** the rollback is announced to screen readers (see Scenario 8).

#### Scenario 5: Card Visibility After Move

  - **Given** a user's current view filters out closed items

  - **When** they drag a card into a Sprint where a workflow rule automatically closes it

  - **Then** the card disappears from the view.

  - **And** a notification/toast is shown informing the user that the moved item is no longer visible in the current view.

#### Scenario 6: Auto-scrolling

  - **Given** a Backlogs list with a vertical scrollbar

  - **When** a user drags a card to the top 10% or bottom 10% of the list container

  - **Then** the list automatically scrolls in that direction.

  - **And** the list only scrolls in a vertical direction

#### Scenario 7: Accessibility (Non-Drag Fallback)

  - **Given** any Work Package card

  - **When** the user opens the card's action menu

  - **Then** they can move the card higher / lower / to top / to bottom within its list without using drag and drop.

  - **And** they can move it to a different Sprint or Backlog bucket via the move dialogs.

  - **And** these paths also work in browsers without drag-and-drop support (e.g. Firefox on Android).

  - **And** successful moves are announced to screen readers (see Scenario 8).

#### Scenario 8: Screen-Reader Announcements (<mention class="mention" data-id="AGILE-324" data-type="work_package" data-text="#AGILE-324">#AGILE-324</mention>)

  - **Given** a screen-reader user moves a card via drag and drop or the card's move menu

  - **Then** a polite live-region announcement fires as soon as the card is optimistically placed, stating the new position (e.g. "moved to position 3 of 7") and, for cross-list moves, the destination list.

  - **When** a card is moved via the move-to-sprint/bucket dialog and remains visible at a changed position

  - **Then** the success is announced via a server-sent live-region update.

  - **When** a move fails due to a network error and is rolled back

  - **Then** an assertive announcement informs the user that the move failed and the card returned to its original position.

  - **And** validation failures (HTTP 422) are announced once via the error flash only (no double announcement).

  - **And** moves after which the card is no longer visible are announced via the existing flash notice (see Scenario 5).

#### Scenario 9: Visual State While Dragging

  - **Given** a user picks up a Work Package card

  - **Then** the original card remains in the list at reduced opacity as a "ghost" placeholder.

  - **And** a drag preview of the card follows the pointer (rendered natively - see the platform note in the Preamble; exact appearance varies by browser and device).

  - **When** the drag ends (drop or cancel)

  - **Then** the placeholder returns to full opacity.

#### Scenario 10: Cancelling a Drag

  - **Given** a user is dragging a card

  - **When** they press Escape or release the card outside any valid drop target

  - **Then** the card returns to its original position.

  - **And** no reorder is persisted (no server request is made).

#### Scenario 11: Touch Drag and Drop

  - **Given** a user on a supported touch device (Safari on iOS/iPadOS, Chrome on Android)

  - **When** they long-press a card and drag

  - **Then** the card can be picked up and moved within and between lists as in Scenarios 1 and 2.

  - **And** auto-scrolling (Scenario 6) also works during a touch drag.

  - **And** normal page scrolling by swipe still works when no card is being dragged.

#### Scenario 12: Partially Loaded Lists (Truncated Inbox)

  - **Given** an Inbox backlog that is truncated (only part of its items rendered)

  - **When** a user drags a card within or into the loaded region

  - **Then** the drop works and the position is persisted correctly.

  - **And** cards can only be dropped into currently loaded regions of the list.

  - **And** announced positions count omitted items (i.e. the absolute position within the whole list).

### Technical Notes

  - Part of the cross-application drag-and-drop epic <mention class="mention" data-id="DREAM-672" data-type="work_package" data-text="#DREAM-672">#DREAM-672</mention>: the `sortable-lists` suite built here is the shared DnD foundation, and Backlogs is its first consumer.

  - Migrating Backlogs DnD from dragula to Atlassian Pragmatic DnD (<mention class="mention" data-id="AGILE-251" data-type="work_package" data-text="#AGILE-251">#AGILE-251</mention>).

  - Reusable `sortable-lists` Stimulus primitive in `frontend/src/stimulus/controllers/dynamic/`; Backlogs is the first consumer.

  - Controller topology: single root per page + leaf controllers for list/item.

  - Live-region announcements shipped with <mention class="mention" data-id="AGILE-324" data-type="work_package" data-text="#AGILE-324">#AGILE-324</mention> (<https://github.com/opf/openproject/pull/24270>): the client announces optimistic placements and network-failure rollbacks; the server announces dialog moves via the `liveRegion` turbo-stream action.

  - Related: <mention class="mention" data-id="AGILE-175" data-type="work_package" data-text="#AGILE-175">#AGILE-175</mention>, <mention class="mention" data-id="AGILE-181" data-type="work_package" data-text="#AGILE-181">#AGILE-181</mention>, <mention class="mention" data-id="AGILE-278" data-type="work_package" data-text="#AGILE-278">#AGILE-278</mention>, <mention class="mention" data-id="AGILE-284" data-type="work_package" data-text="#AGILE-284">#AGILE-284</mention>.

### **Out of scope**

  - Multi-select and batch move (<mention class="mention" data-id="AGILE-181" data-type="work_package" data-text="#AGILE-181">#AGILE-181</mention>).

  - Reordering whole Backlogs lists, buckets, or sprints (<mention class="mention" data-id="AGILE-175" data-type="work_package" data-text="#AGILE-175">#AGILE-175</mention>).

  - advanced gestures beyond basic touch drag.

  - Keyboard-operable drag-and-drop: all actions are available via action menu.

  - Drop rejection feedback (suppressing the drop indicator and "Drop here" affordance for targets that cannot accept an item, e.g. restricted work package types): not yet implemented. An initial `canDrop` gate was reverted because it also disabled reordering within the card's own list; the feedback needs to be suppressed in the indicator layer instead. Needs a follow-up ticket.
