Skip to content

Stage/unstage all changes#361

Merged
Kitenite merged 3 commits into
mainfrom
poor-raccoon-121bf3
Dec 14, 2025
Merged

Stage/unstage all changes#361
Kitenite merged 3 commits into
mainfrom
poor-raccoon-121bf3

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Dec 14, 2025

Summary by CodeRabbit

  • New Features
    • Bulk actions: "Stage all" and "Unstage all" buttons in each section.
    • Per-file actions: hover-revealed stage/unstage icon buttons with plus/minus icons and tooltips.
    • Operation state: controls show in-progress state and are disabled while actions run.
    • Status & feedback: user-facing toast notifications and automatic refresh after actions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 14, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds per-file and bulk staging/unstaging actions to Changes View: mutation hooks (stageAll, unstageAll, stageFile, unstageFile), UI buttons for bulk and per-file actions, and propagation of onStage/onUnstage/isActioning props through FileList → FileListGrouped/FileListTree → FileItem. (50 words)

Changes

Cohort / File(s) Summary
Changes view (mutations & bulk controls)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
Adds stageAll, unstageAll, stageFile, unstageFile mutation hooks with onSuccess refetch and onError toasts/logging; adds "Stage all" / "Unstage all" header buttons with tooltips; wires per-file handlers into FileList props.
Per-file UI and props
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
Extends FileItemProps with onStage?, onUnstage?, isActioning?; replaces outer button with hover-revealed action cluster; adds plus/minus icon buttons (with tooltips) that call callbacks and respect isActioning; stops event propagation for actions.
List component prop threading
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
Adds optional onStage, onUnstage, and isActioning props and forwards them to child list renderers (FileListGrouped / FileListTree).
Grouped list propagation
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
Adds onStage, onUnstage, isActioning to FileListGrouped and FolderGroupItem props; forwards callbacks to FileItem instances (conditional mapping for staged vs unstaged).
Tree list propagation
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
Adds onStage, onUnstage, isActioning to FileListTree, TreeNodeComponent, and TreeNode props; forwards them through recursive rendering to FileItem; ensures consistent file reference when invoking callbacks.

Sequence Diagram(s)

sequenceDiagram
    participant User as User (click)
    participant UI as ChangesView / FileItem
    participant Client as Mutation Client
    participant Server as API (tRPC)
    participant Cache as Query Cache

    Note over User,UI: User clicks a per-file action or a bulk action

    User->>UI: Click stage/unstage (file or "all")
    UI->>Client: call mutation (stageFile|unstageFile|stageAll|unstageAll)
    Client->>Server: invoke RPC
    Server-->>Client: success / error
    alt success
        Client->>Cache: refetch relevant queries (onSuccess)
        Cache->>UI: updated data -> re-render (isActioning cleared)
        UI-->>User: UI reflects staged/unstaged state
    else error
        Client-->>UI: error callback (toast/log)
        UI-->>User: error toast shown
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review mutation onSuccess refetch targets and error handling in ChangesView.
  • Verify correct propagation of onStage/onUnstage/isActioning through FileListTree and FileListGrouped.
  • Confirm UI event.stopPropagation prevents row selection when clicking action buttons and that disabled/pending states are applied consistently.
  • Check imports for added UI components/icons and tooltip accessibility.

Possibly related PRs

Poem

🐰 I hopped through lists with nimble paws,
Buttons gleam with plus and minus laws,
Click one file or tap them all,
I sorted bytes in a cozy hall,
Burrowed changes snug as jaws. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided, missing all required template sections including description of changes, related issues, type of change, testing, and additional context. Add a detailed description following the repository template, including a clear explanation of the changes, related issues, type of change classification, testing approach, and any additional context.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Stage/unstage all changes' clearly and concisely summarizes the main objective of the changeset, which adds UI actions and mutations for staging/unstaging all files at once.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1143d9d and 45a2df1.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (4 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Kitenite Kitenite changed the title poor raccoon 121bf3 Stage/unstage all changes Dec 14, 2025
Copy link
Copy Markdown
Contributor

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (1)

232-236: Simplify defensive null coalescing.

The worktreePath || "" fallback is unnecessary here because worktreePath is already validated as truthy at Line 119. This pattern appears in all mutation calls (lines 234, 254, 277, 297).

-  worktreePath: worktreePath || "",
+  worktreePath,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6fe8fd and 9e106bc.

📒 Files selected for processing (5)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (4 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx (5 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx (4 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx (5 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for code formatting and linting, running at root level for speed

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid any type and prioritize type safety in TypeScript code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.{ts,tsx}: Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Use one component per file (no multi-component files)

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods from renderer process using window.ipcRenderer.invoke with type-safe object parameters

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx
🧬 Code graph analysis (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx (1)
apps/desktop/src/shared/changes-types.ts (1)
  • ChangedFile (22-28)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx (1)
apps/desktop/src/shared/changes-types.ts (1)
  • ChangedFile (22-28)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx (2)
apps/desktop/src/shared/changes-types.ts (1)
  • ChangedFile (22-28)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx (1)
  • FileItem (40-142)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Deploy Admin
  • GitHub Check: Deploy API
  • GitHub Check: Deploy Web
  • GitHub Check: Deploy Marketing
  • GitHub Check: Deploy Docs
  • GitHub Check: Build
🔇 Additional comments (6)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx (1)

258-258: Note: Global pending state per section.

The isActioning prop uses unstageFileMutation.isPending for all staged files and stageFileMutation.isPending for all unstaged files. This means clicking stage/unstage on one file disables the action buttons for all files in that section until the operation completes.

This is likely intentional to serialize git operations and prevent race conditions, but it may cause UX confusion if users expect to stage multiple files concurrently.

Consider whether per-file pending state would be better UX, or if current serialization is required for git safety.

Also applies to: 301-301

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx (1)

59-140: LGTM! Clean hover-action implementation.

The refactor from a single button to a div+button structure with hover-based action buttons is well-executed:

  • Maintains keyboard accessibility via the inner button (Line 67-96)
  • Correctly uses stopPropagation to prevent file selection when clicking action buttons
  • Conditionally renders actions only when callbacks are provided
  • Properly disables buttons during pending operations
  • Tooltip placement and content are appropriate

The structure change is necessary to support the hover-based action cluster without conflicting with the primary file selection behavior.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileList.tsx (1)

13-61: LGTM! Clean prop forwarding.

The addition of onStage, onUnstage, and isActioning props with proper forwarding to both FileListTree and FileListGrouped maintains consistency across view modes. Type safety is preserved throughout.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListGrouped.tsx (1)

12-125: LGTM! Proper callback closure handling.

The prop threading through FolderGroupItem to FileItem is implemented correctly. Lines 94-96 properly create closures that capture the specific file for each callback, ensuring the correct file is passed when the action is triggered.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileList/FileListTree.tsx (2)

134-144: LGTM! Excellent closure handling with local variable.

Line 134 introduces a local file constant before creating closures at lines 139, 142-143. This is a best practice that ensures the callbacks capture a stable reference to the file, preventing potential issues if node.file were to change. The conditional callback mapping correctly passes the file to parent handlers.


12-176: Clean recursive prop threading.

The staging props are correctly threaded through the recursive tree structure via TreeNodeComponent. Each level properly forwards onStage, onUnstage, and isActioning to both child nodes (Line 124-126) and FileItem (Line 142-144), maintaining consistency throughout the tree hierarchy.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 14, 2025

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) View Branch
Vercel API (Vercel) Open Preview
Vercel Web (Vercel) Open Preview
Vercel Marketing (Vercel) Open Preview
Vercel Admin (Vercel) Open Preview
Vercel Docs (Vercel) Open Preview

Preview updates automatically with new commits

@Kitenite Kitenite merged commit 04017e1 into main Dec 14, 2025
10 of 11 checks passed
@Kitenite Kitenite deleted the poor-raccoon-121bf3 branch December 14, 2025 04:45
This was referenced Dec 17, 2025
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.

1 participant