Make it possible to create draft PRs (vibe-kanban) (#1460)

* All checks pass. Let me summarize what was implemented:

## Summary

I've successfully implemented the draft PR feature. Here's what was changed:

### Backend Changes

1. **`crates/server/src/routes/task_attempts.rs`** (lines 70-76, 724-731):
   - Added `draft: Option<bool>` field to `CreateGitHubPrRequest` struct
   - Pass the draft field to the `CreatePrRequest` when creating PRs

2. **`crates/services/src/services/github.rs`** (lines 146-153):
   - Added `draft: Option<bool>` field to `CreatePrRequest` struct

3. **`crates/services/src/services/github/cli.rs`** (lines 158-160):
   - Added logic to pass `--draft` flag to `gh pr create` when draft is true

### Frontend Changes

4. **`frontend/src/components/dialogs/tasks/CreatePRDialog.tsx`**:
   - Added `Checkbox` import
   - Added `isDraft` state (default: false)
   - Added checkbox UI with label from translations
   - Pass `draft: isDraft` in the API call
   - Reset `isDraft` on success and cancel

### Type Generation

5. **`shared/types.ts`** (auto-generated):
   - `CreateGitHubPrRequest` now includes `draft: boolean | null`

### Translations

6. Added `"draftLabel"` translation key to all locale files:
   - `frontend/src/i18n/locales/en/tasks.json`: "Create as draft"
   - `frontend/src/i18n/locales/es/tasks.json`: "Crear como borrador"
   - `frontend/src/i18n/locales/ja/tasks.json`: "下書きとして作成"
   - `frontend/src/i18n/locales/ko/tasks.json`: "초안으로 만들기"
   - `frontend/src/i18n/locales/zh-Hans/tasks.json`: "创建为草稿"

* Done. I've updated the checkbox to use `h-5 w-5` (20px) and added `text-sm` to the label for consistent sizing.
This commit is contained in:
Louis Knight-Webb
2025-12-08 16:53:37 +00:00
committed by GitHub
parent 047695e554
commit 9c70858b21
10 changed files with 30 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ import { Label } from '@radix-ui/react-label';
import { Textarea } from '@/components/ui/textarea.tsx';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import BranchSelector from '@/components/tasks/BranchSelector';
import { useCallback, useEffect, useMemo, useState } from 'react';
@@ -56,6 +57,7 @@ const CreatePRDialogImpl = NiceModal.create<CreatePRDialogProps>(
);
const [branches, setBranches] = useState<GitBranch[]>([]);
const [branchesLoading, setBranchesLoading] = useState(false);
const [isDraft, setIsDraft] = useState(false);
const getGhCliHelpTitle = (variant: GhCliSupportVariant) =>
variant === 'homebrew'
@@ -136,12 +138,14 @@ const CreatePRDialogImpl = NiceModal.create<CreatePRDialogProps>(
title: prTitle,
body: prBody || null,
target_branch: prBaseBranch || null,
draft: isDraft,
});
if (result.success) {
setPrTitle('');
setPrBody('');
setPrBaseBranch('');
setIsDraft(false);
setCreatingPR(false);
modal.hide();
return;
@@ -213,6 +217,7 @@ const CreatePRDialogImpl = NiceModal.create<CreatePRDialogProps>(
prBaseBranch,
prBody,
prTitle,
isDraft,
modal,
isMacEnvironment,
t,
@@ -224,6 +229,7 @@ const CreatePRDialogImpl = NiceModal.create<CreatePRDialogProps>(
setPrTitle('');
setPrBody('');
setPrBaseBranch('');
setIsDraft(false);
}, [modal]);
return (
@@ -286,6 +292,17 @@ const CreatePRDialogImpl = NiceModal.create<CreatePRDialogProps>(
}
/>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="pr-draft"
checked={isDraft}
onCheckedChange={setIsDraft}
className="h-5 w-5"
/>
<Label htmlFor="pr-draft" className="cursor-pointer text-sm">
{t('createPrDialog.draftLabel')}
</Label>
</div>
{ghCliHelp?.variant && (
<Alert variant="default">
<AlertTitle>

View File

@@ -355,6 +355,7 @@
"baseBranchLabel": "Base Branch",
"loadingBranches": "Loading branches...",
"selectBaseBranch": "Select base branch",
"draftLabel": "Create as draft",
"creating": "Creating...",
"createButton": "Create PR",
"errors": {

View File

@@ -112,6 +112,7 @@
"baseBranchLabel": "Rama Base",
"loadingBranches": "Cargando ramas...",
"selectBaseBranch": "Seleccionar rama base",
"draftLabel": "Crear como borrador",
"creating": "Creando...",
"createButton": "Crear PR",
"errors": {

View File

@@ -112,6 +112,7 @@
"baseBranchLabel": "ベースブランチ",
"loadingBranches": "ブランチを読み込み中...",
"selectBaseBranch": "ベースブランチを選択",
"draftLabel": "下書きとして作成",
"creating": "作成中...",
"createButton": "PRを作成",
"errors": {

View File

@@ -112,6 +112,7 @@
"baseBranchLabel": "기본 브랜치",
"loadingBranches": "브랜치 로딩 중...",
"selectBaseBranch": "기본 브랜치 선택",
"draftLabel": "초안으로 만들기",
"creating": "생성 중...",
"createButton": "PR 생성",
"errors": {

View File

@@ -355,6 +355,7 @@
"baseBranchLabel": "基础分支",
"loadingBranches": "加载分支中...",
"selectBaseBranch": "选择基础分支",
"draftLabel": "创建为草稿",
"creating": "创建中...",
"createButton": "创建 PR",
"errors": {