Feature/implement pagination for epic picker - #336
Conversation
- Added a new `useEpicSearch` hook to handle live searching of epics. - Integrated epic search into task context menus, properties panel, and task rows. - Updated UI components to support searching and loading states for epics. - Removed unnecessary task data fetching in mention data hooks. - Enhanced internationalization for epic-related strings, including search placeholders and loading messages. - Implemented infinite scrolling for epic search results to improve user experience.
There was a problem hiding this comment.
Important
One must-address finding — the #-mention task search fires a network request on every keystroke with no debounce. One nit inline and two in the body.
Reviewed changes — replaces the single useQuery fetch for all epic tasks with cursor-paginated useInfiniteQuery (20 items per page) across all epic picker UIs, adds a debounced server-side epic search box, and switches #-mention task lookup from preloaded client-side filtering to on-demand server-side search.
- Epic list pagination —
interaction-layout.tsxandtask-detail/index.tsxeach create anuseInfiniteQueryviaepicTasksInfiniteQueryOptions, flatten pages, and build anEpicsPaginationobject threaded down throughboard-view,list-view,list-group,task-card,task-row,task-context-menu, andproperties-panel. - Epic search — new
useEpicSearchhook wraps a debounced (300ms)useInfiniteQueryagainstsearchEpicTasks; the picker swaps between search results and paginated epics based onisEpicSearching. Added totask-card,task-row, andproperties-panel. - Infinite scroll —
createEpicScrollHandlerinview-utils.tsauto-loads the next page when the picker scrolls within 48px of the bottom; applied to every epic list container including the right-click context menu. #-mention task search —useMentionDatano longer preloads tasks;MentionSuggestionMenuscallssearchMentionableTaskson demand for whatever the user types after#. Three BlockNote consumers (doc-editor,description-section,comment-blocknote) passprojectIdinstead oftasks.- i18n — adds
epicPickernamespace across 9 locales.
ℹ️ Nitpicks
use-project-realtime.ts:25— the comment still referencesepicTasksQueryOptions, which was renamed toepicTasksInfiniteQueryOptions. The invalidation logic is unaffected (the shared["projects", projectId, "tasks"]prefix still covers it), but the comment is stale.interaction-layout.tsxandtask-detail/index.tsxboth repeat the sameuseInfiniteQuery→ flatMap →EpicsPaginationconstruction. Consider extracting a shareduseEpicTasksPaginationhook to keep the wiring in one place.
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
There was a problem hiding this comment.
✅ No new issues found in this commit.
Reviewed changes — one lint commit since the prior review at 751e990.
- Lint fix —
task-detail/index.tsximport reformatted from single-line to multi-line foruseInfiniteQueryand friends. No behavioral change.
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
There was a problem hiding this comment.
ℹ️ No new issues in this commit. The open debounce thread from the prior review (
mention-suggestion-menus.tsx:59) is unchanged by these additions and remains outstanding.
Reviewed changes — adds infinite-scroll pagination to the team member selection dialog, replacing a page_size=500 one-shot fetch that exceeds the backend's 200-item cap. Follows the same cursor‑pagination pattern already established by the epic picker.
usersInfiniteQueryOptions— new infinite‑query export inadmin-api.tsthat pages through the user list 20 at a time, mirroringepicTasksInfiniteQueryOptions.AddMemberDialogpagination — switched fromuseQuery(getUsers(1, 500))touseInfiniteQuery(usersInfiniteQueryOptions())withhandleUsersListScrollauto‑loading the next page on scroll‑near‑bottom.- i18n — added
team.addMemberDialog.loadingMoreacross all 9 locales.
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — two commits since the prior review at 6c6eb04: a test-infrastructure fix and a debounce for the #-mention task search.
useDebouncedAsyncCallback— new hook inhooks/use-debounced-callback.tsthat extends the existinguseDebouncedCallbackfor async callbacks needing a return value. Every call within the debounce window shares the single fetch fired once the timer settles, with all callers' promises resolved from the same result.- Debounced mention search —
mention-suggestion-menus.tsxnow wrapssearchMentionableTasksinuseDebouncedAsyncCallbackwith a 300ms delay, so rapid typing after#fires at most one network request. Also skips client-sidefilterSuggestionItemsfor tasks since the server already filters by query. - Test infrastructure —
task-card.test.tsxwraps allrendercalls with aQueryClientProvidersinceTaskCardnow unconditionally callsuseEpicSearch(which usesuseInfiniteQuery). - i18n — adds
epicPickerandteam.addMemberDialog.loadingMorekeys across all 9 locales.
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

Summary
page_size must be an integer between 1 and 200) that hit whenever the epic dropdown had more than a handful of epics, and separately whenever any task detail page was opened — the#-mention task picker (used in comments, task descriptions, and docs) was requestingpage_size: 500against a backend capped at 200.searchparam, matches title or#task_number), so it now correctly reaches every task in a project instead of silently missing anything past whatever page happened to be preloaded.board.taskCard/taskRow/taskContextMenu's "load more/loading epics" text referenced i18n keys that didn't exist in any locale. Consolidated all epic-picker strings into a sharedepicPicker.*namespace across all 9 locales.Test plan
tsc -bcleanbiome checkcleanpage_size=500400 error directly against the API, then confirmed the fixed calls succeed#task_number) and cursor-based pagination via direct API calls against the local dev stack