Show error when remote branch status is unavailable (Vibe Kanban) (#1825)

* I've completed the implementation. Here's a summary of the changes:

## Summary

### Changes Made

1. **`frontend/src/hooks/useBranchStatus.ts`**
   - Modified to return `{ data, error, isError, isLoading, refetch }` instead of just the query result
   - This exposes the error state to consuming components

2. **`frontend/src/components/tasks/Toolbar/GitOperations.tsx`**
   - Added `branchStatusError` prop to interface
   - Removed `hasConflictsCalculated` from the "Change target branch" button's disabled condition - now it stays enabled even during errors, allowing users to recover
   - Changed the actions section from hiding completely when `selectedRepoStatus` is null to showing an error message when there's a `branchStatusError`

3. **`frontend/src/components/dialogs/tasks/GitActionsDialog.tsx`**
   - Extracted `error` from `useBranchStatus` and passes it to `GitOperations` as `branchStatusError`

4. **`frontend/src/pages/ProjectTasks.tsx`**
   - Updated `DiffsPanelContainer` to accept and pass `branchStatusError`
   - Extracted `branchStatusError` from `useBranchStatus` hook
   - Passes the error through to `DiffsPanelContainer`

5. **i18n translation files** (all 6 locales: en, es, ja, ko, zh-Hans, zh-Hant)
   - Added `git.errors.branchStatusUnavailable` translation string

### Behavior Changes

- **Before**: When branch status API failed, git operations (Merge, PR/Push, Rebase buttons) were completely hidden
- **After**:
  - An error message is shown: "Unable to fetch branch status. You can still change the target branch."
  - The "Change target branch" button remains enabled, allowing users to recover from deadlock situations
  - Users can see something went wrong instead of the UI silently failing

* Cleanup script changes for workspace cdcbb9c6-fc9f-45bf-9c30-0e432d06cccf

* Simplify useBranchStatus hook return

Return useQuery result directly instead of manually constructing an object.
The useQuery hook already returns all needed properties (data, error, isError, isLoading, refetch).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Restore hasConflictsCalculated check for change target branch button

The conflict check wasn't needed for the branch status error fix.
Keeping it prevents changing target branch during active git conflicts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Netsch
2026-01-08 13:42:15 +00:00
committed by GitHub
parent b63c90186e
commit 67711e77f4
9 changed files with 32 additions and 10 deletions

View File

@@ -35,7 +35,9 @@ function GitActionsDialogContent({
task,
}: GitActionsDialogContentProps) {
const { t } = useTranslation('tasks');
const { data: branchStatus } = useBranchStatus(attempt.id);
const { data: branchStatus, error: branchStatusError } = useBranchStatus(
attempt.id
);
const { isAttemptRunning } = useAttemptExecution(attempt.id);
const { error: gitError } = useGitOperationsError();
const { repos, selectedRepoId } = useAttemptRepo(attempt.id);
@@ -83,6 +85,7 @@ function GitActionsDialogContent({
selectedAttempt={attempt}
task={task}
branchStatus={branchStatus ?? null}
branchStatusError={branchStatusError}
isAttemptRunning={isAttemptRunning}
selectedBranch={getSelectedRepoStatus()?.target_branch_name ?? null}
layout="vertical"

View File

@@ -35,6 +35,7 @@ interface GitOperationsProps {
selectedAttempt: Workspace;
task: TaskWithAttemptStatus;
branchStatus: RepoBranchStatus[] | null;
branchStatusError?: Error | null;
isAttemptRunning: boolean;
selectedBranch: string | null;
layout?: 'horizontal' | 'vertical';
@@ -46,6 +47,7 @@ function GitOperations({
selectedAttempt,
task,
branchStatus,
branchStatusError,
isAttemptRunning,
selectedBranch,
layout = 'horizontal',
@@ -463,7 +465,12 @@ function GitOperations({
)}
{/* Right: Actions */}
{selectedRepoStatus && (
{branchStatusError && !selectedRepoStatus ? (
<div className="flex items-center gap-2 text-xs text-destructive">
<AlertTriangle className="h-3.5 w-3.5" />
<span>{t('git.errors.branchStatusUnavailable')}</span>
</div>
) : selectedRepoStatus ? (
<div className={actionsClasses}>
<Button
onClick={handleMergeClick}
@@ -523,7 +530,7 @@ function GitOperations({
<span className="truncate max-w-[10ch]">{rebaseButtonLabel}</span>
</Button>
</div>
)}
) : null}
</div>
</div>
);