Files
fusion/packages/dashboard/app/components/Board.tsx
Dustin Byrne 57e380bb0f feat(HAI-100): add columnMovedAt timestamp and sort board tasks by move order
- Add columnMovedAt field to task types
- Set columnMovedAt on task creation and column moves in store
- Sort tasks by columnMovedAt descending in Board component
- Add store tests for columnMovedAt behavior
2026-03-26 22:44:11 -04:00

51 lines
1.9 KiB
TypeScript

import type { Task, TaskDetail, TaskCreateInput, Column as ColumnType } from "@hai/core";
import { COLUMNS } from "@hai/core";
import { Column } from "./Column";
import type { ToastType } from "../hooks/useToast";
interface BoardProps {
tasks: Task[];
maxConcurrent: number;
onMoveTask: (id: string, column: ColumnType) => Promise<Task>;
onOpenDetail: (task: TaskDetail) => void;
addToast: (message: string, type?: ToastType) => void;
isCreating: boolean;
onCancelCreate: () => void;
onCreateTask: (input: TaskCreateInput) => Promise<Task>;
onNewTask: () => void;
autoMerge: boolean;
onToggleAutoMerge: () => void;
}
export function Board({ tasks, maxConcurrent, onMoveTask, onOpenDetail, addToast, isCreating, onCancelCreate, onCreateTask, onNewTask, autoMerge, onToggleAutoMerge }: BoardProps) {
return (
<main className="board" id="board">
{COLUMNS.map((col) => (
<Column
key={col}
column={col}
tasks={tasks
.filter((t) => t.column === col)
.sort((a, b) => {
// Tasks with columnMovedAt sort descending (most recent first)
// Tasks without it (legacy) fall to the bottom, sorted by createdAt ascending
if (a.columnMovedAt && b.columnMovedAt) {
return b.columnMovedAt.localeCompare(a.columnMovedAt);
}
if (a.columnMovedAt && !b.columnMovedAt) return -1;
if (!a.columnMovedAt && b.columnMovedAt) return 1;
return a.createdAt.localeCompare(b.createdAt);
})}
allTasks={tasks}
maxConcurrent={maxConcurrent}
onMoveTask={onMoveTask}
onOpenDetail={onOpenDetail}
addToast={addToast}
{...(col === "triage" ? { isCreating, onCancelCreate, onCreateTask, onNewTask } : {})}
{...(col === "in-review" ? { autoMerge, onToggleAutoMerge } : {})}
/>
))}
</main>
);
}