Skip to content

Add conversation project organization and detail workflow#463

Merged
AnthonyRonning merged 12 commits intomasterfrom
conversation-projects
Apr 8, 2026
Merged

Add conversation project organization and detail workflow#463
AnthonyRonning merged 12 commits intomasterfrom
conversation-projects

Conversation

@AnthonyRonning
Copy link
Copy Markdown
Contributor

@AnthonyRonning AnthonyRonning commented Apr 4, 2026

Summary

  • add sidebar and chat history support for organizing chats into conversation projects and pinning chats
  • add project selection, move/delete dialogs, and a project detail view for managing grouped conversations
  • sync selected project state through routing and chat creation so new conversations inherit the chosen project

Testing

  • Not run in this session

Notes

  • frontend/package.json currently points @opensecret/react to file:../../OpenSecret-SDK, which looks like a local-only dependency path and may need follow-up before merge.

Open with Devin

Summary by CodeRabbit

  • New Features

    • Organize conversations into projects with a project detail view, per-project chat lists, project picker in toolbars, and a project-focused sidebar
    • Create, rename, and delete projects via dialogs; move chats between projects (single and bulk) with a bulk-move dialog
    • Grouped conversation sections (Projects, Pinned, Recents, Archived), pin/unpin chats, and improved selection-mode actions
  • Bug Fixes

    • Clear cached client data on sign-out to avoid stale state after logout

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Upgrades @opensecret/react and adds project-aware conversation management: project CRUD UI, project-detail page, project picker/dialogs, per-conversation and bulk move/delete flows, LocalState selectedProject sync, URL/event synchronization, and React Query invalidation after project/conversation ops.

Changes

