mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 00:02:24 +00:00
* fix(issues): replace cursor-based pagination with page-number Search API Problem ======= Issue pagination (#8649) had two bugs: 1. Pages 6-16 were unreachable — clicking page 16 highlighted page 5; clicking 6/7 did nothing. The old cursor-based approach (updated:<CURSOR) broke with Search API's relevance sorting — pages after the first few returned no items even though more issues existed. 2. Issue numbers appeared out of order on loaded pages (e.g. #1082 between #1308 and #1499), because client-side sort used updatedAt instead of issue number. Root Cause ========== The pagination used two separate GitHub API strategies: - Initial page 0 load: REST endpoints (repos/:owner/:repo/issues, repos/:owner/:repo/pulls) sorted by updatedAt - Subsequent pages: Search API with cursor (updated:<DATE) These two sources returned items in different orders, causing items to go missing or appear on wrong pages across page boundaries. Solution ======== 1. Unified on GitHub Search API for all pages — initial load and pagination both use search/issues?q=...&page=N, eliminating the REST-vs-Search inconsistency. 2. Changed from cursor-based (update:<DATE) to page-number-based pagination (page=N), which the Search API supports natively. 3. Switched client-side sort from updatedAt to issue number (sortWorkItemsByNumber), matching GitHub's default Issues view. 4. Parallelized page fetches in handleLoadNextPage — clicking page 16 now fetches all intermediate pages concurrently (~2s) instead of sequentially (~30s). 5. Cleaned up dead legacy gh issue list / gh pr list code path, extracted quoteForSearch helper, shortened overlong comments. Files changed: 11 files, +140/-127 lines Closes #8649 * chore: remove unrelated merge formatting --------- Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
// Why: per-repo fetch budget for gh CLI calls. Kept in shared/ so the renderer's
|
|
// prefetch sites (SidebarNav, ui.ts openTaskPage) and the TaskPage all use the
|
|
// same value for cache-key alignment.
|
|
export const PER_REPO_FETCH_LIMIT = 36
|
|
|
|
// Why: how many items to show after cross-repo merge. Decoupled from the per-repo
|
|
// fetch limit so changing the display cap doesn't invalidate cache keys.
|
|
export const CROSS_REPO_DISPLAY_LIMIT = 100
|
|
|
|
export const GITHUB_WORK_ITEMS_SSH_REMOTE_REQUIRED_MESSAGE =
|
|
'GitHub work items require a GitHub remote for SSH repositories'
|
|
|
|
export function isGitHubWorkItemsSshRemoteRequiredError(error: unknown): boolean {
|
|
const message =
|
|
error instanceof Error
|
|
? error.message
|
|
: typeof error === 'object' &&
|
|
error !== null &&
|
|
'message' in error &&
|
|
typeof error.message === 'string'
|
|
? error.message
|
|
: typeof error === 'string'
|
|
? error
|
|
: ''
|
|
|
|
return message.includes(GITHUB_WORK_ITEMS_SSH_REMOTE_REQUIRED_MESSAGE)
|
|
}
|
|
|
|
// Why: generic over item shape for the same cross-caller reasons as
|
|
// sortWorkItemsByUpdatedAt. Sorting by number descending matches GitHub's
|
|
// default Issues view (newest issue number first).
|
|
export function sortWorkItemsByNumber<T extends { number: number }>(items: T[]): T[] {
|
|
return [...items].sort((left, right) => right.number - left.number)
|
|
}
|
|
|
|
// Why: generic over the item shape because main-process callers emit items
|
|
// without repoId (stamped by the renderer after IPC), while renderer callers
|
|
// carry the full GitHubWorkItem. Both share only the updatedAt field needed
|
|
// here.
|
|
export function sortWorkItemsByUpdatedAt<T extends { updatedAt: string }>(items: T[]): T[] {
|
|
return [...items].sort((left, right) => {
|
|
return new Date(right.updatedAt).getTime() - new Date(left.updatedAt).getTime()
|
|
})
|
|
}
|