2026-10-15 20:20:02 -07:00
import { post } from "./api.js" ;
import { errorText , h , replace , showAlert } from "./dom.js" ;
2026-10-17 08:10:55 -07:00
import { currentLead , currentSession , focusTask , state } from "./state.js" ;
2026-10-15 20:20:02 -07:00
import { taskStyle } from "./taskcolor.js" ;
2026-10-17 08:10:55 -07:00
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" }));
2026-10-15 20:20:02 -07:00
}
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" ];
2026-10-17 08:10:55 -07:00
const brief = el . dataset [ "brief" ];
2026-10-15 20:20:02 -07:00
const action = el . querySelector ( ".todo-action" );
const titleEl = el . querySelector ( ".todo-title" );
2026-10-17 08:10:55 -07:00
const task = ( state . tasks . get ( projectId ) ?? []). find (( t ) => t . status === "active" && ( brief === undefined ? t . todo_item === title : t . title === title ));
2026-10-15 20:20:02 -07:00
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 } ` ;
2026-10-17 08:10:55 -07:00
const label = busy . get ( key );
const run = async ( busyLabel , act ) => {
busy . set ( key , busyLabel );
2026-10-15 20:20:02 -07:00
fill ( el , model );
try {
2026-10-17 08:10:55 -07:00
await act ();
2026-10-15 20:20:02 -07:00
}
catch ( err ) {
void showAlert ( errorText ( err ));
}
2026-10-17 08:10:55 -07:00
busy . delete ( key );
2026-10-15 20:20:02 -07:00
fill ( el , model );
};
2026-10-17 08:10:55 -07:00
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 } });
});
2026-10-16 22:34:14 -07:00
replace ( action , startButton , discussButton );
2026-10-15 20:20:02 -07:00
}
//# sourceMappingURL=todolink.js.map