diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index b7628c9c..ebd83fac 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -1153,13 +1153,7 @@ export function BoardView() { autoMode.stop(); } }} - onAddFeature={() => setShowAddDialog(true)} onOpenPlanDialog={() => setShowPlanDialog(true)} - addFeatureShortcut={{ - key: shortcuts.addFeature, - action: () => setShowAddDialog(true), - description: 'Add new feature', - }} isMounted={isMounted} /> @@ -1252,6 +1246,7 @@ export function BoardView() { featuresWithContext={featuresWithContext} runningAutoTasks={runningAutoTasks} onArchiveAllVerified={() => setShowArchiveAllVerifiedDialog(true)} + onAddFeature={() => setShowAddDialog(true)} pipelineConfig={ currentProject?.path ? pipelineConfigByProject[currentProject.path] || null : null } diff --git a/apps/ui/src/components/views/board-view/board-header.tsx b/apps/ui/src/components/views/board-view/board-header.tsx index 45bb8d40..36b19acc 100644 --- a/apps/ui/src/components/views/board-view/board-header.tsx +++ b/apps/ui/src/components/views/board-view/board-header.tsx @@ -1,11 +1,9 @@ import { useState, useCallback } from 'react'; -import { HotkeyButton } from '@/components/ui/hotkey-button'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { Switch } from '@/components/ui/switch'; import { Label } from '@/components/ui/label'; -import { Plus, Bot, Wand2, Settings2, GitBranch } from 'lucide-react'; -import { KeyboardShortcut } from '@/hooks/use-keyboard-shortcuts'; +import { Bot, Wand2, Settings2, GitBranch } from 'lucide-react'; import { UsagePopover } from '@/components/usage-popover'; import { useAppStore } from '@/store/app-store'; import { useSetupStore } from '@/store/setup-store'; @@ -20,9 +18,7 @@ interface BoardHeaderProps { onConcurrencyChange: (value: number) => void; isAutoModeRunning: boolean; onAutoModeToggle: (enabled: boolean) => void; - onAddFeature: () => void; onOpenPlanDialog: () => void; - addFeatureShortcut: KeyboardShortcut; isMounted: boolean; } @@ -38,9 +34,7 @@ export function BoardHeader({ onConcurrencyChange, isAutoModeRunning, onAutoModeToggle, - onAddFeature, onOpenPlanDialog, - addFeatureShortcut, isMounted, }: BoardHeaderProps) { const [showAutoModeSettings, setShowAutoModeSettings] = useState(false); @@ -176,17 +170,6 @@ export function BoardHeader({ Plan - - - - Add Feature - ); diff --git a/apps/ui/src/components/views/board-view/components/kanban-column.tsx b/apps/ui/src/components/views/board-view/components/kanban-column.tsx index 4e08cfba..4a1b62dd 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-column.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-column.tsx @@ -10,6 +10,8 @@ interface KanbanColumnProps { count: number; children: ReactNode; headerAction?: ReactNode; + /** Floating action button at the bottom of the column */ + footerAction?: ReactNode; opacity?: number; showBorder?: boolean; hideScrollbar?: boolean; @@ -24,6 +26,7 @@ export const KanbanColumn = memo(function KanbanColumn({ count, children, headerAction, + footerAction, opacity = 100, showBorder = true, hideScrollbar = false, @@ -79,12 +82,21 @@ export const KanbanColumn = memo(function KanbanColumn({ hideScrollbar && '[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]', // Smooth scrolling - 'scroll-smooth' + 'scroll-smooth', + // Add padding at bottom if there's a footer action + footerAction && 'pb-14' )} > {children} + {/* Floating Footer Action */} + {footerAction && ( +
+ {footerAction} +
+ )} + {/* Drop zone indicator when dragging over */} {isOver && (
diff --git a/apps/ui/src/components/views/board-view/kanban-board.tsx b/apps/ui/src/components/views/board-view/kanban-board.tsx index 2962852d..9a3a5c26 100644 --- a/apps/ui/src/components/views/board-view/kanban-board.tsx +++ b/apps/ui/src/components/views/board-view/kanban-board.tsx @@ -4,7 +4,7 @@ import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable' import { Button } from '@/components/ui/button'; import { KanbanColumn, KanbanCard } from './components'; import { Feature } from '@/store/app-store'; -import { Archive, Settings2, CheckSquare, GripVertical } from 'lucide-react'; +import { Archive, Settings2, CheckSquare, GripVertical, Plus } from 'lucide-react'; import { useResponsiveKanban } from '@/hooks/use-responsive-kanban'; import { getColumnsWithPipeline, type ColumnId } from './constants'; import type { PipelineConfig } from '@automaker/types'; @@ -43,6 +43,7 @@ interface KanbanBoardProps { featuresWithContext: Set; runningAutoTasks: string[]; onArchiveAllVerified: () => void; + onAddFeature: () => void; pipelineConfig: PipelineConfig | null; onOpenPipelineSettings?: () => void; // Selection mode props @@ -78,6 +79,7 @@ export function KanbanBoard({ featuresWithContext, runningAutoTasks, onArchiveAllVerified, + onAddFeature, pipelineConfig, onOpenPipelineSettings, isSelectionMode = false, @@ -127,26 +129,38 @@ export function KanbanBoard({ Complete All ) : column.id === 'backlog' ? ( - +
+ + +
) : column.id === 'in_progress' ? ( + ) : undefined + } > f.id)}