# Feature DREAM-876 - Provide move context menu actions in the Work Packages table

Project: Stream Design System
Status: merged
URL: https://community.openproject.org/work_packages/DREAM-876

## Planning

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

## OPEN POINTS / FEEDBACK

_No work packages_

## Features and Chunks

| ID | Subject | Type | Status | Assignee | Target versions | Spent time |
| --- | --- | --- | --- | --- | --- | --- |
| DREAM-974 | Reorder one or more work packages from the context menu in flat, grouped, and hierarchy tables | Implementation | closed |  | 18.0.0 |  |
| DREAM-982 | Use Primer ActionMenu for work package table context menus and column menus | Implementation | closed |  | 18.0.0 |  |

## Bugs and other work packages

| ID | Type | Subject | Status | Assignee | Target versions | Spent time | Module |
| --- | --- | --- | --- | --- | --- | --- | --- |
| DREAM-1013 | Task | Screen-reader verification: Reorder work packages using move actions | specified |  | 18.0.0 |  |  |

## Technical Details

| Attribute | Value |
| --- | --- |
| Module | Frontend components and Primer design system, Modules and project features / Work packages, Accessibility |
| Feature Flag |  |
| Requires doc change | Yes |
| Enterprise plan | Community (COM) |

## Details

| Attribute | Value |
| --- | --- |
| Pull preview | https://pr-26724-dream-974-table-mov-ip-2-31-205-44.my.opf.run:443 |
| Mockups |  |
| Accessibility | Yes |

## People

| Attribute | Value |
| --- | --- |
| Assignee |  |
| Accountable |  |
| Product manager |  |
| Developers | Alexander Coles |
| Designer | Julia Racsko |
| Ordered by |  |
| Signed off by |  |
| Interest by |  |

## Estimates and progress

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

## Description

**As** a keyboard or screen-reader user working in a manually sorted work package table
**I want to** move work packages up, down, to the top or to the bottom from their context menu
**so that** I can change the manual order without drag-and-drop.

### Background

Manual sorting in the work package table is only operable by pointer drag-and-drop. <mention class="mention" data-id="DREAM-846" data-type="work_package" data-text="#DREAM-846">#DREAM-846</mention> brings cell navigation, keyboard selection and a keyboard-openable context menu to the table but leaves keyboard manual sorting and grab-and-drop out of scope. This feature closes that gap with context menu actions, the same way Backlogs and Sortable Lists offer move actions next to drag-and-drop.

### Implementation and review order

