Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function DashboardSidebarWorkspaceItem({
cancelRename,
handleClick,
handleCopyPath,
handleCopyBranchName,
handleCreateSection,
handleDeleted,
handleOpenInFinder,
Expand All @@ -55,6 +56,7 @@ export function DashboardSidebarWorkspaceItem({
workspaceId: id,
projectId,
workspaceName: name,
branch,
});

const navigate = useNavigate();
Expand Down Expand Up @@ -119,6 +121,7 @@ export function DashboardSidebarWorkspaceItem({
}
onOpenInFinder={handleOpenInFinder}
onCopyPath={handleCopyPath}
onCopyBranchName={handleCopyBranchName}
onRemoveFromSidebar={() => removeWorkspaceFromSidebar(id)}
onRename={startRename}
onDelete={() => setIsDeleteDialogOpen(true)}
Expand Down Expand Up @@ -183,6 +186,7 @@ export function DashboardSidebarWorkspaceItem({
isLocalWorkspace={hostType === "local-device"}
onOpenInFinder={handleOpenInFinder}
onCopyPath={handleCopyPath}
onCopyBranchName={handleCopyBranchName}
onRemoveFromSidebar={() => removeWorkspaceFromSidebar(id)}
onRename={startRename}
onDelete={() => setIsDeleteDialogOpen(true)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
LuCopy,
LuFolderOpen,
LuFolderPlus,
LuGitBranch,
LuPencil,
LuTrash2,
LuX,
Expand All @@ -38,6 +39,7 @@ interface DashboardSidebarWorkspaceContextMenuProps {
onMoveToSection: (sectionId: string | null) => void;
onOpenInFinder: () => void;
onCopyPath: () => void;
onCopyBranchName: () => void;
onRemoveFromSidebar: () => void;
onRename: () => void;
onDelete: () => void;
Expand All @@ -54,6 +56,7 @@ export function DashboardSidebarWorkspaceContextMenu({
onMoveToSection,
onOpenInFinder,
onCopyPath,
onCopyBranchName,
onRemoveFromSidebar,
onRename,
onDelete,
Expand Down Expand Up @@ -96,6 +99,11 @@ export function DashboardSidebarWorkspaceContextMenu({
</ContextMenuItem>
</>
)}
{!isLocalWorkspace && <ContextMenuSeparator />}
<ContextMenuItem onSelect={onCopyBranchName}>
<LuGitBranch className="size-4 mr-2" />
Copy Branch Name
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem onSelect={onCreateSection}>
<LuFolderPlus className="size-4 mr-2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ interface UseDashboardSidebarWorkspaceItemActionsOptions {
workspaceId: string;
projectId: string;
workspaceName: string;
branch: string;
}

export function useDashboardSidebarWorkspaceItemActions({
workspaceId,
projectId,
workspaceName,
branch,
}: UseDashboardSidebarWorkspaceItemActionsOptions) {
const navigate = useNavigate();
const matchRoute = useMatchRoute();
Expand Down Expand Up @@ -144,10 +146,26 @@ export function useDashboardSidebarWorkspaceItemActions({
}
};

const handleCopyBranchName = async () => {
if (!branch) {
toast.error("Branch name is not available");
return;
}
try {
await copyToClipboard(branch);
toast.success("Branch name copied");
} catch (error) {
toast.error(
`Failed to copy branch name: ${error instanceof Error ? error.message : "Unknown error"}`,
);
}
};

return {
cancelRename,
handleClick,
handleCopyPath,
handleCopyBranchName,
handleCreateSection,
handleDeleted,
handleOpenInFinder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import { cn } from "@superset/ui/utils";
import { type RefObject, useMemo, useState } from "react";
import { LuCopy, LuX } from "react-icons/lu";
import { LuCopy, LuGitBranch, LuX } from "react-icons/lu";
import { createContextMenuDeleteDialogCoordinator } from "renderer/react-query/workspaces/useWorkspaceDeleteHandler";
import type { ActivePaneStatus } from "shared/tabs-types";
import { STROKE_WIDTH } from "../constants";
Expand All @@ -36,6 +36,7 @@ interface CollapsedWorkspaceItemProps {
onClick: () => void;
onDeleteClick: () => void;
onCopyPath: () => void;
onCopyBranchName: () => void;
}

export function CollapsedWorkspaceItem({
Expand All @@ -53,6 +54,7 @@ export function CollapsedWorkspaceItem({
onClick,
onDeleteClick,
onCopyPath,
onCopyBranchName,
}: CollapsedWorkspaceItemProps) {
const isBranchWorkspace = type === "branch";
const deleteDialogCoordinator = useMemo(
Expand Down Expand Up @@ -92,15 +94,25 @@ export function CollapsedWorkspaceItem({
if (isBranchWorkspace) {
return (
<>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>{collapsedButton}</TooltipTrigger>
<TooltipContent side="right" className="flex flex-col gap-0.5">
<span className="font-medium">local</span>
<span className="text-xs text-muted-foreground font-mono">
{branch}
</span>
</TooltipContent>
</Tooltip>
<ContextMenu>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<ContextMenuTrigger asChild>{collapsedButton}</ContextMenuTrigger>
</TooltipTrigger>
<TooltipContent side="right" className="flex flex-col gap-0.5">
<span className="font-medium">local</span>
<span className="text-xs text-muted-foreground font-mono">
{branch}
</span>
</TooltipContent>
</Tooltip>
<ContextMenuContent>
<ContextMenuItem onSelect={onCopyBranchName}>
<LuGitBranch className="size-4 mr-2" strokeWidth={STROKE_WIDTH} />
Copy Branch Name
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
<DeleteWorkspaceDialog
workspaceId={id}
workspaceName={name}
Expand Down Expand Up @@ -132,6 +144,10 @@ export function CollapsedWorkspaceItem({
<LuCopy className="size-4 mr-2" strokeWidth={STROKE_WIDTH} />
Copy Path
</ContextMenuItem>
<ContextMenuItem onSelect={onCopyBranchName}>
Comment thread
AviPeltz marked this conversation as resolved.
<LuGitBranch className="size-4 mr-2" strokeWidth={STROKE_WIDTH} />
Copy Branch Name
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem
onSelect={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
LuEyeOff,
LuFolderOpen,
LuFolderPlus,
LuGitBranch,
LuMinus,
LuPencil,
LuX,
Expand Down Expand Up @@ -50,6 +51,7 @@ interface WorkspaceContextMenuProps {
onOpenInFinder: () => void;
onOpenInEditor: () => void;
onCopyPath: () => void;
onCopyBranchName: () => void;
onSetUnread: (isUnread: boolean) => void;
onResetStatus: () => void;
onDelete: () => void;
Expand All @@ -68,6 +70,7 @@ export function WorkspaceContextMenu({
onOpenInFinder,
onOpenInEditor,
onCopyPath,
onCopyBranchName,
onSetUnread,
onResetStatus,
onDelete,
Expand Down Expand Up @@ -150,6 +153,10 @@ export function WorkspaceContextMenu({
<LuCopy className="size-4 mr-2" strokeWidth={STROKE_WIDTH} />
Copy Path
</ContextMenuItem>
<ContextMenuItem onSelect={onCopyBranchName}>
<LuGitBranch className="size-4 mr-2" strokeWidth={STROKE_WIDTH} />
Copy Branch Name
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuSub>
<ContextMenuSubTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ export function WorkspaceListItem({
await copyToClipboard(worktreePath);
toast.success("Path copied to clipboard");
};
const handleCopyBranchName = async () => {
if (!branch) return;
await copyToClipboard(branch);
toast.success("Branch name copied to clipboard");
};
Comment thread
AviPeltz marked this conversation as resolved.

Comment on lines +246 to 251
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.

P1 Silent failure and missing error handling

The v1 sidebar's handleCopyBranchName silently returns without any user feedback when branch is falsy, and has no try/catch around copyToClipboard. If the clipboard write fails the error is swallowed and the success toast is never shown.

The v2 sidebar implementation in useDashboardSidebarWorkspaceItemActions.ts handles both cases correctly — it shows a toast.error for the missing-branch case and wraps the copy in a try/catch with an error toast. The two implementations should be consistent.

Suggested change
const handleCopyBranchName = async () => {
if (!branch) return;
await copyToClipboard(branch);
};
const handleCopyBranchName = async () => {
if (!branch) {
toast.error("Branch name is not available");
return;
}
try {
await copyToClipboard(branch);
toast.success("Branch name copied");
} catch (error) {
toast.error(
`Failed to copy branch name: ${error instanceof Error ? error.message : "Unknown error"}`,
);
}
};
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx
Line: 246-250

Comment:
**Silent failure and missing error handling**

The v1 sidebar's `handleCopyBranchName` silently returns without any user feedback when `branch` is falsy, and has no `try/catch` around `copyToClipboard`. If the clipboard write fails the error is swallowed and the success toast is never shown.

The v2 sidebar implementation in `useDashboardSidebarWorkspaceItemActions.ts` handles both cases correctly — it shows a `toast.error` for the missing-branch case and wraps the copy in a try/catch with an error toast. The two implementations should be consistent.

```suggestion
	const handleCopyBranchName = async () => {
		if (!branch) {
			toast.error("Branch name is not available");
			return;
		}
		try {
			await copyToClipboard(branch);
			toast.success("Branch name copied");
		} catch (error) {
			toast.error(
				`Failed to copy branch name: ${error instanceof Error ? error.message : "Unknown error"}`,
			);
		}
	};
```

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

const pr = githubStatus?.pr;
const diffStats =
Expand Down Expand Up @@ -270,6 +275,7 @@ export function WorkspaceListItem({
onClick={handleClick}
onDeleteClick={handleDeleteClick}
onCopyPath={handleCopyPath}
onCopyBranchName={handleCopyBranchName}
/>
);
}
Expand Down Expand Up @@ -467,6 +473,7 @@ export function WorkspaceListItem({
onOpenInFinder={handleOpenInFinder}
onOpenInEditor={handleOpenInEditor}
onCopyPath={handleCopyPath}
onCopyBranchName={handleCopyBranchName}
onSetUnread={(unread) => setUnread.mutate({ id, isUnread: unread })}
onResetStatus={() => resetWorkspaceStatus(id)}
onDelete={handleDeleteClick}
Expand Down
Loading