Edit branch name (vibe-kanban) (#1182)
* ## ✅ Implementation Complete! I've successfully implemented the branch name editing feature. Here's what was added: ### **Backend Changes** 1. **Database Model** ([task_attempt.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/db/src/models/task_attempt.rs#L407-L421)) - Added `update_branch_name()` method to update the branch field 2. **Git Service** ([git.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/services/src/services/git.rs#L1508-L1526)) - Added `rename_local_branch()` to handle actual Git branch renaming using libgit2 3. **API Endpoint** ([task_attempts.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/server/src/routes/task_attempts.rs#L1111-L1196)) - Added `POST /task-attempts/{id}/rename-branch` endpoint - **Validation:** empty names, Git name validity, duplicates, active rebase, open PRs - **Flow:** validate → ensure worktree → rename in git → update DB → track analytics ### **Frontend Changes** 4. **API Client** ([api.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/lib/api.ts#L533-L546)) - Added `renameBranch()` method 5. **Actions Menu** ([ActionsDropdown.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/components/ui/ActionsDropdown.tsx#L93-L102)) - Added "Edit Branch Name" menu item 6. **Dialog Component** ([EditBranchNameDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/components/dialogs/tasks/EditBranchNameDialog.tsx)) - Text input with validation - Shows backend errors - Auto-refreshes data on success ### **Key Features** ✅ Renames actual Git branch (not just DB) ✅ Blocks when open PR exists ✅ Blocks during active rebase ✅ Validates branch name format ✅ Prevents duplicate branch names ✅ Analytics tracking ✅ All checks pass The feature is now ready to use from the task attempt dropdown menu! * Cleanup script changes for task attempt 98509988-cc54-4336-a94a-fb43c16a8235 * ## ✅ Cache Invalidation Fix Complete! I've updated [EditBranchNameDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/components/dialogs/tasks/EditBranchNameDialog.tsx#L59-L71) to invalidate all relevant query keys after renaming a branch. ### What Changed The dialog now invalidates **5 query keys** instead of just 2: 1. ✅ `['taskAttempt', attemptId]` - **Main fix** for DiffsPanel 2. ✅ `['attempt', attemptId]` - Legacy compatibility 3. ✅ `['attemptBranch', attemptId]` - Branch-specific data 4. ✅ `['branchStatus', attemptId]` - Git operations panel 5. ✅ `['taskAttempts']` - Attempts list in TaskPanel ### Result Now when you rename a branch, **all components immediately show the new name**: - ✅ DiffsPanel (branch name in Git operations toolbar) - ✅ TaskPanel (attempts list) - ✅ GitOperations component - ✅ Any other component displaying the attempt data **No page reload needed!** All checks pass. * Cleanup script changes for task attempt 98509988-cc54-4336-a94a-fb43c16a8235 * ## ✅ Refactored to Use Hook Pattern! I've successfully extracted the mutation logic into a proper `useRenameBranch` hook following the codebase's established patterns. ### Changes Made **1. Created new hook:** [useRenameBranch.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/hooks/useRenameBranch.ts) - Uses `useMutation` from TanStack Query - Handles cache invalidation internally - Provides callbacks for success/error handling - Follows the same pattern as `useChangeTargetBranch`, `useMerge`, `usePush` **2. Simplified EditBranchNameDialog:** - Removed manual API call and cache invalidation - Removed local `isLoading` state (uses `mutation.isPending` instead) - Removed `queryClient` import - Much cleaner and more focused on UI **3. Updated hooks exports:** [index.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/hooks/index.ts#L7) ### Before vs After **Before (inline mutation):** - 40+ lines of try/catch, API calls, and invalidation logic - Manual loading state management - Hard to test, hard to reuse **After (hook-based):** - ~10 lines in dialog - Hook encapsulates all mutation logic - Reusable, testable, consistent with codebase ### Benefits ✅ **Consistency** - Matches existing patterns (useChangeTargetBranch, useMerge, etc.) ✅ **Reusability** - Can be used anywhere branch renaming is needed ✅ **Testability** - Hook can be unit tested separately ✅ **Maintainability** - Single source of truth for invalidation logic ✅ **Cleaner Dialog** - Dialog focuses purely on UI concerns All checks pass! * Cleanup script changes for task attempt 98509988-cc54-4336-a94a-fb43c16a8235 * ## ✅ i18n Check Complete! All internationalization issues have been resolved: ### Fixed Issues **1. Missing translation keys** - Added to all locales (en, es, ja, ko): - `actionsMenu.editBranchName` **2. Hardcoded strings in EditBranchNameDialog** - Now using translation keys: - Dialog title → `t('editBranchName.dialog.title')` - Dialog description → `t('editBranchName.dialog.description')` - Branch name label → `t('editBranchName.dialog.branchNameLabel')` - Placeholder text → `t('editBranchName.dialog.placeholder')` - "Renaming..." → `t('editBranchName.dialog.renaming')` - "Rename Branch" → `t('editBranchName.dialog.action')` ### Translations Added **English:** "Edit branch name" **Spanish (es):** "Editar nombre de rama" **Japanese (ja):** "ブランチ名を編集" **Korean (ko):** "브랜치 이름 편집" ### Results ✅ **No new literal strings introduced** ✅ **No duplicate keys found** ✅ **Translation keys consistent across all locales** ✅ **All type checks pass** The feature is now fully internationalized and ready for users in all supported languages! * Cleanup script changes for task attempt 98509988-cc54-4336-a94a-fb43c16a8235 * ## ✅ Child Task Updates Complete! I've successfully implemented the fix to update child task attempts when renaming a branch. ### What Was Added **1. Database Helper** ([task_attempt.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/db/src/models/task_attempt.rs#L422-L445)) - Added `update_target_branch_for_children_of_attempt()` method - Uses single scoped SQL UPDATE with subquery - Only affects attempts for direct child tasks - Returns count of updated attempts **2. Rename Branch Endpoint** ([task_attempts.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/server/src/routes/task_attempts.rs#L1219-L1239)) - Stores old branch name before update - After renaming, updates all child task attempts - Logs count of updated children - Tracks updated count in analytics ### How It Works **Scenario:** 1. Parent attempt has branch `feature/old` 2. User creates 2 subtasks from parent attempt 3. Subtask attempts inherit `target_branch = "feature/old"` 4. Parent branch renamed to `feature/new` 5. ✅ Both subtask attempts automatically get `target_branch = "feature/new"` **SQL Query:** ```sql UPDATE task_attempts SET target_branch = 'feature/new' WHERE target_branch = 'feature/old' AND task_id IN ( SELECT id FROM tasks WHERE parent_task_attempt = parent_attempt_id ) ``` ### What's Updated ✅ `target_branch` for all attempts of direct child tasks ✅ Only when it matches the old branch name ✅ Scoped by parent-child relationship (via `parent_task_attempt` FK) ### What's NOT Updated ❌ Unrelated attempts that happen to use same branch name ❌ Child attempts' own `branch` field (they have their own branches) ❌ GitHub PR bases (would need GitHub API call) ### Result ✅ Child task attempts continue to work correctly after parent branch rename ✅ Efficient single-query update ✅ Safe scoping prevents unintended changes ✅ All checks pass * Cleanup script changes for task attempt 98509988-cc54-4336-a94a-fb43c16a8235 * ## ✅ Analytics & Types Fixed! ### Changes Made **1. Analytics Anonymity** ([task_attempts.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/server/src/routes/task_attempts.rs#L1240-L1248)) - Removed `old_branch` and `new_branch` from analytics event - Now only tracks: `attempt_id` and `updated_children` (anonymous) **2. Type Export** ([generate_types.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/crates/server/src/bin/generate_types.rs#L51-L52)) - Added `RenameBranchRequest::decl()` and `RenameBranchResponse::decl()` - Types now exported to [shared/types.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/shared/types.ts) **3. Frontend Type Usage** ([api.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/9850-edit-branch-name/frontend/src/lib/api.ts#L49-L50)) - Imported `RenameBranchRequest` and `RenameBranchResponse` from shared types - Changed signature from `Promise<{ branch: string }>` to `Promise<RenameBranchResponse>` - Uses properly typed request payload ### Results ✅ **Anonymous analytics** - No branch names (PII) sent ✅ **Type-safe** - Frontend/backend use same shared types ✅ **Consistent** - Matches pattern of other API methods ✅ **All checks pass** - TypeScript, Rust, and i18n * ## ✅ Analytics Now Fully Anonymous! Removed `attempt_id` from the analytics event. Now the event only tracks: ```json { "updated_children": 0 } ``` Fully anonymous - no IDs, no branch names, no PII. Just aggregate counts for usage metrics. All checks pass!
This commit is contained in:
committed by
GitHub
parent
6ecf592c40
commit
947cb53f44
@@ -264,9 +264,20 @@
|
||||
"createNewAttempt": "Create new attempt",
|
||||
"createSubtask": "Create subtask",
|
||||
"gitActions": "Git actions",
|
||||
"editBranchName": "Edit branch name",
|
||||
"task": "Task",
|
||||
"duplicate": "Duplicate"
|
||||
},
|
||||
"editBranchName": {
|
||||
"dialog": {
|
||||
"title": "Edit Branch Name",
|
||||
"description": "Enter a new name for the branch. Cannot rename if an open PR exists.",
|
||||
"branchNameLabel": "Branch Name",
|
||||
"placeholder": "e.g., feature/my-branch",
|
||||
"renaming": "Renaming...",
|
||||
"action": "Rename Branch"
|
||||
}
|
||||
},
|
||||
"showcases": {
|
||||
"taskPanel": {
|
||||
"companion": {
|
||||
|
||||
@@ -7,12 +7,23 @@
|
||||
"createNewAttempt": "Create new attempt",
|
||||
"createSubtask": "Create subtask",
|
||||
"duplicate": "Duplicate",
|
||||
"editBranchName": "Editar nombre de rama",
|
||||
"gitActions": "Acciones de Git",
|
||||
"openInIde": "Open attempt in IDE",
|
||||
"task": "Task",
|
||||
"viewProcesses": "View processes",
|
||||
"viewRelatedTasks": "View related tasks"
|
||||
},
|
||||
"editBranchName": {
|
||||
"dialog": {
|
||||
"title": "Editar nombre de rama",
|
||||
"description": "Ingrese un nuevo nombre para la rama. No se puede renombrar si existe un PR abierto.",
|
||||
"branchNameLabel": "Nombre de rama",
|
||||
"placeholder": "ej., feature/mi-rama",
|
||||
"renaming": "Renombrando...",
|
||||
"action": "Renombrar rama"
|
||||
}
|
||||
},
|
||||
"attempt": {
|
||||
"actions": {
|
||||
"openInIde": "Abrir en IDE",
|
||||
|
||||
@@ -7,12 +7,23 @@
|
||||
"createNewAttempt": "Create new attempt",
|
||||
"createSubtask": "Create subtask",
|
||||
"duplicate": "Duplicate",
|
||||
"editBranchName": "ブランチ名を編集",
|
||||
"gitActions": "Gitアクション",
|
||||
"openInIde": "Open attempt in IDE",
|
||||
"task": "Task",
|
||||
"viewProcesses": "View processes",
|
||||
"viewRelatedTasks": "View related tasks"
|
||||
},
|
||||
"editBranchName": {
|
||||
"dialog": {
|
||||
"title": "ブランチ名を編集",
|
||||
"description": "ブランチの新しい名前を入力してください。オープンなPRが存在する場合は名前を変更できません。",
|
||||
"branchNameLabel": "ブランチ名",
|
||||
"placeholder": "例: feature/my-branch",
|
||||
"renaming": "名前を変更中...",
|
||||
"action": "ブランチ名を変更"
|
||||
}
|
||||
},
|
||||
"attempt": {
|
||||
"actions": {
|
||||
"openInIde": "IDEで開く",
|
||||
|
||||
@@ -7,12 +7,23 @@
|
||||
"createNewAttempt": "Create new attempt",
|
||||
"createSubtask": "Create subtask",
|
||||
"duplicate": "Duplicate",
|
||||
"editBranchName": "브랜치 이름 편집",
|
||||
"gitActions": "Git 작업",
|
||||
"openInIde": "Open attempt in IDE",
|
||||
"task": "Task",
|
||||
"viewProcesses": "View processes",
|
||||
"viewRelatedTasks": "View related tasks"
|
||||
},
|
||||
"editBranchName": {
|
||||
"dialog": {
|
||||
"title": "브랜치 이름 편집",
|
||||
"description": "브랜치의 새 이름을 입력하세요. 열려있는 PR이 있으면 이름을 변경할 수 없습니다.",
|
||||
"branchNameLabel": "브랜치 이름",
|
||||
"placeholder": "예: feature/my-branch",
|
||||
"renaming": "이름 변경 중...",
|
||||
"action": "브랜치 이름 변경"
|
||||
}
|
||||
},
|
||||
"attempt": {
|
||||
"actions": {
|
||||
"openInIde": "IDE에서 열기",
|
||||
|
||||
Reference in New Issue
Block a user