You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: API.md
+18Lines changed: 18 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -310,6 +310,24 @@ Invalid column keys in `cursorByColumn` or malformed cursors → `VALIDATION_ERR
310
310
311
311
---
312
312
313
+
## REST: Dashboard assigned todos (`GET /api/dashboard/todos`)
314
+
315
+
The web app and other REST clients use this endpoint (separate from MCP). In **full** mode it requires a valid **session cookie** or **`Authorization: Bearer`** API token.
316
+
317
+
Query parameters:
318
+
319
+
-**`limit`** (optional): page size; default **20**, maximum **100**.
320
+
-**`sort`** (optional): **`activity`** (default) or **`board`**. Invalid or empty values are treated as **`activity`** (backward compatible).
321
+
-**`cursor`** (optional): pagination token from the previous JSON response’s **`nextCursor`** field.
322
+
323
+
**Activity sort** (default): rows are ordered by **`updated_at` DESC, `id` DESC**. The cursor is **`updatedAtMs:id`** (two integers, colon-separated, Unix ms for the todo’s `updated_at`).
324
+
325
+
**Board sort** (`sort=board`): rows are ordered by **`project_id` ASC, workflow column `position` ASC, `rank` ASC, `id` ASC**, matching board order within each project. Cross-project order follows numeric project id, not name or recency. The cursor is **`projectId:wcPosition:rank:todoId`** (four integers, colon-separated).
326
+
327
+
A **`cursor`** that does not match the selected **`sort`** (for example, an activity cursor while `sort=board`) is rejected with **HTTP 400** and error code **`VALIDATION_ERROR`**.
328
+
329
+
---
330
+
313
331
## Error codes
314
332
315
333
-**`AUTH_REQUIRED`** - Sign-in required (including some store unauthorized paths mapped from the store layer).
Copy file name to clipboardExpand all lines: CHANGELOG.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,19 @@
3
3
> **Upgrades:** No breaking changes in **3.7.x** unless noted below.
4
4
5
5
6
+
## [3.7.7] - 2026-04-03
7
+
8
+
### Features
9
+
10
+
-**Dashboard todo sort** - Sort assigned todos by **Activity** (recently updated, default) or **Board order** (per project: workflow column position, then lane rank). **`GET /api/dashboard/todos`** supports optional query **`sort=activity`** or **`sort=board`**; pagination **`cursor`** is tied to the active sort, and a cursor from the wrong mode is rejected with **400****`VALIDATION_ERROR`**.
11
+
12
+
### Improvements
13
+
14
+
-**Todo dialog (mobile)** - New/edit todo form scrolls inside the modal on narrow viewports so header, fields, and Save stay usable (aligned with Settings-style scrolling).
15
+
-**Dashboard sort preference (signed-in)** - Choice is saved under **`user_preferences`** key **`dashboardTodoSort`** and restored after login (still mirrored in **localStorage** for fast defaults). Server hydrate skips applying the stored value when it already matches in-memory state, and does not overwrite a sort the user changed locally before preferences finish loading.
Copy file name to clipboardExpand all lines: internal/httpapi/web/dist/state/mutations.js
+37Lines changed: 37 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,9 @@
1
+
import{apiFetch}from'../api.js';
1
2
import{current}from'./state.js';
3
+
import{getUser}from'./selectors.js';
2
4
constDEFAULT_LANE_META=()=>({});
5
+
/** True after the user changes dashboard sort (not server hydrate). Skips applying stored preference so a fast local change is not overwritten when the GET returns. */
constDASHBOARD_SORT_HINT="Order matches each project's board: column, then drag order. Projects appear in a fixed order (not alphabetical or by activity).";
10
+
functiondashboardTodosQueryString(){
11
+
letq='limit=20';
12
+
if(getDashboardTodoSort()==='board'){
13
+
q+='&sort=board';
14
+
}
15
+
returnq;
16
+
}
17
+
/** Narrow viewports use a shorter board option label so the select can stay compact. */
18
+
functionboardOrderOptionText(){
19
+
returntypeofwindow!=='undefined'&&window.innerWidth<=767 ? 'Board Order' : 'Board Order (per project)';
0 commit comments