feat(git): add multi-remote push with remote selection and fork-aware PR creation (#365)
* fix: Usage drop down should be scrollable * fix: When there are multiple remotes, provide the user with an option of which branch to push to * feat(gitview): add remote-push selection and auto checkout on create * feat: enable selecting remote when creating PR * fix: show PR icon in create button when not creating * fix(pullrequest): drop remote picker and use explicit remote * feat: add remote selection for PR status and creation * fix: improve PR creation with selected remote and fork head * chore(ui): simplify PR remote link UI * fix(web): handle cross-repo PRs and branch validation * feat: add remote selection for commit and push * feat(git): delegate PR head source resolution to server * chore(web): remove noisy PR creation logs
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
RiAiGenerate2,
|
||||
RiLoader4Line,
|
||||
RiEmotionHappyLine,
|
||||
RiArrowDownSLine,
|
||||
} from '@remixicon/react';
|
||||
import {
|
||||
Collapsible,
|
||||
@@ -15,6 +16,13 @@ import { CommitInput } from './CommitInput';
|
||||
import { AIHighlightsBox } from './AIHighlightsBox';
|
||||
import { useDeviceInfo } from '@/lib/device';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import type { GitRemote } from '@/lib/api/types';
|
||||
|
||||
type CommitAction = 'commit' | 'commitAndPush' | null;
|
||||
|
||||
@@ -28,11 +36,12 @@ interface CommitSectionProps {
|
||||
onGenerateMessage: () => void;
|
||||
isGeneratingMessage: boolean;
|
||||
onCommit: () => void;
|
||||
onCommitAndPush: () => void;
|
||||
onCommitAndPush: (remote?: GitRemote) => void;
|
||||
commitAction: CommitAction;
|
||||
isBusy: boolean;
|
||||
gitmojiEnabled: boolean;
|
||||
onOpenGitmojiPicker: () => void;
|
||||
remotes?: GitRemote[];
|
||||
variant?: 'framed' | 'plain';
|
||||
}
|
||||
|
||||
@@ -51,11 +60,13 @@ export const CommitSection: React.FC<CommitSectionProps> = ({
|
||||
isBusy,
|
||||
gitmojiEnabled,
|
||||
onOpenGitmojiPicker,
|
||||
remotes = [],
|
||||
variant = 'framed',
|
||||
}) => {
|
||||
const hasSelectedFiles = selectedCount > 0;
|
||||
const canCommit = commitMessage.trim() && hasSelectedFiles && commitAction === null;
|
||||
const { isMobile } = useDeviceInfo();
|
||||
const hasMultipleRemotes = remotes.length > 1;
|
||||
|
||||
const containerClassName =
|
||||
variant === 'framed'
|
||||
@@ -165,31 +176,113 @@ export const CommitSection: React.FC<CommitSectionProps> = ({
|
||||
</ButtonLarge>
|
||||
|
||||
{isMobile ? (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
hasMultipleRemotes ? (
|
||||
<DropdownMenu>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
disabled={!canCommit || isGeneratingMessage}
|
||||
className="h-7 gap-0.5 px-1.5"
|
||||
aria-label="Commit & Push"
|
||||
>
|
||||
{commitAction === 'commitAndPush' ? (
|
||||
<RiLoader4Line className="size-4 animate-spin" />
|
||||
) : (
|
||||
<>
|
||||
<RiArrowUpLine className="size-4" />
|
||||
<RiArrowDownSLine className="size-3 opacity-60" />
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
<p>Commit & Push</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<DropdownMenuContent align="end" className="min-w-[200px]">
|
||||
{remotes.map((remote) => (
|
||||
<DropdownMenuItem key={remote.name} onSelect={() => onCommitAndPush(remote)}>
|
||||
<div className="flex flex-col">
|
||||
<span className="typography-ui-label text-foreground">
|
||||
{remote.name}
|
||||
</span>
|
||||
<span className="typography-meta text-muted-foreground truncate">
|
||||
{remote.pushUrl}
|
||||
</span>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={() => onCommitAndPush()}
|
||||
disabled={!canCommit || isGeneratingMessage}
|
||||
className="h-7 w-7 p-0"
|
||||
aria-label="Commit & Push"
|
||||
>
|
||||
{commitAction === 'commitAndPush' ? (
|
||||
<RiLoader4Line className="size-4 animate-spin" />
|
||||
) : (
|
||||
<RiArrowUpLine className="size-4" />
|
||||
)}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
<p>Commit & Push</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)
|
||||
) : hasMultipleRemotes ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<ButtonLarge
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={onCommitAndPush}
|
||||
disabled={!canCommit || isGeneratingMessage}
|
||||
className="h-7 w-7 p-0"
|
||||
className="commit-actions__btn"
|
||||
aria-label="Commit & Push"
|
||||
>
|
||||
{commitAction === 'commitAndPush' ? (
|
||||
<RiLoader4Line className="size-4 animate-spin" />
|
||||
<>
|
||||
<RiLoader4Line className="size-4 animate-spin" />
|
||||
<span className="commit-actions__label commit-actions__label--long">Pushing...</span>
|
||||
</>
|
||||
) : (
|
||||
<RiArrowUpLine className="size-4" />
|
||||
<>
|
||||
<RiArrowUpLine className="size-4" />
|
||||
<span className="commit-actions__label commit-actions__label--long">Commit & Push</span>
|
||||
<RiArrowDownSLine className="size-3.5 opacity-60 -mr-0.5" />
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
<p>Commit & Push</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</ButtonLarge>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="min-w-[200px]">
|
||||
{remotes.map((remote) => (
|
||||
<DropdownMenuItem key={remote.name} onSelect={() => onCommitAndPush(remote)}>
|
||||
<div className="flex flex-col">
|
||||
<span className="typography-ui-label text-foreground">
|
||||
{remote.name}
|
||||
</span>
|
||||
<span className="typography-meta text-muted-foreground truncate">
|
||||
{remote.pushUrl}
|
||||
</span>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<ButtonLarge
|
||||
variant="default"
|
||||
onClick={onCommitAndPush}
|
||||
onClick={() => onCommitAndPush()}
|
||||
disabled={!canCommit || isGeneratingMessage}
|
||||
className="commit-actions__btn"
|
||||
aria-label="Commit & Push"
|
||||
|
||||
Reference in New Issue
Block a user