'use client' import { FileText } from 'lucide-react' import { cn } from '../../../lib/utils' import { DocumentEditor } from '../../../widgets' import { DocumentArtifact } from '../artifacts' import { ChatCanvasActions } from '../actions' import { useChatCanvas } from '../context' import { useState } from 'react' import { Button } from '../../../ui/button' interface DocumentArtifactViewerProps { className?: string children?: React.ReactNode } // Convert citation with node_id to citation number in markdown function processDocument(content: string, nodeIds: string[]) { if (nodeIds.length === 0) return content const citationRegex = /\[citation:([a-fA-F0-9\\-]+)\](?:\(javascript:void\(0\)\))?/g let processedContent = content.replace(citationRegex, (match, citationId) => { const nodeIndex = nodeIds.findIndex(nodeId => nodeId === citationId) if (nodeIndex !== -1) return ` \`${nodeIndex + 1}\` ` return match // return original citation if not found }) // MdxEditor does not support tags processedContent = processedContent.replace(//gi, ' ') return processedContent } export function DocumentArtifactViewer({ className, children, }: DocumentArtifactViewerProps) { const { displayedArtifact, updateArtifact } = useChatCanvas() const [updatedContent, setUpdatedContent] = useState() if (displayedArtifact?.type !== 'document') return null const documentArtifact = displayedArtifact as DocumentArtifact const { data: { content, title, type }, } = documentArtifact const transformedContent = processDocument( content, documentArtifact.data.sources?.map(source => source.id) ?? [] ) const handleDocumentChange = (markdown: string) => { setUpdatedContent(markdown) } const handleSaveChanges = () => { if (!updatedContent) return updateArtifact(documentArtifact, updatedContent) setUpdatedContent(undefined) } return ( {title} {type} {updatedContent && ( Save setUpdatedContent(undefined)} > Revert )} {children ?? ( )} ) }