Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/renderer/components/MainContentArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const MainContentArea: React.FC<MainContentAreaProps> = ({
const {
activeTask,
activeTaskAgent,
tasksByProjectId,
isCreatingTask,
handleTaskInterfaceReady: onTaskInterfaceReady,
openTaskModal,
Expand All @@ -70,6 +71,7 @@ const MainContentArea: React.FC<MainContentAreaProps> = ({
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
<KanbanBoard
project={selectedProject}
tasks={tasksByProjectId[selectedProject.id] ?? []}
onOpenTask={(ws: any) => {
handleSelectTask(ws);
setShowKanban(false);
Expand Down
21 changes: 10 additions & 11 deletions src/renderer/components/kanban/KanbanBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ const titles: Record<KanbanStatus, string> = {

const KanbanBoard: React.FC<{
project: Project;
tasks: Task[];
onOpenTask?: (ws: Task) => void;
onCreateTask?: () => void;
}> = ({ project, onOpenTask, onCreateTask }) => {
}> = ({ project, tasks, onOpenTask, onCreateTask }) => {
const [statusMap, setStatusMap] = React.useState<Record<string, KanbanStatus>>({});
const wsList = React.useMemo(() => tasks, [tasks]);
const taskSignature = React.useMemo(() => wsList.map((task) => task.id).join('|'), [wsList]);

React.useEffect(() => {
setStatusMap(getAll());
Expand All @@ -31,7 +34,6 @@ const KanbanBoard: React.FC<{
React.useEffect(() => {
const offs: Array<() => void> = [];
const idleTimers = new Map<string, ReturnType<typeof setTimeout>>();
const wsList = project.tasks || [];
for (const ws of wsList) {
// Watch PTY output to capture terminal-based providers as activity
offs.push(watchTaskPty(ws.id));
Expand Down Expand Up @@ -99,12 +101,11 @@ const KanbanBoard: React.FC<{
}
return () => offs.forEach((f) => f());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [project.id, project.tasks?.length]);
}, [project.id, taskSignature]);

// Promote any task with local changes directly to "Ready for review" (done)
React.useEffect(() => {
let cancelled = false;
const wsList = project.tasks || [];
const check = async () => {
for (const ws of wsList) {
const variantPaths: string[] = (() => {
Expand Down Expand Up @@ -150,12 +151,11 @@ const KanbanBoard: React.FC<{
cancelled = true;
window.clearInterval(id);
};
}, [project.id, project.tasks?.length]);
}, [project.id, taskSignature]);

// Promote any task with an open PR to "Ready for review" (done)
React.useEffect(() => {
let cancelled = false;
const wsList = project.tasks || [];
const check = async () => {
for (const ws of wsList) {
const variantPaths: string[] = (() => {
Expand Down Expand Up @@ -201,11 +201,10 @@ const KanbanBoard: React.FC<{
cancelled = true;
window.clearInterval(id);
};
}, [project.id, project.tasks?.length]);
}, [project.id, taskSignature]);

React.useEffect(() => {
let cancelled = false;
const wsList = project.tasks || [];
const check = async () => {
for (const ws of wsList) {
const variantPaths: string[] = (() => {
Expand Down Expand Up @@ -253,14 +252,14 @@ const KanbanBoard: React.FC<{
cancelled = true;
window.clearInterval(id);
};
}, [project.id, project.tasks?.length]);
}, [project.id, taskSignature]);

const byStatus: Record<KanbanStatus, Task[]> = { todo: [], 'in-progress': [], done: [] };
for (const ws of project.tasks || []) {
for (const ws of wsList) {
const s = statusMap[ws.id] || 'todo';
byStatus[s].push(ws);
}
const hasAny = (project.tasks?.length ?? 0) > 0;
const hasAny = wsList.length > 0;

const handleDrop = (target: KanbanStatus, taskId: string) => {
setStatus(taskId, target);
Expand Down
Loading