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
@@ -1,3 +1,4 @@
import { toast } from "@superset/ui/sonner";
import { createFileRoute, notFound, useNavigate } from "@tanstack/react-router";
import { useCallback, useMemo } from "react";
import { electronTrpc } from "renderer/lib/electron-trpc";
Expand All @@ -8,6 +9,7 @@ import { usePresetHotkeys } from "renderer/routes/_authenticated/_dashboard/work
import { NotFound } from "renderer/routes/not-found";
import { WorkspaceInitializingView } from "renderer/screens/main/components/WorkspaceView/WorkspaceInitializingView";
import { WorkspaceLayout } from "renderer/screens/main/components/WorkspaceView/WorkspaceLayout";
import { usePRStatus } from "renderer/screens/main/hooks";
import { useAppHotkey } from "renderer/stores/hotkeys";
import { SidebarMode, useSidebarStore } from "renderer/stores/sidebar-state";
import { getPaneDimensions } from "renderer/stores/tabs/pane-refs";
Expand Down Expand Up @@ -251,6 +253,25 @@ function WorkspacePage() {
[workspace?.worktreePath],
);

// Open PR shortcut (⌘⇧P)
const { pr } = usePRStatus({ workspaceId });
const createPRMutation = electronTrpc.changes.createPR.useMutation({
onSuccess: () => toast.success("Opening GitHub..."),
onError: (error) => toast.error(`Failed: ${error.message}`),
});
useAppHotkey(
"OPEN_PR",
() => {
if (pr?.url) {
window.open(pr.url, "_blank");
} else if (workspace?.worktreePath) {
createPRMutation.mutate({ worktreePath: workspace.worktreePath });
}
},
undefined,
[pr?.url, workspace?.worktreePath],
);

// Toggle changes sidebar (⌘L)
useAppHotkey("TOGGLE_SIDEBAR", () => toggleSidebar(), undefined, [
toggleSidebar,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
DropdownMenuTrigger,
} from "@superset/ui/dropdown-menu";
import { toast } from "@superset/ui/sonner";
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import { HiChevronDown } from "react-icons/hi2";
import { LuLoaderCircle } from "react-icons/lu";
import { LuGitPullRequest, LuLoaderCircle } from "react-icons/lu";
import { VscGitMerge } from "react-icons/vsc";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { PRIcon } from "renderer/screens/main/components/PRIcon";
Expand Down Expand Up @@ -37,6 +38,14 @@ export function PRButton({
onError: (error) => toast.error(`Merge failed: ${error.message}`),
});

const createPRMutation = electronTrpc.changes.createPR.useMutation({
onSuccess: () => {
toast.success("Opening GitHub...");
onRefresh();
},
onError: (error) => toast.error(`Failed: ${error.message}`),
});

const handleMergePR = (strategy: "merge" | "squash" | "rebase") =>
mergePRMutation.mutate({ worktreePath, strategy, deleteBranch: true });

Expand All @@ -46,7 +55,27 @@ export function PRButton({
);
}

if (!pr) return null;
if (!pr) {
return (
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
className="flex items-center ml-auto hover:opacity-80 transition-opacity disabled:opacity-50"
onClick={() => createPRMutation.mutate({ worktreePath })}
disabled={createPRMutation.isPending}
>
{createPRMutation.isPending ? (
<LuLoaderCircle className="w-4 h-4 animate-spin text-muted-foreground" />
) : (
<LuGitPullRequest className="w-4 h-4 text-muted-foreground" />
)}
</button>
Comment on lines +58 to +73
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.

⚠️ Potential issue | 🟡 Minor

Add an accessible label for the icon-only PR button.

The create-PR button is icon-only, so screen readers won’t get a usable name. Add aria-label (and optionally aria-busy) to make it discoverable.

♿ Suggested accessibility fix
 					<button
 						type="button"
 						className="flex items-center ml-auto hover:opacity-80 transition-opacity disabled:opacity-50"
 						onClick={() => createPRMutation.mutate({ worktreePath })}
 						disabled={createPRMutation.isPending}
+						aria-label={
+							createPRMutation.isPending
+								? "Creating pull request"
+								: "Create Pull Request"
+						}
+						aria-busy={createPRMutation.isPending}
 					>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!pr) {
return (
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
className="flex items-center ml-auto hover:opacity-80 transition-opacity disabled:opacity-50"
onClick={() => createPRMutation.mutate({ worktreePath })}
disabled={createPRMutation.isPending}
>
{createPRMutation.isPending ? (
<LuLoaderCircle className="w-4 h-4 animate-spin text-muted-foreground" />
) : (
<LuGitPullRequest className="w-4 h-4 text-muted-foreground" />
)}
</button>
if (!pr) {
return (
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
className="flex items-center ml-auto hover:opacity-80 transition-opacity disabled:opacity-50"
onClick={() => createPRMutation.mutate({ worktreePath })}
disabled={createPRMutation.isPending}
aria-label={
createPRMutation.isPending
? "Creating pull request"
: "Create Pull Request"
}
aria-busy={createPRMutation.isPending}
>
{createPRMutation.isPending ? (
<LuLoaderCircle className="w-4 h-4 animate-spin text-muted-foreground" />
) : (
<LuGitPullRequest className="w-4 h-4 text-muted-foreground" />
)}
</button>
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/components/ChangesHeader/components/PRButton/PRButton.tsx`
around lines 58 - 73, PRButton renders an icon-only button when no PR exists;
add accessibility attributes so screen readers can announce it: update the
button inside PRButton (the element using createPRMutation.mutate and
worktreePath) to include a descriptive aria-label (e.g., "Create pull request")
and set aria-busy={createPRMutation.isPending} while the mutation is pending;
keep the existing disabled prop and visual loading icon behavior.

</TooltipTrigger>
<TooltipContent side="bottom">Create Pull Request</TooltipContent>
</Tooltip>
);
}

const canMerge = pr.state === "open";

Expand Down
6 changes: 6 additions & 0 deletions apps/desktop/src/shared/hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,12 @@ export const HOTKEYS = {
category: "Workspace",
description: "Open an existing project folder",
}),
OPEN_PR: defineHotkey({
keys: "meta+shift+p",
label: "Open Pull Request",
category: "Workspace",
description: "Open existing PR or create a new one on GitHub",
}),

// Window
NEW_WINDOW: defineHotkey({
Expand Down
Loading