import { post } from "./api.js"; import { errorText, h, replace, showAlert } from "./dom.js"; import { currentLead, currentSession, focusTask, state } from "./state.js"; import { taskStyle } from "./taskcolor.js"; const busy = new Map(); export function todoLink(projectId, title, children, brief) { const data = { project: projectId, title }; if (brief !== undefined) { data["brief"] = brief; } return h("span", { class: "todo-link", data }, h("span", { class: "todo-title" }, ...children), " ", h("span", { class: "todo-action" })); } export function fillTodoLinks(root, model) { for (const el of root.querySelectorAll(".todo-link")) { fill(el, model); } } function fill(el, model) { const projectId = el.dataset["project"]; const title = el.dataset["title"]; const brief = el.dataset["brief"]; const action = el.querySelector(".todo-action"); const titleEl = el.querySelector(".todo-title"); const task = (state.tasks.get(projectId) ?? []).find((t) => t.status === "active" && (brief === undefined ? t.todo_item === title : t.title === 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) => { 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 label = busy.get(key); const run = async (busyLabel, act) => { busy.set(key, busyLabel); fill(el, model); try { await act(); } catch (err) { void showAlert(errorText(err)); } busy.delete(key); fill(el, model); }; if (brief === undefined) { const start = (discuss) => run(discuss ? "discuss" : "start", () => post("/api/projects/{projectId}/todo/tasks", { path: { projectId }, body: { title, model, discuss } })); const startButton = h("button", { disabled: !!label, title: "Start a task that gets straight to work" }, label === "start" ? "starting…" : "start"); startButton.onclick = () => void start(false); const discussButton = h("button", { disabled: !!label, title: "Start a task that discusses it with you in chat before building anything" }, label === "discuss" ? "starting…" : "discuss"); discussButton.onclick = () => void start(true); replace(action, startButton, discussButton); return; } const startButton = h("button", { disabled: !!label, title: "Start a task with the lead's brief" }, label === "start" ? "starting…" : "start"); startButton.onclick = () => void run("start", () => post("/api/projects/{projectId}/tasks", { path: { projectId }, body: { title, prompt: brief, model } })); const discussButton = h("button", { disabled: !!label, title: "Ask your lead to talk it over in chat" }, label === "discuss" ? "sending…" : "discuss"); discussButton.onclick = () => void run("discuss", () => { const lead = currentLead(); const live = lead !== undefined && lead.state !== "completed"; return post("/api/me/lead/messages", { body: { text: `Let's discuss your suggestion "${title}" before starting it:\n\n${brief}`, model: live ? undefined : model } }); }); replace(action, startButton, discussButton); } //# sourceMappingURL=todolink.js.map