Files
vibe-kanban/crates/server/src/bin
Alex Netsch f989b47470 Refactor branch fetching to use repo IDs instead of project IDs (Vibe Kanban) (#1560)
* All tasks are complete. Here's a summary of the changes made:

## Summary

Successfully refactored the project branches API to fetch branches using repo IDs instead of project IDs.

### Files Created
- `frontend/src/hooks/useRepoBranches.ts` - New hook that fetches branches for a single repository using `repoApi.getBranches(repoId)`

### Files Modified

1. **`frontend/src/hooks/index.ts`** - Added export for `useRepoBranches`

2. **`frontend/src/components/dialogs/tasks/GitActionsDialog.tsx`**
   - Removed `useState` for `repoBranches` and `loadingBranches`
   - Removed `useEffect` that called `projectsApi.getBranches(effectiveProjectId)`
   - Removed `useMemo` that filtered branches by `selectedRepoId`
   - Now uses `useRepoBranches(selectedRepoId)` to fetch branches directly for the selected repo from the task attempt

3. **`frontend/src/components/dialogs/tasks/CreatePRDialog.tsx`**
   - Removed `projectId` from props interface and component destructuring
   - Removed `useState` for `branches` and `branchesLoading`
   - Removed branch-fetching logic from useEffect
   - Now uses `useRepoBranches(repoId)` to fetch branches directly for the specified repo
   - Split useEffect into two: one for form initialization, one for setting default base branch

4. **`frontend/src/components/tasks/Toolbar/GitOperations.tsx`**
   - Removed `projectId` from `CreatePRDialog.show()` call

### Benefits
- More efficient - fetches only branches for the specific repo needed instead of all project repos
- Better caching - React Query caches branches per repo for efficient reuse
- Cleaner code - removed manual filtering logic from components
- Type safety - hooks return `GitBranch[]` directly instead of `RepositoryBranches[]`

* All tasks complete. Here's a summary of the changes made:

## Summary

Successfully decoupled the branches API from project IDs.

### Changes Made

**1. `frontend/src/hooks/useBranches.ts`** - Refactored to accept `repos: Array<{ id: string; name: string }>` instead of `projectId`
- Now uses `useQueries` to fetch branches for multiple repos in parallel
- Reuses the same query keys as `useRepoBranches` for cache consistency

**2. `frontend/src/hooks/useRepoBranchSelection.ts`** - Refactored to accept `repos: Repo[]` instead of `projectId`
- Removed internal fetch of project repos (caller now provides them)
- Removed `projectRepos` from return value
- Uses refactored `useBranches(repos)`

**3. `frontend/src/components/dialogs/tasks/CreateAttemptDialog.tsx`**
- Added `useQuery` to fetch project repos separately
- Passes `repos` to `useRepoBranchSelection`

**4. `frontend/src/components/dialogs/tasks/TaskFormDialog.tsx`**
- Already fetched `projectRepos`
- Updated to pass `projectRepos` to refactored `useBranches`

**5. `frontend/src/components/layout/Navbar.tsx`**
- Replaced `useBranches(projectId)` with `useQuery` for `projectsApi.getRepositories`
- Only needed repo count, not branches

**6. `frontend/src/components/projects/ProjectCard.tsx`**
- Replaced `useBranches(project.id)` with `useQuery` for `projectsApi.getRepositories`
- Only needed repo count, not branches

### Benefits
- Branch hooks no longer require a project ID
- Repos can come from any source (project, attempt, or future sources without projects)
- Better separation of concerns
- Enables future task attempts without projects attached

* Cleanup script changes for task attempt 6b5b9208-565d-4620-9fe3-20791db77d7a

* The fix is already applied. Type checks pass with `Repo[]` instead of the loose `Array<{ id: string; name: string }>` type.

This makes it explicit that `useBranches` expects actual `Repo` objects (with `Repo.id` being the repository's UUID), not project-repo junction records.

* All done. The refactor is complete:

**Summary of changes:**

1. **Created `useProjectRepos` hook** (`frontend/src/hooks/useProjectRepos.ts`) - A reusable hook that fetches project repositories with proper query key management

2. **Updated 5 files** to use the new hook instead of duplicating the `useQuery` pattern:
   - `CreateAttemptDialog.tsx`
   - `TaskFormDialog.tsx`
   - `Navbar.tsx`
   - `ProjectCard.tsx`
   - `NoServerContent.tsx`

3. **Earlier refactors** (from before the summary):
   - `useBranches.ts` - Now accepts `repos: Repo[]` instead of `projectId`
   - `useRepoBranchSelection.ts` - Now accepts `repos: Repo[]` instead of `projectId`

This enables future task attempts without projects attached, as branch fetching is now decoupled from project IDs.

* No more usages. The branches in `ProjectTasks.tsx` are used for the diffs panel - showing available branches for git operations when viewing an attempt's diffs.

* Cleanup script changes for task attempt 6b5b9208-565d-4620-9fe3-20791db77d7a

* All done. The refactor is complete:

**Summary of changes:**

`GitOperations` now fetches its own branches using `useRepoBranches(selectedRepoId)` instead of receiving them as a prop. This:

1. Removes prop drilling through `ProjectTasks` → `DiffsPanelContainer` → `DiffsPanel` → `GitOperations`
2. Removes the need for `ProjectTasks` to fetch all project repos just to get branches for the selected repo
3. Makes `GitOperations` self-contained - it already has `selectedRepoId` from `useAttemptRepo`, so it can fetch its own branches
4. Simplifies `GitActionsDialog` which no longer needs to fetch branches either

* All done. Here's a summary of the changes:

**Removed `projectId` from GitOperations flow:**

1. **`useRebase.ts`** - Changed param from `projectId` to `repoId`, updated invalidation to use `repoBranchKeys.byRepo(repoId)`

2. **`useChangeTargetBranch.ts`** - Changed param from `projectId` to `repoId`, updated invalidation to use `repoBranchKeys.byRepo(repoId)`

3. **`useMerge.ts`** - Updated invalidation to use `repoBranchKeys.all` instead of `['projectBranches']`

4. **`useGitOperations.ts`** - Changed param from `projectId` to `repoId`

5. **`GitOperations.tsx`** - Removed `projectId` prop, now passes `selectedRepoId` to `useGitOperations`

6. **`GitActionsDialog.tsx`** - Removed `projectId` from props and internal logic

7. **`DiffsPanelContainer`** (in ProjectTasks.tsx) - Removed `projectId` prop

8. **Callers of `GitActionsDialog.show`** - Removed `projectId` from `NextActionCard.tsx` and `actions-dropdown.tsx`

* The cleanup is complete. Here's a summary of what was done:

**Removed dead project branches code:**

1. **Backend** (`crates/server/src/routes/projects.rs`):
   - Removed `get_project_branches` handler and route
   - Removed `RepositoryBranches` and `ProjectBranchesResponse` structs
   - Fixed unused `Serialize` import warning

2. **Type Generation** (`crates/server/src/bin/generate_types.rs`):
   - Removed exports for `ProjectBranchesResponse` and `RepositoryBranches`

3. **Frontend Hooks** (`frontend/src/hooks/useBranches.ts`):
   - Defined local `RepositoryBranches` type instead of importing from shared/types

4. **Frontend API** (`frontend/src/lib/api.ts`):
   - Removed `projectsApi.getBranches` method
   - Removed `RepositoryBranches` and `ProjectBranchesResponse` imports

Both TypeScript and Rust compilation pass without errors.

* Done. Removed the `RepositoryBranches` type and simplified `useBranches` to return `Map<string, GitBranch[]>`. Changes:

1. **`useBranches.ts`** - Returns `Map<string, GitBranch[]>` instead of `RepositoryBranches[]`
2. **`useRepoBranchSelection.ts`** - Uses `branchMap.get(repo.id) ?? []` instead of `.find()`
3. **`TaskFormDialog.tsx`** - Uses `branchMap.get(repo.id) ?? []` instead of `.find()`

Type checks pass.

* Done. Deleted `useBranches` entirely and consolidated everything into `useRepoBranchSelection`. Summary:

1. **Deleted** `frontend/src/hooks/useBranches.ts`
2. **Updated** `useRepoBranchSelection.ts` - inlined the `useQueries` logic directly
3. **Updated** `hooks/index.ts` - removed `useBranches` export
4. **Updated** `TaskFormDialog.tsx` - now uses `useRepoBranchSelection` instead of duplicating the config-building logic

Type checks pass.

* types
2025-12-16 14:21:42 +00:00
..