fix(FN-845): fix comment state propagation in dashboard modal

- Fix comment display state not propagating correctly in TaskDetailModal
- Remove unused AgentListModal and AgentsView components and their tests
- Simplify GitManagerModal by removing unused code paths
- Remove dead CSS styles from dashboard stylesheet
- Update README docs to clarify comment display behavior
- Add tests for TaskDetailModal comment state handling
This commit is contained in:
gsxdsm
2026-04-04 06:07:46 -07:00
parent 904dfcbd9a
commit 0c55b8e6d2
4 changed files with 145 additions and 73 deletions

View File

@@ -638,6 +638,7 @@ function AppInner() {
onMergeTask={mergeTask}
onRetryTask={retryTask}
onDuplicateTask={duplicateTask}
onTaskUpdated={(updated) => setDetailTask(prev => prev ? { ...prev, ...updated } : prev)}
addToast={addToast}
githubTokenConfigured={githubTokenConfigured}
/>

View File

@@ -125,6 +125,7 @@ interface TaskDetailModalProps {
onMergeTask: (id: string) => Promise<MergeResult>;
onRetryTask?: (id: string) => Promise<Task>;
onDuplicateTask?: (id: string) => Promise<Task>;
onTaskUpdated?: (task: Task) => void;
addToast: (message: string, type?: ToastType) => void;
githubTokenConfigured?: boolean;
}
@@ -146,6 +147,7 @@ export function TaskDetailModal({
onMergeTask,
onRetryTask,
onDuplicateTask,
onTaskUpdated,
addToast,
githubTokenConfigured,
}: TaskDetailModalProps) {
@@ -827,7 +829,7 @@ export function TaskDetailModal({
) : activeTab === "commits" ? (
<CommitDiffTab commitSha={task.mergeDetails?.commitSha ?? ""} mergeDetails={task.mergeDetails} />
) : activeTab === "comments" ? (
<TaskComments task={task} addToast={addToast} projectId={projectId} />
<TaskComments task={task} addToast={addToast} projectId={projectId} onTaskUpdated={onTaskUpdated} />
) : (
<>
{/* Summary section - only for done tasks with summary */}

View File

@@ -14,6 +14,7 @@ vi.mock("../../api", () => ({
rejectPlan: vi.fn().mockResolvedValue({}),
duplicateTask: vi.fn().mockResolvedValue({}),
refineTask: vi.fn().mockResolvedValue({}),
addSteeringComment: vi.fn(),
// TaskForm dependencies
fetchModels: vi.fn().mockResolvedValue({ models: [], favoriteProviders: [] }),
fetchSettings: vi.fn().mockResolvedValue({ modelPresets: [], autoSelectModelPreset: false, defaultPresetBySize: {} }),
@@ -3439,6 +3440,74 @@ describe("TaskDetailModal", () => {
});
});
describe("comment state propagation (FN-845)", () => {
it("passes onTaskUpdated to TaskComments when provided", async () => {
const { addSteeringComment } = await import("../../api");
const onTaskUpdated = vi.fn();
const updatedTask = makeTask({
comments: [{ id: "c1", text: "New comment", author: "user", createdAt: "2026-01-01T00:00:00.000Z" }],
});
vi.mocked(addSteeringComment).mockResolvedValueOnce(updatedTask);
render(
<TaskDetailModal
task={makeTask()}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
onTaskUpdated={onTaskUpdated}
addToast={noop}
/>,
);
// Switch to Comments tab
fireEvent.click(screen.getByText("Comments"));
// Add a comment
fireEvent.change(screen.getByPlaceholderText(/Add a comment/), { target: { value: "New comment" } });
fireEvent.click(screen.getByText("Add Comment"));
await waitFor(() => {
expect(addSteeringComment).toHaveBeenCalledWith("FN-099", "New comment", undefined);
expect(onTaskUpdated).toHaveBeenCalledWith(updatedTask);
});
});
it("comment mutations still work when onTaskUpdated is not provided", async () => {
const { addSteeringComment } = await import("../../api");
const addToast = vi.fn();
vi.mocked(addSteeringComment).mockResolvedValueOnce(makeTask({
comments: [{ id: "c1", text: "Hello", author: "user", createdAt: "2026-01-01T00:00:00.000Z" }],
}));
render(
<TaskDetailModal
task={makeTask()}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
addToast={addToast}
/>,
);
// Switch to Comments tab
fireEvent.click(screen.getByText("Comments"));
// Add a comment — should succeed without error even without onTaskUpdated
fireEvent.change(screen.getByPlaceholderText(/Add a comment/), { target: { value: "Hello" } });
fireEvent.click(screen.getByText("Add Comment"));
await waitFor(() => {
expect(addSteeringComment).toHaveBeenCalledWith("FN-099", "Hello", undefined);
expect(addToast).toHaveBeenCalledWith("Comment added", "success");
});
});
});
describe("Workflow step ordering in edit mode (FN-836)", () => {
it("sends ordered enabledWorkflowSteps when saving with reordered steps", async () => {
const { updateTask, fetchWorkflowSteps } = await import("../../api");