feat(HAI-057): add task dependency editing to dashboard UI
- Add dependencies field support to store updateTask method - Wire dependencies through PATCH route and client API - Add dependency editing UI (add/remove) to TaskDetailModal - Pass tasks prop from App to TaskDetailModal for dependency picker - Add tests for dependency CRUD in modal and API layer
This commit is contained in:
@@ -348,4 +348,41 @@ describe("TaskStore", () => {
|
||||
expect(result.log).toHaveLength(initialLogCount + 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateTask — dependencies", () => {
|
||||
it("adds dependencies to a task with none", async () => {
|
||||
const task = await createTestTask();
|
||||
expect(task.dependencies).toEqual([]);
|
||||
|
||||
const updated = await store.updateTask(task.id, { dependencies: ["HAI-001", "HAI-002"] });
|
||||
expect(updated.dependencies).toEqual(["HAI-001", "HAI-002"]);
|
||||
|
||||
// Verify persistence
|
||||
const fetched = await store.getTask(task.id);
|
||||
expect(fetched.dependencies).toEqual(["HAI-001", "HAI-002"]);
|
||||
});
|
||||
|
||||
it("replaces existing dependencies", async () => {
|
||||
const task = await store.createTask({ description: "Dep task", dependencies: ["HAI-001"] });
|
||||
expect(task.dependencies).toEqual(["HAI-001"]);
|
||||
|
||||
const updated = await store.updateTask(task.id, { dependencies: ["HAI-002", "HAI-003"] });
|
||||
expect(updated.dependencies).toEqual(["HAI-002", "HAI-003"]);
|
||||
});
|
||||
|
||||
it("clears dependencies with empty array", async () => {
|
||||
const task = await store.createTask({ description: "Dep task", dependencies: ["HAI-001"] });
|
||||
expect(task.dependencies).toEqual(["HAI-001"]);
|
||||
|
||||
const updated = await store.updateTask(task.id, { dependencies: [] });
|
||||
expect(updated.dependencies).toEqual([]);
|
||||
});
|
||||
|
||||
it("leaves dependencies unchanged when not provided", async () => {
|
||||
const task = await store.createTask({ description: "Dep task", dependencies: ["HAI-001"] });
|
||||
|
||||
const updated = await store.updateTask(task.id, { title: "New title" });
|
||||
expect(updated.dependencies).toEqual(["HAI-001"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -282,7 +282,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
|
||||
async updateTask(
|
||||
id: string,
|
||||
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null; blockedBy?: string | null },
|
||||
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null; dependencies?: string[] },
|
||||
): Promise<Task> {
|
||||
return this.withTaskLock(id, async () => {
|
||||
const dir = this.taskDir(id);
|
||||
@@ -291,6 +291,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
if (updates.title !== undefined) task.title = updates.title;
|
||||
if (updates.description !== undefined) task.description = updates.description;
|
||||
if (updates.worktree !== undefined) task.worktree = updates.worktree;
|
||||
if (updates.dependencies !== undefined) task.dependencies = updates.dependencies;
|
||||
if (updates.status === null) {
|
||||
task.status = undefined;
|
||||
} else if (updates.status !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user