Let task agents create and manage subtasks
This commit is contained in:
+21
-3
@@ -2,7 +2,7 @@ import { get, post, type ByreEvent, type Project, type Schemas, type Task } from
|
||||
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";
|
||||
|
||||
type Todo = Schemas["Todo"];
|
||||
@@ -106,6 +106,21 @@ function projectBlock(project: Project, todo: Todo | string | undefined, startin
|
||||
);
|
||||
}
|
||||
|
||||
function nested(active: Task[]): { task: Task; depth: number }[] {
|
||||
const ids = new Set(active.map((t) => t.id));
|
||||
const out: { task: Task; depth: number }[] = [];
|
||||
const add = (task: Task, depth: number) => {
|
||||
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: Task[]): HTMLElement {
|
||||
if (active.length === 0) {
|
||||
return h("p", { class: "empty-row" }, "No active tasks.");
|
||||
@@ -113,12 +128,13 @@ function tasksBlock(active: Task[]): HTMLElement {
|
||||
return h(
|
||||
"ul",
|
||||
{ class: "task-list" },
|
||||
...active.map((task) => {
|
||||
...nested(active).map(({ task, depth }) => {
|
||||
const ts = taskState(task);
|
||||
const count = state.inbox.filter((item) => item.task_id === task.id).length;
|
||||
const classes = [task.id === state.selectedTaskId && "selected", task.parent_task_id !== undefined && "subtask"].filter(Boolean).join(" ");
|
||||
return h(
|
||||
"li",
|
||||
{ class: task.id === state.selectedTaskId ? "selected" : "", style: taskStyle(task.id) },
|
||||
{ class: classes, style: `${taskStyle(task.id)}; --depth: ${depth}` },
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
@@ -128,10 +144,12 @@ function tasksBlock(active: Task[]): HTMLElement {
|
||||
focusTask(task.id);
|
||||
},
|
||||
},
|
||||
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"),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user