Cohort / File(s) Summary
Dependency
frontend/package.json
Bumped @opensecret/react from 1.5.3 to 3.0.2.
Chat list & project integration
frontend/src/components/ChatHistoryList.tsx
Replaced local conversation API usage with useOpenSecret() ops; added project grouping (projects, pinned, recents, archived), search across groups, pin/rename/delete/move handlers, bulk move/delete, query invalidation, and pagination adjustments.
Project UI components
frontend/src/components/ConversationProjectDialog.tsx, frontend/src/components/ConversationProjectPicker.tsx, frontend/src/components/DeleteConversationProjectDialog.tsx, frontend/src/components/MoveChatsDialog.tsx
Added components for creating/renaming projects, project selection picker, delete-project confirmation, and bulk-move dialog with selection UI and typed props.
Project page
frontend/src/components/ProjectDetailView.tsx
Added project-detail view with paginated project conversations, header actions (rename/delete), selection/bulk actions, and project-specific dialogs and instructions preview.
Sidebar & selection flow
frontend/src/components/Sidebar.tsx
Integrated selectedProjectId into local state, added bulk-move event (openbulkmove) and Move action in selection header, changed new-chat emission to CustomEvent with project detail, and synchronous selectedProject clearing on new chat.
Composer & draft project
frontend/src/components/UnifiedChat.tsx
Introduced draftProjectId synced with LocalState, added ConversationProjectPicker to toolbars, conditional conversation creation with os.createConversation(..., { project_id }), hardened async conversation loading (request counter), and broader query invalidation targets.
Routing & app state sync
frontend/src/routes/index.tsx
Added AuthenticatedHomeContent to render ProjectDetailView when project_id is present or UnifiedChat otherwise; syncs active project_id via projectselected, conversationselected, newchat, and popstate listeners.
Local state context
frontend/src/state/LocalStateContext.tsx, frontend/src/state/LocalStateContextDef.ts
Added `selectedProjectId: string
React Query cache on sign-out flows
frontend/src/components/AccountMenu.tsx, frontend/src/components/DeleteAccountDialog.tsx, frontend/src/components/GuestPaymentWarningDialog.tsx, frontend/src/components/VerificationModal.tsx
Invoke queryClient.clear() after os.signOut() in sign-out/delete flows to clear React Query cache.
Pagination helpers
frontend/src/utils/paginatedLists.ts
Added helpers listAllConversations and listAllConversationProjects to fetch and deduplicate all paginated results from OpenSecret clients.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Sidebar
    participant MoveDialog as MoveChatsDialog
    participant OS as OpenSecretAPI
    participant ChatList as ChatHistoryList
    participant LocalState as LocalState Context
    participant Unified as UnifiedChat

    User->>Sidebar: Click "Move Selected"
    Sidebar->>Sidebar: Dispatch "openbulkmove" CustomEvent
    Sidebar->>MoveDialog: Event opens dialog
    User->>MoveDialog: Select destination, confirm
    MoveDialog->>OS: batchUpdateConversationProject(chatIds, projectId)
    OS-->>MoveDialog: Success
    MoveDialog->>ChatList: Invalidate conversation/project queries
    ChatList->>OS: Re-fetch conversations (project-scoped)
    OS-->>ChatList: Updated conversation list
    ChatList->>User: Render updated groups

    User->>ChatList: Click "New Chat"
    ChatList->>LocalState: Read selectedProjectId
    LocalState-->>ChatList: projectId
    ChatList->>Unified: Dispatch "newchat" CustomEvent {detail:{projectId}}
    Unified->>Unified: Set draftProjectId from event
    User->>Unified: Send message
    Unified->>OS: createConversation({}, {project_id: draftProjectId})
    OS-->>Unified: Conversation created in project
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
I hopped through code and nudged files in pairs,
Folders opened, projects grew like spring fairs.
I moved a chat, I pinned a line—soft thump—
A rabbit's small hop makes order from the clump. ✨📁

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add conversation project organization and detail workflow' accurately summarizes the main changes: introducing conversation project management, project selection UI, project detail views, and related workflows for organizing chats.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch conversation-projects

Comment @coderabbitai help to get the list of available commands and usage tips.

AnthonyRonning and others added 3 commits April 7, 2026 14:07
This keeps chat history manageable with projects, pinning, batch moves, and project-aware new chats while preserving the existing chat flow.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Use the new conversation activity field and unassigned-project filter so recents, pinned chats, and project views stay separated without crowding the selection controls.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@AnthonyRonning AnthonyRonning force-pushed the conversation-projects branch from b94a7ce to 611091b Compare April 7, 2026 19:14
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Apr 7, 2026

Deploying maple with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0db7abe
Status: ✅  Deploy successful!
Preview URL: https://ed2444c3.maple-ca8.pages.dev
Branch Preview URL: https://conversation-projects.maple-ca8.pages.dev

View logs

@AnthonyRonning AnthonyRonning marked this pull request as ready for review April 7, 2026 19:16
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Issue

When viewing a chat that is inside a project, clicking the "New Chat" button at the top of the sidebar does not work. It briefly goes to the new chat screen and immediately redirects back to chat that you were viewing.

The "New Chat" button works correctly when viewing a chat that is not inside of a project.

Keep new chat actions consistent across project flows and prevent stale conversation loads from restoring the previous chat. Also make active project selection visible in the composer.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@AnthonyRonning
Copy link
Copy Markdown
Contributor Author

Issue

When viewing a chat that is inside a project, clicking the "New Chat" button at the top of the sidebar does not work. It briefly goes to the new chat screen and immediately redirects back to chat that you were viewing.

The "New Chat" button works correctly when viewing a chat that is not inside of a project.

good find, fixed.

@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Issue

When creating a new chat within a project, either from the Project details screen or from the main New Chat screen, the title of the new chat remains "New Conversation" until it is reloaded on the screen. This can happen by collapsing the project in the sidebar and expanding again, refreshing the entire page, or by selecting "View Project".

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
frontend/src/components/UnifiedChat.tsx (1)

2680-2693: Consider adding documentName to the dependency array.

documentName is read directly in the function body (e.g., line 2367: const originalDocumentName = documentName), but it's not included in the dependency array. While this is unlikely to cause issues in practice since state changes trigger re-renders, it would be flagged by ESLint's exhaustive-deps rule.

♻️ Suggested fix
   [
     input,
     isGenerating,
     openai,
     os,
     conversation,
     draftProjectId,
     localState.model,
     draftImages,
     documentText,
+    documentName,
     clearAllAttachments,
     processStreamingResponse,
     isWebSearchEnabled
   ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/UnifiedChat.tsx` around lines 2680 - 2693, The
