mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-13 17:52:38 +02:00
chat-messages: add timeline module with builder, grouping, items, and rendering.
This commit is contained in:
parent
9e451a5907
commit
48c4df822a
12 changed files with 879 additions and 0 deletions
|
|
@ -0,0 +1,68 @@
|
|||
"use client";
|
||||
|
||||
import type { FC } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ReasoningItem, ToolCallItem } from "./items";
|
||||
import type { ItemStatus, TimelineGroup, TimelineItem } from "./types";
|
||||
|
||||
function renderItem(item: TimelineItem) {
|
||||
if (item.kind === "reasoning") return <ReasoningItem item={item} />;
|
||||
return <ToolCallItem item={item} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single group row in the timeline tree: status dot + connector line in
|
||||
* the gutter, parent item content + indented children in the body.
|
||||
*
|
||||
* The connector line overshoots by ~15px to land on the next group's
|
||||
* dot center; the line passes BEHIND any indented children (whose
|
||||
* column has no dot of its own) for a clean tree look.
|
||||
*/
|
||||
export const TimelineGroupRow: FC<{
|
||||
group: TimelineGroup;
|
||||
parentStatus: ItemStatus;
|
||||
showParentLine: boolean;
|
||||
}> = ({ group, parentStatus, showParentLine }) => {
|
||||
const hasChildren = group.children.length > 0;
|
||||
|
||||
return (
|
||||
<div className="relative flex gap-3">
|
||||
<div className="relative flex flex-col items-center w-2 self-stretch">
|
||||
{showParentLine && (
|
||||
<div className="absolute left-1/2 top-[15px] -bottom-[15px] w-px -translate-x-1/2 bg-muted-foreground/30" />
|
||||
)}
|
||||
<div className="relative z-10 mt-[7px] flex shrink-0 items-center justify-center">
|
||||
{parentStatus === "running" ? (
|
||||
<span className="relative flex size-2">
|
||||
<span className="absolute inline-flex size-full animate-ping rounded-full bg-primary/60" />
|
||||
<span className="relative inline-flex size-2 rounded-full bg-primary" />
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
className={cn(
|
||||
"size-2 rounded-full",
|
||||
parentStatus === "error"
|
||||
? "bg-destructive"
|
||||
: parentStatus === "cancelled"
|
||||
? "bg-muted-foreground/40"
|
||||
: "bg-muted-foreground/30"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 min-w-0 pb-4">
|
||||
{renderItem(group.parent)}
|
||||
|
||||
{hasChildren && (
|
||||
<div className="mt-2 ml-3 space-y-2">
|
||||
{group.children.map((child) => (
|
||||
<div key={child.id}>{renderItem(child)}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue