Skip to content

feat(desktop): hover dropdown actions on changes sidebar rows#3897

Merged
Kitenite merged 1 commit into
mainfrom
sidebar-hover-actions
Apr 30, 2026
Merged

feat(desktop): hover dropdown actions on changes sidebar rows#3897
Kitenite merged 1 commit into
mainfrom
sidebar-hover-actions

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Apr 30, 2026

Summary

  • Each file in the v2 changes sidebar now reveals a more-actions dropdown on hover (status badge / +/- counts hide while the action is showing)
  • Dropdown mirrors the right-click context menu and adds new Open File / Open File in New Tab entries (routed through the same pane-opener the Files tab uses)
  • Existing click-modifier shortcuts (⇧ click, ⌘ click) are shown next to the corresponding dropdown items so the dropdown and context menu stay in sync

Test plan

  • Hover a row in the Changes sidebar — the chevron button appears, stats hide
  • Open the dropdown — five actions visible, ⇧ click and ⌘ click hints shown
  • Open Diff / Open Diff in New Tab open the diff pane (matches plain click and ⇧ click)
  • Open File / Open File in New Tab open the file (not the diff) in the same way the Files tab does
  • Open in Editor launches the external editor (matches ⌘ click)
  • Right-click context menu shows the same items
  • Dropdown stays visible while open even if cursor leaves the row

Summary by cubic

Adds a hover “more actions” dropdown to each file row in the v2 Changes sidebar, with quick actions to open diffs, files, or the external editor. The dropdown mirrors the right‑click menu and adds new Open File options.

  • New Features
    • Shows a chevron on hover; status badge and +/- counts hide while visible.
    • Actions: Open Diff, Open Diff in New Tab, Open File, Open File in New Tab, Open in Editor.
    • Displays shortcut hints for ⇧ click and ⌘ click.
    • Right‑click context menu matches the dropdown.
    • Wires onOpenFile through useChangesTab so file opens use the existing Files pane opener.

Written for commit dde72ca. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

Release Notes

  • New Features
    • Users can now open changed files directly from the changes interface
    • Added "Open File in New Tab" option for quick access to changed files
    • New "More actions" dropdown menu appears on hover, providing quick access to file operations
    • Right-click context menu expanded with file opening options

Each file in the v2 changes sidebar now reveals a more-actions
dropdown on hover, with Open Diff / Open Diff in New Tab / Open File
/ Open File in New Tab / Open in Editor (mirrors the right-click
menu, plus new Open File entries that route through the existing
file-open pane). Click-modifier shortcut hints (⇧/⌘) are shown next
to the actions that have them.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

A new optional onOpenFile callback is threaded through the WorkspaceSidebar component hierarchy from useChangesTab down to FileRow, enabling files to be opened by absolute path with optional new-tab behavior. The FileRow component is simultaneously refactored to expose file operations via a dropdown menu revealed on hover and an extended context menu.

Changes

Cohort / File(s) Summary
Callback Propagation
WorkspaceSidebar.tsx, useChangesTab.tsx, ChangesTabContent.tsx, ChangesFileList.tsx
New optional onOpenFile callback added to hook and component signatures, threaded sequentially through the component tree to enable downstream file-opening functionality.
FileRow UI Refactoring
FileRow.tsx
Component refactored to accept onOpenFile callback and expose file operations (Open File, Open File in New Tab) via a dropdown menu that appears on hover and through an enhanced right-click context menu, replacing previous single-button layout.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A callback hops through the tree so tall,
From sidebar to row, it answers the call,
Files open with ease, in tab or the same,
A menu appears—reveal and reclaim! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(desktop): hover dropdown actions on changes sidebar rows' is clear, specific, and directly summarizes the main change—adding hover dropdown actions to changes sidebar file rows.
Description check ✅ Passed The description includes a clear summary of changes, test plan with checkboxes, related implementation details, and a reference to the auto-generated summary by cubic tool, meeting the template requirements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sidebar-hover-actions

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
Review rate limit: 6/8 reviews remaining, refill in 13 minutes and 18 seconds.

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

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR adds a hover-revealed chevron dropdown to each row in the Changes sidebar, mirroring the existing right-click context menu and adding new "Open File" / "Open File in New Tab" actions routed through the same pane-opener as the Files tab. The prop is threaded cleanly from WorkspaceSidebaruseChangesTabChangesTabContentChangesFileListFileRow, and keyboard-shortcut hints are correctly attached to "Open Diff in New Tab" (⇧ click) and "Open in Editor" (⌘ click).