dependency array for the effect in the UnifiedChat component is missing
documentName, which is referenced in the function body; update the dependency
array (the array containing input, isGenerating, openai, os, conversation,
draftProjectId, localState.model, draftImages, documentText,
clearAllAttachments, processStreamingResponse, isWebSearchEnabled) to include
documentName so the effect reacts when documentName changes and satisfies ESLint
exhaustive-deps; locate the effect in UnifiedChat.tsx where originalDocumentName
= documentName is used and add documentName to that dependency array.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/src/components/UnifiedChat.tsx`:
- Around line 2680-2693: The dependency array for the effect in the UnifiedChat
component is missing documentName, which is referenced in the function body;
update the dependency array (the array containing input, isGenerating, openai,
os, conversation, draftProjectId, localState.model, draftImages, documentText,
clearAllAttachments, processStreamingResponse, isWebSearchEnabled) to include
documentName so the effect reacts when documentName changes and satisfies ESLint
exhaustive-deps; locate the effect in UnifiedChat.tsx where originalDocumentName
= documentName is used and add documentName to that dependency array.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 43adceb9-823d-4497-a74e-dd603dc9e107

📥 Commits

Reviewing files that changed from the base of the PR and between 611091b and 03e9d66.

📒 Files selected for processing (2)
  • frontend/src/components/ConversationProjectPicker.tsx
  • frontend/src/components/UnifiedChat.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/ConversationProjectPicker.tsx

Keep project, pinned, and recent chat lists in sync when a new conversation title is generated so users do not need to reload to see the final name.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@AnthonyRonning
Copy link
Copy Markdown
Contributor Author

Issue

When creating a new chat within a project, either from the Project details screen or from the main New Chat screen, the title of the new chat remains "New Conversation" until it is reloaded on the screen. This can happen by collapsing the project in the sidebar and expanding again, refreshing the entire page, or by selecting "View Project".

nice fixed

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

AnthonyRonning and others added 2 commits April 7, 2026 21:24
Load all project, pinned, and project-scoped conversation pages so sidebar and picker views stay complete for larger accounts.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Keep project bulk actions aligned with the sidebar selection workflow so users get the same limits and feedback across both views.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
coderabbitai[bot]

This comment was marked as resolved.

Surface bulk delete and move errors in project detail views so failed batch actions do not silently disappear.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Suggestion

When deleting a project, it would be good to have the confirmation dialog require the user to type "DELETE" or the name of the project into a box in order to proceed. Project deletion can be a very destructive process if the user has many chats in it.

image

Keep bulk move dialogs open until the move succeeds so failures surface inline instead of looking like successful closes.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Testing Projects and Pinned Chats

  • Create a new project
  • Move a chat into a project
  • Move a chat out of a project
  • Pin a chat
  • Chat inside of a pinned chat
  • Unpin a chat
  • Test new instructions for project
  • Update instructions for project
  • Delete instructions for project
  • Move chat into project and check that it gets the special instructions
  • Move chat out of project and check that it doesn't get the special instructions
  • Delete chat from inside a project
  • Delete chat that is not assigned to a project
  • Delete a project
  • Create more than one project
  • Move a chat between projects and make sure the special instructions are applied correctly
  • While in a project chat, start a new chat from the button at the top of the screen
  • In a non project chat, start a new chat from the button at the top of the screen

@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Tested and working well!

The only small odd thing I saw that isn't really a bug has to do with dates on chats. And we are doing away with dates in the redesign, so this probably doesn't matter.

  1. Pin an existing chat from an older date
  2. Make a reply in the chat after it is pinned
  3. Unpin the chat
  4. It is now at the top of the list with today's date

Make project deletion use the same typed confirmation pattern as other destructive flows so users must explicitly acknowledge deleting the project and its chats.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@AnthonyRonning
Copy link
Copy Markdown
Contributor Author

@TestFlight build

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

🚀 TestFlight deployment triggered! Check the Actions tab for progress.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

✅ TestFlight deployment completed successfully!

@marksftw
Copy link
Copy Markdown
Contributor

marksftw commented Apr 8, 2026

Issue

If you are on the project details page and move an existing chat into the project, it doesn't show up on the details page until you refresh. The opposite works correctly: moving a chat out of the project updates the screen immediately.

Reload the project detail list when conversation project metadata changes so chats moved into or out of the active project appear immediately.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 20 additional findings in Devin Review.

Open in Devin Review

window.history.replaceState({}, "", params.toString() ? `/?${params}` : "/");

// Dispatch event to clear UnifiedChat
window.dispatchEvent(new Event("newchat"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 newchat dispatched as plain Event (not CustomEvent) when deleting a non-archived conversation, keeping stale project context

When a non-archived conversation is deleted and it is the current chat, ChatHistoryList.tsx:677 dispatches new Event("newchat") — a plain Event without a detail payload. In UnifiedChat.handleNewChat (UnifiedChat.tsx:1157-1161), this causes the event instanceof CustomEvent check to be false, so nextProjectId falls back to selectedProjectId ?? null instead of being explicitly set to null. If the deleted conversation belonged to a project, selectedProjectId still holds that project's ID (set at ChatHistoryList.tsx:1083 when the conversation was originally selected), so draftProjectId is set to that project. The next message the user sends will silently create a new conversation inside that project. All other newchat dispatch sites use new CustomEvent("newchat", { detail: { projectId: ... } }) to explicitly control the project context.

Suggested change
window.dispatchEvent(new Event("newchat"));
window.dispatchEvent(new CustomEvent("newchat", { detail: { projectId: null } }));
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@AnthonyRonning
Copy link
Copy Markdown
Contributor Author

@TestFlight build

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

🚀 TestFlight deployment triggered! Check the Actions tab for progress.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

✅ TestFlight deployment completed successfully!

@AnthonyRonning AnthonyRonning merged commit 039d30d into master Apr 8, 2026
14 checks passed
@AnthonyRonning AnthonyRonning deleted the conversation-projects branch April 8, 2026 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants