Merge branch 'feature/story-28-ui-show-test-todos'

This commit is contained in:
Dave
2026-02-19 15:36:04 +00:00
13 changed files with 606 additions and 17 deletions

View File

@@ -9,6 +9,7 @@ import type { Message, ProviderConfig, ToolCall } from "../types";
import { ChatHeader } from "./ChatHeader";
import { GatePanel } from "./GatePanel";
import { ReviewPanel } from "./ReviewPanel";
import { TodoPanel } from "./TodoPanel";
const { useCallback, useEffect, useRef, useState } = React;
@@ -61,6 +62,12 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
const [lastGateRefresh, setLastGateRefresh] = useState<Date | null>(null);
const [isCollectingCoverage, setIsCollectingCoverage] = useState(false);
const [coverageError, setCoverageError] = useState<string | null>(null);
const [storyTodos, setStoryTodos] = useState<
{ storyId: string; storyName: string | null; items: string[] }[]
>([]);
const [todoError, setTodoError] = useState<string | null>(null);
const [isTodoLoading, setIsTodoLoading] = useState(false);
const [lastTodoRefresh, setLastTodoRefresh] = useState<Date | null>(null);
const storyId = "26_establish_tdd_workflow_and_gates";
const gateStatusColor = isGateLoading
@@ -255,6 +262,68 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
};
}, []);
useEffect(() => {
let active = true;
setIsTodoLoading(true);
setTodoError(null);
workflowApi
.getStoryTodos()
.then((response) => {
if (!active) return;
setStoryTodos(
response.stories.map((s) => ({
storyId: s.story_id,
storyName: s.story_name,
items: s.todos,
})),
);
setLastTodoRefresh(new Date());
})
.catch((error) => {
if (!active) return;
const message =
error instanceof Error
? error.message
: "Failed to load story TODOs.";
setTodoError(message);
setStoryTodos([]);
})
.finally(() => {
if (active) {
setIsTodoLoading(false);
}
});
return () => {
active = false;
};
}, []);
const refreshTodos = async () => {
setIsTodoLoading(true);
setTodoError(null);
try {
const response = await workflowApi.getStoryTodos();
setStoryTodos(
response.stories.map((s) => ({
storyId: s.story_id,
storyName: s.story_name,
items: s.todos,
})),
);
setLastTodoRefresh(new Date());
} catch (error) {
const message =
error instanceof Error ? error.message : "Failed to load story TODOs.";
setTodoError(message);
setStoryTodos([]);
} finally {
setIsTodoLoading(false);
}
};
const refreshGateState = async (targetStoryId: string = storyId) => {
setIsGateLoading(true);
setGateError(null);
@@ -599,6 +668,14 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
onCollectCoverage={handleCollectCoverage}
isCollectingCoverage={isCollectingCoverage}
/>
<TodoPanel
todos={storyTodos}
isTodoLoading={isTodoLoading}
todoError={todoError}
lastTodoRefresh={lastTodoRefresh}
onRefresh={refreshTodos}
/>
</div>
</div>