-
Notifications
You must be signed in to change notification settings - Fork 975
Refactor branch fetching to use repo IDs instead of project IDs (Vibe Kanban) #1560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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[]`
## 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
… 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.
**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.
…iffs panel - showing available branches for git operations when viewing an attempt's diffs.
**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
**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`
**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.
…es` 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.
… `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.
Vibe Kanban Review FailedUnfortunately, the code review could not be completed. Review ID: |
Vibe Kanban Review FailedUnfortunately, the code review could not be completed. Review ID: |
1 similar comment
Vibe Kanban Review FailedUnfortunately, the code review could not be completed. Review ID: |
Vibe Kanban Review FailedUnfortunately, the code review could not be completed. Review ID: |
ggordonhall
approved these changes
Dec 16, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Refactors the branch fetching architecture to decouple branches from projects, enabling future task attempts without projects attached.
Key Changes
Backend:
/api/projects/{id}/branchesendpoint and related types (ProjectBranchesResponse,RepositoryBranches)/api/repos/{repoId}/branchesFrontend Hooks:
useRepoBranches(repoId)- single repo branch fetching with proper cachinguseProjectRepos(projectId)- fetches repos for a project (setup phase only)useBranchesintouseRepoBranchSelection- eliminated intermediate hookuseRebase,useMerge,useChangeTargetBranch) to userepoBranchKeysfor cache invalidationprojectIdfromuseGitOperations- now usesrepoIdonlyComponents:
GitOperationsnow fetches branches internally viauseRepoBranches(selectedRepoId)instead of receiving as propsprojectIdandbranchesprops fromGitActionsDialogandDiffsPanelContainerTaskFormDialogandCreateAttemptDialogto useuseRepoBranchSelectionArchitecture
The refactored architecture cleanly separates:
useProjectRepos(projectId)→useRepoBranchSelection({repos})→ create attemptuseAttemptRepo(attemptId)→useRepoBranches(repoId)→ git operationsQuery keys are now repo-scoped (
['repoBranches', repoId]) enabling proper cache sharing across components.Files Changed
useBranches.ts, backendget_project_brancheshandlerThis PR was written using Vibe Kanban