diff --git a/surfsense_web/components/chat/ChatSources.tsx b/surfsense_web/components/chat/ChatSources.tsx index 8b39c28..863b0c2 100644 --- a/surfsense_web/components/chat/ChatSources.tsx +++ b/surfsense_web/components/chat/ChatSources.tsx @@ -1,19 +1,29 @@ "use client"; import { getAnnotationData, type Message } from "@llamaindex/chat-ui"; -import { IconBrandGithub } from "@tabler/icons-react"; -import { ExternalLink, FileText, Globe } from "lucide-react"; +import { + IconBrandDiscord, + IconBrandGithub, + IconBrandNotion, + IconBrandSlack, + IconBrandYoutube, +} from "@tabler/icons-react"; +import { + BookOpen, + Calendar, + CheckSquare, + ExternalLink, + FileText, + Globe, + Link2, + Mail, + Puzzle, +} from "lucide-react"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; +import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; interface Source { @@ -46,15 +56,77 @@ interface SourceNode { function getSourceIcon(type: string) { switch (type) { + // GitHub case "USER_SELECTED_GITHUB_CONNECTOR": case "GITHUB_CONNECTOR": return ; + + // Notion case "USER_SELECTED_NOTION_CONNECTOR": case "NOTION_CONNECTOR": - return ; + return ; + + // Slack + case "USER_SELECTED_SLACK_CONNECTOR": + case "SLACK_CONNECTOR": + return ; + + // Discord + case "USER_SELECTED_DISCORD_CONNECTOR": + case "DISCORD_CONNECTOR": + return ; + + // Google Calendar + case "USER_SELECTED_GOOGLE_CALENDAR_CONNECTOR": + case "GOOGLE_CALENDAR_CONNECTOR": + return ; + + // Google Gmail + case "USER_SELECTED_GOOGLE_GMAIL_CONNECTOR": + case "GOOGLE_GMAIL_CONNECTOR": + return ; + + // YouTube + case "USER_SELECTED_YOUTUBE_VIDEO": + case "YOUTUBE_VIDEO": + return ; + + // Linear + case "USER_SELECTED_LINEAR_CONNECTOR": + case "LINEAR_CONNECTOR": + return ; + + // Jira + case "USER_SELECTED_JIRA_CONNECTOR": + case "JIRA_CONNECTOR": + return ; + + // Confluence + case "USER_SELECTED_CONFLUENCE_CONNECTOR": + case "CONFLUENCE_CONNECTOR": + return ; + + // ClickUp + case "USER_SELECTED_CLICKUP_CONNECTOR": + case "CLICKUP_CONNECTOR": + return ; + + // Files case "USER_SELECTED_FILE": case "FILE": return ; + + // Extension + case "USER_SELECTED_EXTENSION": + case "EXTENSION": + return ; + + // Crawled URL + case "USER_SELECTED_CRAWLED_URL": + case "CRAWLED_URL": + return ; + + // Default for any other source type default: return ; } @@ -63,28 +135,34 @@ function getSourceIcon(type: string) { function SourceCard({ source }: { source: Source }) { const hasUrl = source.url && source.url.trim() !== ""; + // Clean up the description for better display + const cleanDescription = source.description + .replace(/## Metadata\n\n/g, "") + .replace(/\n+/g, " ") + .trim(); + return ( - - + + - + {source.title} {hasUrl && ( window.open(source.url, "_blank")} > - + )} - - - {source.description} + + + {cleanDescription} @@ -147,28 +225,33 @@ export default function ChatSourcesDisplay({ message }: { message: Message }) { const totalSources = sourceGroups.reduce((acc, group) => acc + group.sources.length, 0); return ( - - + + View Sources ({totalSources}) - - - - Sources - + + + + + Sources + + {totalSources} {totalSources === 1 ? "source" : "sources"} + + + - - + + {sourceGroups.map((group) => ( {getSourceIcon(group.type)} - {group.name} + {group.name} {group.sources.length} @@ -177,9 +260,13 @@ export default function ChatSourcesDisplay({ message }: { message: Message }) { {sourceGroups.map((group) => ( - - - + + + {group.sources.map((source) => ( ))} @@ -188,7 +275,7 @@ export default function ChatSourcesDisplay({ message }: { message: Message }) { ))} - - + + ); }