feat: paginate project conversation history#3564
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
💡 Codex Review
When the history consists only of custom-workspace conversations, refreshConversations now filters those rows out of timelineSections and the Projects section is populated separately via projectGroups. This condition still ignores projectGroups, so the component returns the No history view before rendering any project folders, even after the project summaries load. Include projectGroups.length in the check or move the empty state after project rendering.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const cursor = reset ? undefined : current.items.at(-1)?.id; | ||
| const result = await ipcBridge.database.getUserConversations.invoke({ | ||
| workspace, | ||
| limit: PROJECT_PAGE_SIZE, |
There was a problem hiding this comment.
Load the active project conversation before locating it
For a direct URL to a project conversation that is older than the first page, this hook only fetches the latest five project rows, while locateConversation searches only the loaded project rows. The active conversation is therefore never found, so the sidebar does not expand, scroll to, or highlight the current conversation until the user manually pages through the project. When an id is present, load the page containing that conversation or fetch its workspace before giving up.
Useful? React with 👍 / 👎.
| extra?.is_health_check !== true && | ||
| !extra?.team_id && | ||
| !extra?.teamId && | ||
| (isPinned || belongsInConversationSection) |
There was a problem hiding this comment.
Keep project conversations in shortcut ordering
This filter removes unpinned custom-workspace conversations from groupedHistory, but useVisibleConversationIds still builds the Ctrl+Tab conversation order solely from that grouped history. As a result, project conversations rendered from useProjectConversations are skipped by the conversation-switching shortcut even when they are visible. The shortcut source needs to include the loaded project rows too.
Useful? React with 👍 / 👎.
| const page = await ipcBridge.database.getUserConversations.invoke({ | ||
| workspace: removeProjectTarget.workspace, | ||
| limit: 100, | ||
| cursor, | ||
| }); |
There was a problem hiding this comment.
Avoid deleting hidden team-owned project rows
When a team-owned conversation shares the same workspace as a personal project, this workspace-wide fetch returns rows that were never shown in the project folder, and the subsequent removeConversation call deletes all of them. The old implementation deleted only group.conversations, which had already gone through the regular history filters; this path should apply the same team/health visibility filter or ask the backend for only removable project conversations.
Useful? React with 👍 / 👎.
| })); | ||
|
|
||
| try { | ||
| const cursor = reset ? undefined : current.items.at(-1)?.id; |
There was a problem hiding this comment.
Advance pagination past filtered rows
If a project page contains only rows that filterVisibleConversations removes, such as legacy health-check or team-owned conversations, current.items does not grow and this cursor stays on the same last visible conversation. Every later Show more request then refetches the same hidden page and the user can never reach older visible conversations. Track the raw page's last id as the next cursor, or have the API exclude the hidden rows before paginating.
Useful? React with 👍 / 👎.
| }, [expandedWorkspaces.length, projects]); | ||
|
|
||
| useEffect(() => { | ||
| expandedWorkspaces.forEach(ensureLoaded); |
There was a problem hiding this comment.
Load project pages when the sidebar is collapsed
When a project is collapsed in the persisted folder state and the whole sidebar is collapsed, WorkspaceCollapse still forces its children visible for the icon-only sidebar, but this hook only loads pages for expandedWorkspaces. That leaves those visible collapsed-sidebar project slots empty until the user changes expansion state; load all visible projects in collapsed sidebar mode or decouple first-page loading from folder expansion.
Useful? React with 👍 / 👎.
| return ipcBridge.conversation.listChanged.on(() => { | ||
| void refresh(); | ||
| }); |
There was a problem hiding this comment.
Refresh project pages on completed turns
Project conversations are now populated by useProjectConversations, so useConversationListSync's existing turnCompleted refresh no longer updates those rows. For background or scheduled project conversations that emit conversation.turnCompleted without a separate list-change or manual history refresh, the project folder can keep stale titles, timestamps, and ordering until another mutation happens. Subscribe to turnCompleted here and call refresh just like the main history store does.
Useful? React with 👍 / 👎.
Summary
Closes #3563
Backend dependency
Requires: iOfficeAI/AionCore#606
UI
Validation