mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-02-03 15:43:06 +00:00
feat: move feature action buttons to pending column header
Move the "Add Feature" (+) and "Expand Project" (sparkles) buttons from the top navigation bar to the Pending column header in the Kanban board. Changes: - KanbanColumn: Add optional onAddFeature, onExpandProject, and showExpandButton props; render action buttons in column header - KanbanBoard: Accept and pass action handlers to the Pending column - App: Remove buttons from header, pass handlers to KanbanBoard This improves UX by placing feature creation actions contextually near the pending features they affect. Keyboard shortcuts (N, E) still work. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@ import { AssistantFAB } from './components/AssistantFAB'
|
|||||||
import { AssistantPanel } from './components/AssistantPanel'
|
import { AssistantPanel } from './components/AssistantPanel'
|
||||||
import { ExpandProjectModal } from './components/ExpandProjectModal'
|
import { ExpandProjectModal } from './components/ExpandProjectModal'
|
||||||
import { SettingsModal } from './components/SettingsModal'
|
import { SettingsModal } from './components/SettingsModal'
|
||||||
import { Plus, Loader2, Sparkles, Settings } from 'lucide-react'
|
import { Loader2, Settings } from 'lucide-react'
|
||||||
import type { Feature } from './lib/types'
|
import type { Feature } from './lib/types'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -171,31 +171,6 @@ function App() {
|
|||||||
|
|
||||||
{selectedProject && (
|
{selectedProject && (
|
||||||
<>
|
<>
|
||||||
<button
|
|
||||||
onClick={() => setShowAddFeature(true)}
|
|
||||||
className="neo-btn neo-btn-primary text-sm"
|
|
||||||
title="Add new feature"
|
|
||||||
>
|
|
||||||
<Plus size={18} />
|
|
||||||
<kbd className="ml-1.5 px-1.5 py-0.5 text-xs bg-black/20 rounded font-mono">
|
|
||||||
N
|
|
||||||
</kbd>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Expand Project - only show if project has features */}
|
|
||||||
{features && (features.pending.length + features.in_progress.length + features.done.length) > 0 && (
|
|
||||||
<button
|
|
||||||
onClick={() => setShowExpandProject(true)}
|
|
||||||
className="neo-btn bg-[var(--color-neo-progress)] text-black text-sm"
|
|
||||||
title="Expand project with AI"
|
|
||||||
>
|
|
||||||
<Sparkles size={18} />
|
|
||||||
<kbd className="ml-1.5 px-1.5 py-0.5 text-xs bg-black/20 rounded font-mono">
|
|
||||||
E
|
|
||||||
</kbd>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<AgentControl
|
<AgentControl
|
||||||
projectName={selectedProject}
|
projectName={selectedProject}
|
||||||
status={wsState.agentStatus}
|
status={wsState.agentStatus}
|
||||||
@@ -267,6 +242,8 @@ function App() {
|
|||||||
<KanbanBoard
|
<KanbanBoard
|
||||||
features={features}
|
features={features}
|
||||||
onFeatureClick={setSelectedFeature}
|
onFeatureClick={setSelectedFeature}
|
||||||
|
onAddFeature={() => setShowAddFeature(true)}
|
||||||
|
onExpandProject={() => setShowExpandProject(true)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,9 +4,13 @@ import type { Feature, FeatureListResponse } from '../lib/types'
|
|||||||
interface KanbanBoardProps {
|
interface KanbanBoardProps {
|
||||||
features: FeatureListResponse | undefined
|
features: FeatureListResponse | undefined
|
||||||
onFeatureClick: (feature: Feature) => void
|
onFeatureClick: (feature: Feature) => void
|
||||||
|
onAddFeature?: () => void
|
||||||
|
onExpandProject?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function KanbanBoard({ features, onFeatureClick }: KanbanBoardProps) {
|
export function KanbanBoard({ features, onFeatureClick, onAddFeature, onExpandProject }: KanbanBoardProps) {
|
||||||
|
const hasFeatures = features && (features.pending.length + features.in_progress.length + features.done.length) > 0
|
||||||
|
|
||||||
if (!features) {
|
if (!features) {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
@@ -32,6 +36,9 @@ export function KanbanBoard({ features, onFeatureClick }: KanbanBoardProps) {
|
|||||||
features={features.pending}
|
features={features.pending}
|
||||||
color="pending"
|
color="pending"
|
||||||
onFeatureClick={onFeatureClick}
|
onFeatureClick={onFeatureClick}
|
||||||
|
onAddFeature={onAddFeature}
|
||||||
|
onExpandProject={onExpandProject}
|
||||||
|
showExpandButton={hasFeatures}
|
||||||
/>
|
/>
|
||||||
<KanbanColumn
|
<KanbanColumn
|
||||||
title="In Progress"
|
title="In Progress"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { FeatureCard } from './FeatureCard'
|
import { FeatureCard } from './FeatureCard'
|
||||||
|
import { Plus, Sparkles } from 'lucide-react'
|
||||||
import type { Feature } from '../lib/types'
|
import type { Feature } from '../lib/types'
|
||||||
|
|
||||||
interface KanbanColumnProps {
|
interface KanbanColumnProps {
|
||||||
@@ -7,6 +8,9 @@ interface KanbanColumnProps {
|
|||||||
features: Feature[]
|
features: Feature[]
|
||||||
color: 'pending' | 'progress' | 'done'
|
color: 'pending' | 'progress' | 'done'
|
||||||
onFeatureClick: (feature: Feature) => void
|
onFeatureClick: (feature: Feature) => void
|
||||||
|
onAddFeature?: () => void
|
||||||
|
onExpandProject?: () => void
|
||||||
|
showExpandButton?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const colorMap = {
|
const colorMap = {
|
||||||
@@ -21,6 +25,9 @@ export function KanbanColumn({
|
|||||||
features,
|
features,
|
||||||
color,
|
color,
|
||||||
onFeatureClick,
|
onFeatureClick,
|
||||||
|
onAddFeature,
|
||||||
|
onExpandProject,
|
||||||
|
showExpandButton,
|
||||||
}: KanbanColumnProps) {
|
}: KanbanColumnProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -32,10 +39,34 @@ export function KanbanColumn({
|
|||||||
className="px-4 py-3 border-b-3 border-[var(--color-neo-border)]"
|
className="px-4 py-3 border-b-3 border-[var(--color-neo-border)]"
|
||||||
style={{ backgroundColor: colorMap[color] }}
|
style={{ backgroundColor: colorMap[color] }}
|
||||||
>
|
>
|
||||||
<h2 className="font-display text-lg font-bold uppercase flex items-center justify-between text-[var(--color-neo-text)]">
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="font-display text-lg font-bold uppercase flex items-center gap-2 text-[var(--color-neo-text)]">
|
||||||
{title}
|
{title}
|
||||||
<span className="neo-badge bg-white text-[var(--color-neo-text)]">{count}</span>
|
<span className="neo-badge bg-white text-[var(--color-neo-text)]">{count}</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
{(onAddFeature || onExpandProject) && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{onAddFeature && (
|
||||||
|
<button
|
||||||
|
onClick={onAddFeature}
|
||||||
|
className="neo-btn neo-btn-primary text-sm py-1.5 px-2"
|
||||||
|
title="Add new feature (N)"
|
||||||
|
>
|
||||||
|
<Plus size={16} />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{onExpandProject && showExpandButton && (
|
||||||
|
<button
|
||||||
|
onClick={onExpandProject}
|
||||||
|
className="neo-btn bg-[var(--color-neo-progress)] text-black text-sm py-1.5 px-2"
|
||||||
|
title="Expand project with AI (E)"
|
||||||
|
>
|
||||||
|
<Sparkles size={16} />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Cards */}
|
{/* Cards */}
|
||||||
|
|||||||
Reference in New Issue
Block a user