- ChatSearchDialog: CommandDialog with shouldFilter=false for server-side FTS, term highlighting via React components - ChatMessageBookmark: ghost icon button with fill-current for bookmarked state, aria-label toggle - ChatBookmarkList: scrollable list with skeleton loading, empty state, navigation callbacks - ChatBranchSelector: horizontal branch picker bar with GitBranch icon, active branch highlight
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { GitBranch } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
import type { ChatConversation } from "@paperclipai/shared";
|
|
|
|
interface ChatBranchSelectorProps {
|
|
conversationId: string;
|
|
branches: ChatConversation[];
|
|
activeBranchId: string | null;
|
|
onSelectBranch: (id: string) => void;
|
|
}
|
|
|
|
function formatDate(dateStr: string): string {
|
|
return new Date(dateStr).toLocaleDateString(undefined, { month: "short", day: "numeric" });
|
|
}
|
|
|
|
export function ChatBranchSelector({
|
|
conversationId,
|
|
branches,
|
|
activeBranchId,
|
|
onSelectBranch,
|
|
}: ChatBranchSelectorProps) {
|
|
if (branches.length === 0) return null;
|
|
|
|
return (
|
|
<div className="flex items-center gap-1 px-2 py-1 border-b border-border overflow-x-auto">
|
|
<GitBranch className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
|
<span className="text-xs text-muted-foreground shrink-0 mr-1">Branch:</span>
|
|
|
|
{/* Original conversation */}
|
|
<button
|
|
type="button"
|
|
className={cn(
|
|
"shrink-0 rounded px-2 py-0.5 text-xs transition-colors",
|
|
activeBranchId === null || activeBranchId === conversationId
|
|
? "bg-accent text-accent-foreground"
|
|
: "hover:bg-accent/50 text-muted-foreground",
|
|
)}
|
|
onClick={() => onSelectBranch(conversationId)}
|
|
title="Original conversation"
|
|
>
|
|
Original
|
|
</button>
|
|
|
|
{branches.map((branch, index) => (
|
|
<button
|
|
key={branch.id}
|
|
type="button"
|
|
className={cn(
|
|
"shrink-0 rounded px-2 py-0.5 text-xs transition-colors",
|
|
activeBranchId === branch.id
|
|
? "bg-accent text-accent-foreground"
|
|
: "hover:bg-accent/50 text-muted-foreground",
|
|
)}
|
|
onClick={() => onSelectBranch(branch.id)}
|
|
title={`Created ${formatDate(branch.createdAt)}`}
|
|
>
|
|
{branch.title ?? `Branch ${index + 1}`}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|