feat: improve task creation (#220)

This commit is contained in:
Carlos Florêncio
2026-02-13 17:26:38 +00:00
committed by GitHub
parent e2ba35b3bd
commit ea751d3ecc
32 changed files with 1177 additions and 699 deletions
+8 -2
View File
@@ -54,11 +54,17 @@ export const Combobox = memo(function Combobox({
showSearch = true,
}: ComboboxProps) {
const [open, setOpen] = useState(false)
// Track the highlighted item. Defaults to the selected value so the current
// selection is highlighted when the popover opens (not the first item).
const [highlighted, setHighlighted] = useState("")
const selectedOption = options.find((option) => option.value === value)
return (
<Popover open={open} onOpenChange={setOpen}>
<Popover open={open} onOpenChange={(next) => {
setOpen(next)
if (next) setHighlighted(value)
}}>
<PopoverTrigger asChild>
<Button
variant="ghost"
@@ -78,7 +84,7 @@ export const Combobox = memo(function Combobox({
</Button>
</PopoverTrigger>
<PopoverContent className={cn("w-[var(--radix-popover-trigger-width)] min-w-[300px] max-w-none p-0", className)} align="start">
<Command>
<Command value={highlighted} onValueChange={setHighlighted}>
{dropdownLabel ? (
<div className="text-muted-foreground px-2 py-1.5 text-xs border-b">
{dropdownLabel}
+2 -6
View File
@@ -61,7 +61,7 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {}
handleWorkspaceChange,
handleBoardChange,
deletingTaskId,
} = useKanbanActions({ kanban, workspaceState, boardsState });
} = useKanbanActions({ workspaceState, boardsState });
// Data fetching and derived state
const {
@@ -215,7 +215,6 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {}
onSearchChange={setSearchQuery}
/>
<TaskCreateDialog
key={isDialogOpen ? 'open' : 'closed'}
open={isDialogOpen}
onOpenChange={handleDialogOpenChange}
workspaceId={workspaceState.activeId}
@@ -235,7 +234,6 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {}
: null
}
onSuccess={handleDialogSuccess}
navigateOnSessionCreate={false}
initialValues={
editingTask
? {
@@ -246,11 +244,10 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {}
}
: undefined
}
submitLabel={editingTask ? 'Update' : 'Create'}
mode={editingTask ? 'edit' : 'create'}
/>
{/* Workflow automation session creation dialog */}
<TaskCreateDialog
key={isWorkflowDialogOpen ? 'workflow-open' : 'workflow-closed'}
open={isWorkflowDialogOpen}
onOpenChange={(open) => {
setIsWorkflowDialogOpen(open);
@@ -267,7 +264,6 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {}
title: '',
description: workflowAutomation?.taskDescription ?? '',
}}
submitLabel="Start Agent"
/>
{/* Approval warning modal */}
<AlertDialog open={!!moveError} onOpenChange={(open) => !open && setMoveError(null)}>
+2 -2
View File
@@ -138,7 +138,7 @@ export function KanbanCard({ task, repositoryName, onClick, onEdit, onDelete, on
style={style}
className={cn(
'max-h-48 bg-card rounded-sm data-[size=sm]:py-1 cursor-pointer mb-2 w-full py-0 relative border border-border overflow-visible shadow-none ring-0',
task.state === 'IN_PROGRESS' && 'kanban-task-pulse',
(task.state === 'IN_PROGRESS' || task.state === 'SCHEDULING') && 'kanban-task-pulse',
isDragging && 'opacity-50 z-50'
)}
onClick={() => onClick?.(task)}
@@ -151,7 +151,7 @@ export function KanbanCard({ task, repositoryName, onClick, onEdit, onDelete, on
repoName={repositoryName ?? null}
actions={
<div className="flex items-center gap-2">
{task.state === 'IN_PROGRESS' && statusIcon}
{(task.state === 'IN_PROGRESS' || task.state === 'SCHEDULING') && statusIcon}
{showMaximizeButton && onOpenFullPage && task.hasSession !== false && (
<button
type="button"
File diff suppressed because it is too large Load Diff
@@ -14,7 +14,7 @@ type AgentStatusProps = {
};
const STATE_CONFIG: Record<TaskSessionState, { label: string; icon: 'spinner' | 'error' | 'warning' | null }> = {
CREATED: { label: 'Agent is being created', icon: 'spinner' },
CREATED: { label: '', icon: null },
STARTING: { label: 'Agent is starting', icon: 'spinner' },
RUNNING: { label: 'Agent is running', icon: 'spinner' },
WAITING_FOR_INPUT: { label: '', icon: null },
@@ -43,7 +43,8 @@ export const VirtualizedMessageList = memo(function VirtualizedMessageList({
const previousHeightRef = useRef(0);
const isInitialLoading = messagesLoading && messages.length === 0;
const showLoadingState = (messagesLoading || isInitialLoading) && !isWorking;
const isCreatedSession = sessionState === 'CREATED';
const showLoadingState = (messagesLoading || isInitialLoading) && !isWorking && !isCreatedSession;
const { loadMore, hasMore, isLoading: isLoadingMore } = useLazyLoadMessages(sessionId);
const itemCount = items.length;
@@ -454,7 +454,7 @@ export const SessionTaskSwitcherSheet = memo(function SessionTaskSwitcherSheet({
<TaskCreateDialog
open={dialogOpen}
onOpenChange={setDialogOpen}
mode="task"
mode="create"
workspaceId={workspaceId}
boardId={boardId}
defaultColumnId={dialogColumns[0]?.id ?? null}
+1 -1
View File
@@ -64,7 +64,7 @@ export const TaskItem = memo(function TaskItem({
// Effective open state: keep menu open while deleting
const effectiveMenuOpen = menuOpen || isDeleting;
const isInProgress = state === 'IN_PROGRESS' || state === 'SCHEDULING' || state === 'CREATED';
const isInProgress = state === 'IN_PROGRESS' || state === 'SCHEDULING';
const hasDiffStats = diffStats && (diffStats.additions > 0 || diffStats.deletions > 0);
// Determine what to show on the right side
@@ -46,7 +46,7 @@ export const NewTaskButton = memo(function NewTaskButton({
<TaskCreateDialog
open={dialogOpen}
onOpenChange={setDialogOpen}
mode="task"
mode="create"
workspaceId={workspaceId}
boardId={boardId}
defaultColumnId={columns[0]?.id ?? null}