diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx index 0878c23cd53..068c1267b63 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/DashboardSidebarWorkspaceItem.tsx @@ -1,6 +1,9 @@ import { useNavigate } from "@tanstack/react-router"; +import { useState } from "react"; import { useDiffStats } from "renderer/hooks/host-service/useDiffStats"; +import { useOptimisticCollectionActions } from "renderer/routes/_authenticated/hooks/useOptimisticCollectionActions"; import { useDeletingWorkspaces } from "renderer/routes/_authenticated/providers/DeletingWorkspacesProvider"; +import { RenameBranchDialog } from "renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components"; import { useV2WorkspaceNotificationStatus } from "renderer/stores/v2-notifications"; import type { DashboardSidebarWorkspace } from "../../types"; import { DashboardSidebarDeleteDialog } from "../DashboardSidebarDeleteDialog"; @@ -67,6 +70,13 @@ export function DashboardSidebarWorkspaceItem({ }); const navigate = useNavigate(); + const { v2Workspaces: v2WorkspaceActions } = useOptimisticCollectionActions(); + const [renameBranchTarget, setRenameBranchTarget] = useState( + null, + ); + const handleAfterBranchRename = (newBranchName: string) => { + v2WorkspaceActions.updateWorkspace(id, { branch: newBranchName }); + }; const isPending = !!creationStatus; // Keep the delete dialog outside the hidden wrapper below — the destroy // flow reopens it into an error pane on conflict/teardown-failed. @@ -122,6 +132,7 @@ export function DashboardSidebarWorkspaceItem({ } isLocalWorkspace={hostType === "local-device"} @@ -153,6 +164,17 @@ export function DashboardSidebarWorkspaceItem({ onDeleted={handleDeleted} /> )} + {renameBranchTarget && ( + { + if (!open) setRenameBranchTarget(null); + }} + onAfterRename={handleAfterBranchRename} + /> + )} ); } @@ -196,6 +218,7 @@ export function DashboardSidebarWorkspaceItem({ } onCreateSection={handleCreateSection} @@ -227,6 +250,17 @@ export function DashboardSidebarWorkspaceItem({ onDeleted={handleDeleted} /> )} + {renameBranchTarget && ( + { + if (!open) setRenameBranchTarget(null); + }} + onAfterRename={handleAfterBranchRename} + /> + )} ); } diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceHoverCardContent/DashboardSidebarWorkspaceHoverCardContent.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceHoverCardContent/DashboardSidebarWorkspaceHoverCardContent.tsx index 667b816e84e..e3dffa07be2 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceHoverCardContent/DashboardSidebarWorkspaceHoverCardContent.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarWorkspaceHoverCardContent/DashboardSidebarWorkspaceHoverCardContent.tsx @@ -2,7 +2,12 @@ import { Button } from "@superset/ui/button"; import { Kbd, KbdGroup } from "@superset/ui/kbd"; import { formatDistanceToNow } from "date-fns"; import { FaGithub } from "react-icons/fa"; -import { LuExternalLink, LuGlobe, LuTriangleAlert } from "react-icons/lu"; +import { + LuExternalLink, + LuGlobe, + LuPencil, + LuTriangleAlert, +} from "react-icons/lu"; import type { DiffStats } from "renderer/hooks/host-service/useDiffStats"; import { useHotkeyDisplay } from "renderer/hotkeys"; import type { DashboardSidebarWorkspace } from "../../../../types"; @@ -14,11 +19,13 @@ import { ReviewStatus } from "./components/ReviewStatus"; interface DashboardSidebarWorkspaceHoverCardContentProps { workspace: DashboardSidebarWorkspace; diffStats: DiffStats | null; + onEditBranchClick?: (branchName: string) => void; } export function DashboardSidebarWorkspaceHoverCardContent({ workspace, diffStats, + onEditBranchClick, }: DashboardSidebarWorkspaceHoverCardContentProps) { const { name, @@ -59,23 +66,37 @@ export function DashboardSidebarWorkspaceHoverCardContent({ Branch - {repoUrl && branchExistsOnRemote ? ( - - {branch} - - - ) : ( - - {branch} - - )} +
+ {onEditBranchClick ? ( + + ) : ( + + {branch} + + )} + {repoUrl && branchExistsOnRemote && ( + e.stopPropagation()} + > + + + )} +
{formatDistanceToNow(createdAt, { addSuffix: true })} diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/CollapsedWorkspaceItem.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/CollapsedWorkspaceItem.tsx index fb910d4fd49..14a052c8356 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/CollapsedWorkspaceItem.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/CollapsedWorkspaceItem.tsx @@ -17,7 +17,11 @@ 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"; -import { DeleteWorkspaceDialog, WorkspaceHoverCardContent } from "./components"; +import { + DeleteWorkspaceDialog, + RenameBranchDialog, + WorkspaceHoverCardContent, +} from "./components"; import { HOVER_CARD_CLOSE_DELAY, HOVER_CARD_OPEN_DELAY } from "./constants"; import { WorkspaceIcon } from "./WorkspaceIcon"; @@ -62,6 +66,9 @@ export function CollapsedWorkspaceItem({ [onDeleteClick], ); const [isContextMenuOpen, setIsContextMenuOpen] = useState(false); + const [renameBranchTarget, setRenameBranchTarget] = useState( + null, + ); const collapsedButton = ( + + + + + + ); +} diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/RenameBranchDialog/index.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/RenameBranchDialog/index.ts new file mode 100644 index 00000000000..4c810563485 --- /dev/null +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/RenameBranchDialog/index.ts @@ -0,0 +1 @@ +export { RenameBranchDialog } from "./RenameBranchDialog"; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx index 4fab6df7245..42ef7472217 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx @@ -6,6 +6,7 @@ import { LuExternalLink, LuGlobe, LuLoaderCircle, + LuPencil, LuTriangleAlert, } from "react-icons/lu"; import { useHotkeyDisplay } from "renderer/hotkeys"; @@ -20,11 +21,13 @@ import { ReviewStatus } from "./components/ReviewStatus"; interface WorkspaceHoverCardContentProps { workspaceId: string; workspaceAlias?: string; + onEditBranchClick?: (branchName: string) => void; } export function WorkspaceHoverCardContent({ workspaceId, workspaceAlias, + onEditBranchClick, }: WorkspaceHoverCardContentProps) { const { data: worktreeInfo } = electronTrpc.workspaces.getWorktreeInfo.useQuery( @@ -80,26 +83,43 @@ export function WorkspaceHoverCardContent({ Branch - {repoUrl && branchExistsOnRemote ? ( - - {branchName} - - - ) : ( - - {branchName} - - )} +
+ {onEditBranchClick ? ( + + ) : ( + + {branchName} + + )} + {repoUrl && branchExistsOnRemote && ( + e.stopPropagation()} + > + + + )} +
)} {worktreeInfo?.createdAt && ( diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/index.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/index.ts index 489dd1ba41a..4d0ce41efb9 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/index.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/index.ts @@ -1,2 +1,3 @@ export { DeleteWorkspaceDialog } from "./DeleteWorkspaceDialog"; +export { RenameBranchDialog } from "./RenameBranchDialog"; export { WorkspaceHoverCardContent } from "./WorkspaceHoverCard";