import { Dispatch, SetStateAction, useCallback } from 'react'; import { Button } from '@/components/ui/button.tsx'; import { X } from 'lucide-react'; import type { GitBranch, Task } from 'shared/types'; import type { ExecutorConfig } from 'shared/types'; import type { ExecutorProfileId } from 'shared/types'; import type { TaskAttempt } from 'shared/types'; import { useAttemptCreation } from '@/hooks/useAttemptCreation'; import { useAttemptExecution } from '@/hooks/useAttemptExecution'; import BranchSelector from '@/components/tasks/BranchSelector.tsx'; import { ExecutorProfileSelector } from '@/components/settings'; import { useKeyboardShortcuts } from '@/lib/keyboard-shortcuts.ts'; import { showModal } from '@/lib/modals'; import { Card } from '@/components/ui/card'; import { Label } from '@/components/ui/label'; type Props = { task: Task; branches: GitBranch[]; taskAttempts: TaskAttempt[]; createAttemptBranch: string | null; selectedProfile: ExecutorProfileId | null; selectedBranch: string | null; setIsInCreateAttemptMode: Dispatch>; setCreateAttemptBranch: Dispatch>; setSelectedProfile: Dispatch>; availableProfiles: Record | null; selectedAttempt: TaskAttempt | null; }; function CreateAttempt({ task, branches, taskAttempts, createAttemptBranch, selectedProfile, selectedBranch, setIsInCreateAttemptMode, setCreateAttemptBranch, setSelectedProfile, availableProfiles, selectedAttempt, }: Props) { const { isAttemptRunning } = useAttemptExecution(selectedAttempt?.id); const { createAttempt, isCreating } = useAttemptCreation(task.id); // Create attempt logic const actuallyCreateAttempt = useCallback( async (profile: ExecutorProfileId, baseBranch?: string) => { const effectiveBaseBranch = baseBranch || selectedBranch; if (!effectiveBaseBranch) { throw new Error('Base branch is required to create an attempt'); } await createAttempt({ profile, baseBranch: effectiveBaseBranch, }); }, [createAttempt, selectedBranch] ); // Handler for Enter key or Start button const onCreateNewAttempt = useCallback( async ( profile: ExecutorProfileId, baseBranch?: string, isKeyTriggered?: boolean ) => { if (task.status === 'todo' && isKeyTriggered) { try { const result = await showModal<'confirmed' | 'canceled'>( 'create-attempt-confirm', { title: 'Start New Attempt?', message: 'Are you sure you want to start a new attempt for this task? This will create a new session and branch.', } ); if (result === 'confirmed') { await actuallyCreateAttempt(profile, baseBranch); setIsInCreateAttemptMode(false); } } catch (error) { // User cancelled - do nothing } } else { await actuallyCreateAttempt(profile, baseBranch); setIsInCreateAttemptMode(false); } }, [task.status, actuallyCreateAttempt, setIsInCreateAttemptMode] ); // Keyboard shortcuts useKeyboardShortcuts({ onEnter: () => { if (!selectedProfile) { return; } onCreateNewAttempt( selectedProfile, createAttemptBranch || undefined, true ); }, hasOpenDialog: false, closeDialog: () => {}, }); const handleExitCreateAttemptMode = () => { setIsInCreateAttemptMode(false); }; const handleCreateAttempt = () => { if (!selectedProfile) { return; } onCreateNewAttempt(selectedProfile, createAttemptBranch || undefined); }; return (
Create Attempt
{taskAttempts.length > 0 && ( )}
{/* Top Row: Executor Profile and Variant (spans 2 columns) */} {availableProfiles && (
)} {/* Bottom Row: Base Branch and Start Button */}
); } export default CreateAttempt;