wu981526092's picture
🚀 Deploy AgentGraph: Complete agent monitoring and knowledge graph system
c2ea5ed
/**
* Context Document Card Component
*
* Displays individual context documents with preview and actions
*/
import React from "react";
import { Card, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Trash2, FileText, Edit } from "lucide-react";
import { ContextDocument } from "@/types/context";
import { shouldRenderAsMarkdown } from "@/lib/markdown-utils";
import ReactMarkdown from "react-markdown";
interface ContextDocumentCardProps {
document: ContextDocument;
onDelete: () => void;
onViewEdit: () => void;
}
export function ContextDocumentCard({
document,
onDelete,
onViewEdit,
}: ContextDocumentCardProps) {
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
});
};
const getPreviewContent = (content: string, maxLength: number = 150) => {
if (content.length <= maxLength) return content;
return content.substring(0, maxLength) + "...";
};
return (
<Card className="transition-all duration-200 hover:shadow-md">
<CardHeader className="pb-3">
<div className="space-y-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 flex-1 min-w-0">
<FileText className="h-5 w-5 text-primary" />
<CardTitle className="text-base truncate">
{document.title}
</CardTitle>
</div>
{/* Action buttons in top right */}
<div className="flex items-center gap-2">
<Button
variant="outline"
size="sm"
onClick={onViewEdit}
className="gap-1"
title="View and edit context document"
>
<Edit className="h-4 w-4" />
View/Edit
</Button>
<Button
variant="ghost"
size="sm"
onClick={onDelete}
className="h-8 w-8 p-0 text-muted-foreground hover:text-destructive"
title="Delete context document"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
<div className="flex flex-wrap gap-2 text-sm text-muted-foreground items-center">
<span>{formatDate(document.created_at)}</span>
{/* Document metadata */}
<Badge
variant="outline"
className="text-xs h-5 flex items-center gap-1"
>
<FileText className="h-3 w-3" />
Type: {document.document_type.replace(/_/g, " ")}
</Badge>
{/* Character count */}
<div className="text-xs text-muted-foreground">
{document.content.length.toLocaleString()} chars
</div>
</div>
{/* Content preview */}
<div className="text-sm text-muted-foreground bg-muted/30 rounded-md p-2 border-l-2 border-primary/20">
{shouldRenderAsMarkdown(document.content, document.file_name) ? (
<div className="prose prose-sm max-w-none [&>*]:my-1 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&>h1]:text-sm [&>h2]:text-sm [&>h3]:text-sm [&>h4]:text-sm [&>h5]:text-sm [&>h6]:text-sm [&>p]:text-xs [&>ul]:text-xs [&>ol]:text-xs [&>li]:text-xs [&>blockquote]:text-xs [&>code]:text-xs [&>pre]:text-xs">
<ReactMarkdown>
{getPreviewContent(document.content, 200)}
</ReactMarkdown>
</div>
) : (
<div className="whitespace-pre-wrap">
{getPreviewContent(document.content)}
</div>
)}
</div>
</div>
</CardHeader>
</Card>
);
}