- Remove hardcoded AGENT_NAME_MAP, load profiles from agent_profile_updated events - OGraphClient.loadAgentProfiles() fetches agent objects and replays profile events (LWW) - Hardcoded fallback map retained for graceful degradation - TaskDialog accepts dynamic agents list as prop - App.tsx loads profiles in parallel with tasks on startup
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { ALL_STATUSES, type Task, type TaskStatus } from "@/types"
|
|
import { KanbanColumn } from "@/components/KanbanColumn"
|
|
|
|
interface KanbanBoardProps {
|
|
tasks: Task[]
|
|
onTaskClick: (task: Task) => void
|
|
onAddTask: (status: TaskStatus) => void
|
|
onMoveTask: (taskId: number, status: TaskStatus) => void
|
|
}
|
|
|
|
export function KanbanBoard({ tasks, onTaskClick, onAddTask, onMoveTask }: KanbanBoardProps) {
|
|
return (
|
|
<div className="flex gap-4 overflow-x-auto pb-4 px-6 pt-4">
|
|
{ALL_STATUSES.map((status) => {
|
|
const columnTasks = tasks
|
|
.filter((t) => t.status === status)
|
|
.sort((a, b) => {
|
|
// Sort by priority first (p0 first), then by updatedAt descending
|
|
const prioOrder = a.priority.localeCompare(b.priority)
|
|
if (prioOrder !== 0) return prioOrder
|
|
return b.updatedAt - a.updatedAt
|
|
})
|
|
|
|
return (
|
|
<KanbanColumn
|
|
key={status}
|
|
status={status}
|
|
tasks={columnTasks}
|
|
onTaskClick={onTaskClick}
|
|
onAddTask={onAddTask}
|
|
onDrop={onMoveTask}
|
|
/>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
}
|