import { post } from "./api.js"; import { errorText, h, replace, showAlert } from "./dom.js"; import { currentSession, focusTask, state } from "./state.js"; import { taskStyle } from "./taskcolor.js"; const starting = new Set(); export function todoLink(projectId: string, title: string, children: Node[]): HTMLElement { return h("span", { class: "todo-link", data: { project: projectId, title } }, h("span", { class: "todo-title" }, ...children), " ", h("span", { class: "todo-action" })); } export function fillTodoLinks(root: HTMLElement, model: string): void { for (const el of root.querySelectorAll(".todo-link")) { fill(el, model); } } function fill(el: HTMLElement, model: string): void { const projectId = el.dataset["project"]!; const title = el.dataset["title"]!; const action = el.querySelector(".todo-action")!; const titleEl = el.querySelector(".todo-title")!; const task = (state.tasks.get(projectId) ?? []).find((t) => t.status === "active" && t.todo_item === title); if (task) { const sess = currentSession(task.id); el.setAttribute("style", taskStyle(task.id)); titleEl.classList.add("task-name"); replace( action, h( "a", { class: "todo-task", href: `#/task/${task.id}`, onclick: (e: MouseEvent) => { e.preventDefault(); focusTask(task.id); }, }, h("span", { class: `dot ${sess?.state ?? "none"}`, title: sess?.state ?? "no session" }), sess?.state ?? "no agent", ), ); return; } el.removeAttribute("style"); titleEl.classList.remove("task-name"); const key = `${projectId}\n${title}`; const busy = starting.has(key); const start = async (discuss: boolean) => { starting.add(key); fill(el, model); try { await post("/api/projects/{projectId}/todo/tasks", { path: { projectId }, body: { title, model, discuss } }); } catch (err) { void showAlert(errorText(err)); } starting.delete(key); fill(el, model); }; const startButton = h("button", { disabled: busy, title: "Start a task that gets straight to work" }, busy ? "Starting…" : "Start"); startButton.onclick = () => void start(false); const discussButton = h("button", { disabled: busy, title: "Start a task that talks it through with you before changing anything" }, "Discuss"); discussButton.onclick = () => void start(true); replace(action, startButton, " ", discussButton); }