refactor(ui): migrate board view to React Query

- Replace manual fetching in use-board-features with useFeatures query
- Migrate use-board-actions to use mutation hooks
- Update kanban-card and agent-info-panel to use query hooks
- Migrate agent-output-modal to useAgentOutput query
- Migrate create-pr-dialog to useCreatePR mutation
- Remove manual loading/error state management
- Add proper cache invalidation on mutations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Shirone
2026-01-15 16:21:23 +01:00
parent d08ef472a3
commit 3411256366
7 changed files with 160 additions and 402 deletions

View File

@@ -14,6 +14,7 @@ import { getElectronAPI } from '@/lib/electron';
import { isConnectionError, handleServerOffline } from '@/lib/http-api-client';
import { toast } from 'sonner';
import { useAutoMode } from '@/hooks/use-auto-mode';
import { useVerifyFeature, useResumeFeature } from '@/hooks/mutations';
import { truncateDescription } from '@/lib/utils';
import { getBlockingDependencies } from '@automaker/dependency-resolver';
import { createLogger } from '@automaker/utils/logger';
@@ -94,6 +95,10 @@ export function useBoardActions({
} = useAppStore();
const autoMode = useAutoMode();
// React Query mutations for feature operations
const verifyFeatureMutation = useVerifyFeature(currentProject?.path ?? '');
const resumeFeatureMutation = useResumeFeature(currentProject?.path ?? '');
// Worktrees are created when adding/editing features with a branch name
// This ensures the worktree exists before the feature starts execution
@@ -480,28 +485,9 @@ export function useBoardActions({
const handleVerifyFeature = useCallback(
async (feature: Feature) => {
if (!currentProject) return;
try {
const api = getElectronAPI();
if (!api?.autoMode) {
logger.error('Auto mode API not available');
return;
}
const result = await api.autoMode.verifyFeature(currentProject.path, feature.id);
if (result.success) {
logger.info('Feature verification started successfully');
} else {
logger.error('Failed to verify feature:', result.error);
await loadFeatures();
}
} catch (error) {
logger.error('Error verifying feature:', error);
await loadFeatures();
}
verifyFeatureMutation.mutate(feature.id);
},
[currentProject, loadFeatures]
[currentProject, verifyFeatureMutation]
);
const handleResumeFeature = useCallback(
@@ -511,40 +497,9 @@ export function useBoardActions({
logger.error('No current project');
return;
}
try {
const api = getElectronAPI();
if (!api?.autoMode) {
logger.error('Auto mode API not available');
return;
}
logger.info('Calling resumeFeature API...', {
projectPath: currentProject.path,
featureId: feature.id,
useWorktrees,
});
const result = await api.autoMode.resumeFeature(
currentProject.path,
feature.id,
useWorktrees
);
logger.info('resumeFeature result:', result);
if (result.success) {
logger.info('Feature resume started successfully');
} else {
logger.error('Failed to resume feature:', result.error);
await loadFeatures();
}
} catch (error) {
logger.error('Error resuming feature:', error);
await loadFeatures();
}
resumeFeatureMutation.mutate({ featureId: feature.id, useWorktrees });
},
[currentProject, loadFeatures, useWorktrees]
[currentProject, resumeFeatureMutation, useWorktrees]
);
const handleManualVerify = useCallback(