Skip to content

Commit 02456f7

Browse files
authored
Merge pull request #7 from Paca-AI/feature/enhance-member-pagination
feat: add cursor-paged listTasksPage and TaskPage type
2 parents a7b01cc + 6a6f175 commit 02456f7

4 files changed

Lines changed: 31 additions & 8 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Returns `{ api, ui, meta }` from the nearest `<PluginProvider>`.
5252

5353
### `PluginApiClient`
5454
Scoped HTTP client. Methods:
55-
- `listTasks(filters?)` — list tasks in current project
55+
- `listTasks(filters?)` — the first page of the current project's tasks (up to 200); use `listTasksPage(filters?)` and follow `next_cursor` to read them all
5656
- `getTask(taskId)` — fetch a single task
5757
- `getProject()` — fetch current project summary
5858
- `listMembers()` — list project members

‎src/api-client.ts‎

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
ListMembersOptions,
1212
MemberPage,
1313
ProjectSummary,
14+
TaskPage,
1415
Task,
1516
TaskFilters,
1617
TaskSummary,
@@ -59,27 +60,35 @@ export class PluginApiClient {
5960
// ── Core read-only helpers ──────────────────────────────────────────────
6061

6162
/**
62-
* List tasks for the current project with optional filters.
63-
* Defaults to the host's max page size (200) when the caller doesn't
64-
* specify one, since most callers use this for an unfiltered "get the
65-
* project's tasks" lookup and the host otherwise defaults to only 20.
63+
* The first page of the current project's tasks (up to 200 by default).
64+
* A project with more matching tasks is truncated: use `listTasksPage` and
65+
* follow `next_cursor` when every task matters.
6666
*/
6767
async listTasks(filters: TaskFilters = {}): Promise<TaskSummary[]> {
68+
return (await this.listTasksPage(filters)).items;
69+
}
70+
71+
/**
72+
* One page of the current project's tasks with optional filters. Pass the
73+
* previous page's `next_cursor` as `filters.cursor` for the next page.
74+
* Defaults to the host's max page size (200) when the caller doesn't
75+
* specify one, since the host otherwise defaults to only 20.
76+
*/
77+
async listTasksPage(filters: TaskFilters = {}): Promise<TaskPage> {
6878
const params = new URLSearchParams();
79+
if (filters.cursor) params.set("cursor", filters.cursor);
6980
if (filters.status_ids?.length)
7081
params.set("status_ids", filters.status_ids.join(","));
7182
if (filters.assignee_ids?.length)
7283
params.set("assignee_ids", filters.assignee_ids.join(","));
7384
if (filters.sprint_id) params.set("sprint_id", filters.sprint_id);
7485
if (filters.parent_task_id)
7586
params.set("parent_task_id", filters.parent_task_id);
76-
if (filters.page) params.set("page", String(filters.page));
7787
params.set("page_size", String(filters.page_size ?? 200));
7888

7989
const qs = params.toString();
8090
const url = `${this.baseUrl}/projects/${this.projectId}/tasks${qs ? `?${qs}` : ""}`;
81-
const envelope = await this._get<{ items: TaskSummary[] }>(url);
82-
return envelope.items;
91+
return this._get<TaskPage>(url);
8392
}
8493

8594
/** Get a single task by ID. */

‎src/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type {
4040
ProjectSummary,
4141
Task,
4242
TaskFilters,
43+
TaskPage,
4344
TaskSummary,
4445
} from "./types";
4546
export { permissionsFromRole } from "./types";

‎src/types.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,23 @@ export interface TaskFilters {
2626
assignee_ids?: string[];
2727
sprint_id?: string;
2828
parent_task_id?: string;
29+
/** Cursor from a previous page's `next_cursor` (see listTasksPage). */
30+
cursor?: string;
31+
/** @deprecated Ignored: tasks page by cursor. Use `cursor` (see listTasksPage). */
2932
page?: number;
3033
page_size?: number;
3134
}
3235

36+
/** One page of the tasks list, keyset-paginated by cursor. */
37+
export interface TaskPage {
38+
items: TaskSummary[];
39+
page_size: number;
40+
/** Pass as `cursor` for the next page; null on the last page. */
41+
next_cursor: string | null;
42+
/** Tasks matching the filters across all pages (first page only). */
43+
total_count?: number;
44+
}
45+
3346
// ── Project ───────────────────────────────────────────────────────────────────
3447

3548
/** Project summary returned by the project_get host function. */

0 commit comments

Comments
 (0)