Let task agents create and manage subtasks
This commit is contained in:
Vendored
+19
-4
@@ -2,7 +2,7 @@ import { get, post } from "./api.js";
|
||||
import { errorText, h, replace, showAlert } from "./dom.js";
|
||||
import { markdown } from "./markdown.js";
|
||||
import { models } from "./task.js";
|
||||
import { currentSession, focusedProject, focusTask, on, onEach, state, taskState } from "./state.js";
|
||||
import { currentSession, findTask, focusedProject, focusTask, on, onEach, state, taskState } from "./state.js";
|
||||
import { taskStyle } from "./taskcolor.js";
|
||||
const refreshKinds = new Set(["task.merged", "project.created"]);
|
||||
export function mountProject(root) {
|
||||
@@ -86,20 +86,35 @@ function projectBlock(project, todo, starting, start) {
|
||||
const active = (state.tasks.get(project.id) ?? []).filter((t) => t.status === "active");
|
||||
return h("section", { class: "project" }, h("h2", {}, project.name, " ", h("span", { class: "repo" }, project.default_branch)), h("h3", {}, "Tasks"), tasksBlock(active), h("h3", {}, "TODO"), ...todoBlock(project, todo, active, starting, start));
|
||||
}
|
||||
function nested(active) {
|
||||
const ids = new Set(active.map((t) => t.id));
|
||||
const out = [];
|
||||
const add = (task, depth) => {
|
||||
out.push({ task, depth });
|
||||
for (const child of active.filter((t) => t.parent_task_id === task.id).reverse()) {
|
||||
add(child, depth + 1);
|
||||
}
|
||||
};
|
||||
for (const task of active.filter((t) => t.parent_task_id === undefined || !ids.has(t.parent_task_id))) {
|
||||
add(task, 0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function tasksBlock(active) {
|
||||
if (active.length === 0) {
|
||||
return h("p", { class: "empty-row" }, "No active tasks.");
|
||||
}
|
||||
return h("ul", { class: "task-list" }, ...active.map((task) => {
|
||||
return h("ul", { class: "task-list" }, ...nested(active).map(({ task, depth }) => {
|
||||
const ts = taskState(task);
|
||||
const count = state.inbox.filter((item) => item.task_id === task.id).length;
|
||||
return h("li", { class: task.id === state.selectedTaskId ? "selected" : "", style: taskStyle(task.id) }, h("a", {
|
||||
const classes = [task.id === state.selectedTaskId && "selected", task.parent_task_id !== undefined && "subtask"].filter(Boolean).join(" ");
|
||||
return h("li", { class: classes, style: `${taskStyle(task.id)}; --depth: ${depth}` }, h("a", {
|
||||
href: `#/task/${task.id}`,
|
||||
onclick: (e) => {
|
||||
e.preventDefault();
|
||||
focusTask(task.id);
|
||||
},
|
||||
}, h("span", { class: `dot ${ts ?? "none"}`, title: ts ?? "no session" }), h("span", { class: "task-title task-name" }, task.title), count > 0 && h("span", { class: "badge", title: "inbox items" }, count), task.merge_queued_at !== undefined && h("span", { class: "task-state warn", title: "Waiting for the merge in progress in this project to finish" }, "merge held"), h("span", { class: "task-state" }, ts ?? "no agent")));
|
||||
}, task.parent_task_id !== undefined && h("span", { class: "subtask-mark", title: `Subtask of ${findTask(task.parent_task_id)?.title ?? task.parent_task_id}` }, "↳"), h("span", { class: `dot ${ts ?? "none"}`, title: ts ?? "no session" }), h("span", { class: "task-title task-name" }, task.title), count > 0 && h("span", { class: "badge", title: "inbox items" }, count), task.merge_queued_at !== undefined && h("span", { class: "task-state warn", title: "Waiting for the merge in progress in this project to finish" }, "merge held"), task.merging_into_parent && h("span", { class: "task-state warn", title: "Waiting for the parent task's agent to merge it" }, "merging into parent"), h("span", { class: "task-state" }, ts ?? "no agent")));
|
||||
}));
|
||||
}
|
||||
function todoBlock(project, todo, active, starting, start) {
|
||||
|
||||
Reference in New Issue
Block a user