Confidence Score: 5/5

Safe to merge — all findings are P2 style suggestions with no correctness impact.

The prop-threading is clean and the UI logic is sound. The two flagged items (stats reappearing off-row while the dropdown is open, and absent separators between action groups) are cosmetic polish items that do not affect functionality or data integrity.

FileRow.tsx — hover-visibility interaction between the stats span and the dropdown open state.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/components/FileRow/FileRow.tsx Core UI change: wraps row in a hover group, adds an absolute-positioned DropdownMenu button that mirrors the context menu, and makes stats invisible on hover. Two minor style concerns: stats can reappear while the dropdown is open off-row, and there are no separators between action groups.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/WorkspaceSidebar.tsx Correctly wires onOpenFile: onSelectFile into useChangesTab, routing file-open actions through the same pane-opener used by the Files tab.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/useChangesTab.tsx Receives onOpenFile in hook params and passes it into ChangesTabContent; no logic changes.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesTabContent/ChangesTabContent.tsx Pass-through of new onOpenFile prop from interface to ChangesFileList; straightforward plumbing, no issues.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/ChangesFileList.tsx Adds onOpenFile prop and threads it to each FileRow; clean and minimal.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User hovers FileRow] --> B{Dropdown button appears}
    B --> C[Click dropdown chevron]
    C --> D[DropdownMenuContent shown]
    D --> E1[Open Diff]
    D --> E2[Open Diff in New Tab]
    D --> E3[Open File]
    D --> E4[Open File in New Tab]
    D --> E5[Open in Editor]
    E1 --> F1[onSelect file.path]
    E2 --> F2[onSelect file.path, true]
    E3 --> F3[onOpenFile absolutePath]
    E4 --> F4[onOpenFile absolutePath, true]
    E5 --> F5[onOpenInEditor file.path]
    F3 --> G[WorkspaceSidebar.onSelectFile]
    F4 --> G
    G --> H[Files tab pane-opener]
    F1 --> I[Diff pane]
    F2 --> I
    F5 --> J[External editor]
    A --> K[Right-click ContextMenu]
    K --> L[Same 5 actions + PathActionsMenuItems]
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/components/FileRow/FileRow.tsx:91-104
**Stats visible alongside dropdown button when menu is open off-row**

The stats span uses `group-hover:invisible` to hide when the row is hovered, but once the dropdown is open and the pointer moves onto the menu content (a portal outside the row), the `.group` div is no longer hovered. At that point the stats reappear while the dropdown button stays visible via `has-[[data-state=open]]`, so both are shown simultaneously.

Adding `group-has-[[data-state=open]]:invisible` to the stats span keeps them hidden for the full lifetime of the dropdown, matching the PR intent ("status badge / +/- counts hide while the action is showing"):

```suggestion
				<span className="ml-auto flex shrink-0 items-center gap-1.5 group-hover:invisible group-has-[[data-state=open]]:invisible">
```

### Issue 2 of 2
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/components/FileRow/FileRow.tsx:118-145
**No visual separator between "Open Diff" and "Open File" action groups**

The dropdown now mixes two conceptually different action groups — diff-opening actions ("Open Diff", "Open Diff in New Tab") and file-opening actions ("Open File", "Open File in New Tab") — with no visual separator between them. The existing code already uses `ContextMenuSeparator` before `PathActionsMenuItems`; a `DropdownMenuSeparator` (and `ContextMenuSeparator`) between the diff and file groups would make the menu easier to scan.

Reviews (1): Last reviewed commit: "feat(desktop): add hover dropdown action..." | Re-trigger Greptile

@Kitenite Kitenite merged commit 03be01e into main Apr 30, 2026
6 of 7 checks passed
@Kitenite Kitenite deleted the sidebar-hover-actions branch April 30, 2026 04:57
Comment on lines +91 to +104
<span className="ml-auto flex shrink-0 items-center gap-1.5 group-hover:invisible">
{(file.additions > 0 || file.deletions > 0) && (
<span className="text-[10px] text-muted-foreground">
{file.additions > 0 && (
<span className="text-green-400">+{file.additions}</span>
)}
{file.additions > 0 && file.deletions > 0 && " "}
{file.deletions > 0 && (
<span className="text-red-400">-{file.deletions}</span>
)}
</span>
)}
<StatusIndicator status={file.status} />
</span>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Stats visible alongside dropdown button when menu is open off-row

The stats span uses group-hover:invisible to hide when the row is hovered, but once the dropdown is open and the pointer moves onto the menu content (a portal outside the row), the .group div is no longer hovered. At that point the stats reappear while the dropdown button stays visible via has-[[data-state=open]], so both are shown simultaneously.

Adding group-has-[[data-state=open]]:invisible to the stats span keeps them hidden for the full lifetime of the dropdown, matching the PR intent ("status badge / +/- counts hide while the action is showing"):

Suggested change
<span className="ml-auto flex shrink-0 items-center gap-1.5 group-hover:invisible">
{(file.additions > 0 || file.deletions > 0) && (
<span className="text-[10px] text-muted-foreground">
{file.additions > 0 && (
<span className="text-green-400">+{file.additions}</span>
)}
{file.additions > 0 && file.deletions > 0 && " "}
{file.deletions > 0 && (
<span className="text-red-400">-{file.deletions}</span>
)}
</span>
)}
<StatusIndicator status={file.status} />
</span>
<span className="ml-auto flex shrink-0 items-center gap-1.5 group-hover:invisible group-has-[[data-state=open]]:invisible">
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/components/FileRow/FileRow.tsx
Line: 91-104

Comment:
**Stats visible alongside dropdown button when menu is open off-row**

The stats span uses `group-hover:invisible` to hide when the row is hovered, but once the dropdown is open and the pointer moves onto the menu content (a portal outside the row), the `.group` div is no longer hovered. At that point the stats reappear while the dropdown button stays visible via `has-[[data-state=open]]`, so both are shown simultaneously.

Adding `group-has-[[data-state=open]]:invisible` to the stats span keeps them hidden for the full lifetime of the dropdown, matching the PR intent ("status badge / +/- counts hide while the action is showing"):

```suggestion
				<span className="ml-auto flex shrink-0 items-center gap-1.5 group-hover:invisible group-has-[[data-state=open]]:invisible">
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +118 to +145
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuItem onSelect={() => onSelect?.(file.path)}>
Open Diff
</DropdownMenuItem>
<DropdownMenuItem onSelect={() => onSelect?.(file.path, true)}>
Open Diff in New Tab
<DropdownMenuShortcut>{SHIFT_CLICK_LABEL}</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => absolutePath && onOpenFile?.(absolutePath)}
disabled={!onOpenFile || !absolutePath}
>
Open File
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => absolutePath && onOpenFile?.(absolutePath, true)}
disabled={!onOpenFile || !absolutePath}
>
Open File in New Tab
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => onOpenInEditor?.(file.path)}
disabled={!onOpenInEditor}
>
Open in Editor
<DropdownMenuShortcut>{MOD_CLICK_LABEL}</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 No visual separator between "Open Diff" and "Open File" action groups

The dropdown now mixes two conceptually different action groups — diff-opening actions ("Open Diff", "Open Diff in New Tab") and file-opening actions ("Open File", "Open File in New Tab") — with no visual separator between them. The existing code already uses ContextMenuSeparator before PathActionsMenuItems; a DropdownMenuSeparator (and ContextMenuSeparator) between the diff and file groups would make the menu easier to scan.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useChangesTab/components/ChangesFileList/components/FileRow/FileRow.tsx
Line: 118-145

Comment:
**No visual separator between "Open Diff" and "Open File" action groups**

The dropdown now mixes two conceptually different action groups — diff-opening actions ("Open Diff", "Open Diff in New Tab") and file-opening actions ("Open File", "Open File in New Tab") — with no visual separator between them. The existing code already uses `ContextMenuSeparator` before `PathActionsMenuItems`; a `DropdownMenuSeparator` (and `ContextMenuSeparator`) between the diff and file groups would make the menu easier to scan.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch

Thank you for your contribution! 🎉

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