Skip to content

Commit f6d2297

Browse files
committed
feat(ui): agent todolist component
1 parent 2d29e5b commit f6d2297

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

typescript/ui/src/core/components/ChatMessage/ChatMessage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
useMessage,
1313
} from "../../stores/HistoryStore/selectors.ts";
1414
import { MessageRole } from "@ragbits/api-client";
15+
import TodoList from "../TodoList.tsx";
1516

1617
type ChatMessageProps = {
1718
classNames?: {
@@ -100,6 +101,8 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>(
100101
{showMessageReferences && (
101102
<MessageReferences references={references} />
102103
)}
104+
{/* TODO: Add check for todos availability */}
105+
<TodoList />
103106
{showMessageActions && (
104107
<MessageActions
105108
content={content}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Checkbox, CircularProgress } from "@heroui/react";
2+
3+
interface Todo {
4+
content: string;
5+
status: "initial" | "in-progress" | "done";
6+
}
7+
8+
const DUMMY_TODOS: Record<string, Todo> = {
9+
"1": {
10+
content: "Todo item 1",
11+
status: "done",
12+
},
13+
"2": {
14+
content: "Todo item 2",
15+
status: "in-progress",
16+
},
17+
"3": {
18+
content: "Todo item 3",
19+
status: "initial",
20+
},
21+
"4": {
22+
content: "Todo item 4",
23+
status: "initial",
24+
},
25+
};
26+
27+
interface TodoListProps {
28+
// TODO: Remove optional, should be optional only during development
29+
todos?: Record<string, Todo>;
30+
}
31+
32+
export default function TodoList({ todos = DUMMY_TODOS }: TodoListProps) {
33+
return (
34+
<div className="space-y-2">
35+
{Object.entries(todos).map(([id, todo]) => {
36+
const inProgressIcon = (
37+
<CircularProgress
38+
size="sm"
39+
color="primary"
40+
aria-label="Task is in progress"
41+
className="m-0 p-0"
42+
classNames={{
43+
svg: "w-4 h-4",
44+
}}
45+
/>
46+
);
47+
return (
48+
<Checkbox
49+
key={id}
50+
isSelected={todo.status === "done"}
51+
disabled
52+
className="block"
53+
icon={
54+
todo.status === "in-progress" ? () => inProgressIcon : undefined
55+
}
56+
classNames={{
57+
hiddenInput: "cursor-default",
58+
wrapper: todo.status === "in-progress" && "before:border-none",
59+
base: "pointer-events-none hover:bg-transparent",
60+
label: [
61+
"transition-colors",
62+
todo.status === "done" && "line-through text-default-400",
63+
todo.status === "in-progress" && "text-primary italic",
64+
todo.status === "initial" && "text-default-900",
65+
]
66+
.filter(Boolean)
67+
.join(" "),
68+
}}
69+
>
70+
{todo.content}
71+
</Checkbox>
72+
);
73+
})}
74+
</div>
75+
);
76+
}

0 commit comments

Comments
 (0)