1.  <mention class="mention" data-id="DREAM-982" data-type="work_package" data-text="#DREAM-982">#DREAM-982</mention> introduces ActionMenu for row, bulk and column menus, including nested menu support, and turns column headers and the row **⋯** trigger into real menu buttons. [PR <mention class="mention" data-id="26723" data-type="work_package" data-text="#26723">#26723</mention>](https://github.com/opf/openproject/pull/26723)
2.  <mention class="mention" data-id="DREAM-974" data-type="work_package" data-text="#DREAM-974">#DREAM-974</mention> adds all move commands for flat tables, groups, siblings and selections. [PR <mention class="mention" data-id="26724" data-type="work_package" data-text="#26724">#26724</mention>](https://github.com/opf/openproject/pull/26724)
3.  Follow-up changes to the row and column menus, see below. [PR <mention class="mention" data-id="26873" data-type="work_package" data-text="#26873">#26873</mention>](https://github.com/opf/openproject/pull/26873)

### Acceptance criteria

  - When the table is manually sorted, the row context menu offers **Move to top**, **Move up**, **Move down** and **Move to bottom** in a **Move to position** submenu, with the same labels as the Backlogs card menu.
  - Actions that cannot apply are disabled, not hidden: **Move up**/**Move to top** on the first row, **Move down**/**Move to bottom** on the last row.
  - The actions appear only when the table is manually sorted, drag-and-drop is enabled for that table, and the user may reorder the query. They do not appear in automatically sorted tables, read-only query views, or tables without drag-and-drop.
  - In grouped tables a work package moves within its group; the group boundaries are the edges and its group attribute does not change.
  - In hierarchy tables a work package moves within its siblings, together with its descendants; the parent does not change (**Indent**/**Outdent** remain the way to change it).
  - When the manually sorted table shows only part of the results (the existing limited-results notice), the actions work on the shown rows; **Move to bottom** places the work package after the last shown row.
  - With several work packages selected, the same actions in the selection's context menu move them together as one block, keeping their relative order. They are disabled when the whole block cannot move that way, and absent in grouped or hierarchy tables unless all selected work packages share a group or a parent.
  - Moving persists the order the same way drag-and-drop does, and the rows re-render at their new positions without a full table reload.
  - After a move, keyboard focus stays on the moved work package and the selection is unchanged.
  - The result is announced to assistive technology, e.g. "Alpha moved to position 3 of 12", or "3 items moved to positions 1 through 3 of 12" for several work packages.

### Follow-up menu changes

These came out of the review of the new menus. They are only loosely related to the move actions and are tracked here for lack of a better place.

**Work package context menu**

  - Entries are ordered into groups separated by dividers: opening and copying, logging, organizing, exporting, deleting. The same order applies to the menu of the full and split views, the card view and the calendar.
  - **Copy link** becomes **Copy link to clipboard**, **Copy ID** becomes **Copy work package ID** and the **Move** submenu becomes **Move to position**, at the top of its group.
  - **Delete** is shown in the danger scheme.
  - Icons follow the SPOT to Octicon mapping: `hash` for **Copy work package ID**, `op-budget` for **Log unit costs**, `package-dependents` for **Add predecessor**. The Backlogs card menu uses `op-view-fullscreen` for **Open fullscreen view**.

**Column menus**

  - **Sort descending** and **Sort ascending** show a checkmark when the column is the primary sort criterion in that direction, in the work package table and the projects list.
  - The grouping item names the column, e.g. **Group by Status**. The filter item of the projects list does the same, e.g. **Filter by Status**.
  - **Insert columns** (work packages) and **Add column** (projects) become **Add columns**. **Hide column** (work packages) becomes **Remove column**. In both tables it uses the `x-circle` icon, is no longer shown in the danger scheme and has no divider before it.

**Table headers**

  - The sorted column shows its direction with the `sort-asc` / `sort-desc` Octicons in the work package table, the generic table and the projects list, replacing the icon font glyph.

### Technical notes

  - Flat-table menu moves reuse the drag-and-drop move path (`WorkPackageViewOrderService.prepareMove`, persist, re-render, focus retention through #DREAM-846's focus owner, row positions repainted through the table's mutation protocol from <mention class="mention" data-id="DREAM-959" data-type="work_package" data-text="#DREAM-959">#DREAM-959</mention>). Group, sibling and selection moves prepare the order with the same service (`prepareMove`, `prepareBlockMove`) and re-render the reordered rows without a full table reload.
  - `PATCH /api/v3/queries/:id/order` already accepts a delta for several work packages; a multi-row variant of the client-side delta builder (`buildBlockDelta`) persists a selection in one request.
  - The table uses Primer ActionMenu for nested commands. Disabled menu items expose `aria-disabled`.
  - Availability: `WorkPackageViewSortByService.isManualSortingMode`, the table's `dragAndDropEnabled` configuration, and the query's `updateOrderedWorkPackages` link (or an unsaved query). Table drag-and-drop does not check that link today; this feature does not change drag-and-drop.

### Permissions and visibility considerations

  - Visible only in manually sorted tables with drag-and-drop enabled, to users who may reorder the query.

### Translation considerations

  - "Move to top" and "Move to bottom" are new keys in the frontend locale (`js.label_sort_highest`, `js.label_sort_lowest`), copied from the existing Rails `label_sort_highest`/`label_sort_lowest`; "Move up"/"Move down" already exist.
  - Announcements reuse `js.sortable_lists.announcements.moved` and `moved_batch`.

### Out of scope

  - Keyboard grab-and-drop (Space to pick up, arrows to move).
  - Moving across pages, groups or parents.
  - Changing non-manual sort orders.
  - Drag-and-drop behaviour changes.
  - Boards (they share the order service; candidate follow-up).
