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:
@@ -638,6 +638,7 @@ function AppInner() {
|
||||
onMergeTask={mergeTask}
|
||||
onRetryTask={retryTask}
|
||||
onDuplicateTask={duplicateTask}
|
||||
onTaskUpdated={(updated) => setDetailTask(prev => prev ? { ...prev, ...updated } : prev)}
|
||||
addToast={addToast}
|
||||
githubTokenConfigured={githubTokenConfigured}
|
||||
/>
|
||||
|
||||
@@ -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 */}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user