Soham Waghmare commited on
Commit
fcd8ded
·
1 Parent(s): 08ee506

fix: delete chat

Browse files
frontend/src/components/ChatInterface.tsx CHANGED
@@ -46,6 +46,19 @@ const ChatInterface = () => {
46
  citations: false,
47
  });
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  // Initialize socket once
50
  useEffect(() => {
51
  const socket = initializeSocket();
@@ -224,12 +237,13 @@ const ChatInterface = () => {
224
  };
225
 
226
  const handleNewConversation = () => {
 
227
  setCurrentConversationId(null);
228
- setChatState({
229
  messages: [],
230
  isLoading: false,
231
  error: null,
232
- });
233
  };
234
 
235
  const handleSelectConversation = (id: string) => {
@@ -249,12 +263,22 @@ const ChatInterface = () => {
249
  active: conv.id === id,
250
  }))
251
  );
252
- userInputRef.current?.focus();
253
  };
254
 
255
- const sidebar = <ConversationList conversations={conversations} onNewConversation={handleNewConversation} onSelectConversation={handleSelectConversation} />;
 
 
 
 
 
 
 
 
 
 
 
 
256
 
257
- const userInputRef = useRef<HTMLTextAreaElement>();
258
  const mainContent = (
259
  <div className="flex flex-col w-full h-full relative" tabIndex={-1}>
260
  <ChatHistory messages={chatState.messages} isLoading={chatState.isLoading} />
 
46
  citations: false,
47
  });
48
 
49
+ const userInputRef = useRef<HTMLTextAreaElement>(null);
50
+
51
+ // Add this effect for focus management
52
+ useEffect(() => {
53
+ const focusInput = () => {
54
+ setTimeout(() => {
55
+ userInputRef.current?.focus();
56
+ }, 100);
57
+ };
58
+
59
+ focusInput();
60
+ }, [currentConversationId]);
61
+
62
  // Initialize socket once
63
  useEffect(() => {
64
  const socket = initializeSocket();
 
237
  };
238
 
239
  const handleNewConversation = () => {
240
+ userInputRef.current?.focus();
241
  setCurrentConversationId(null);
242
+ setChatState((prev) => ({
243
  messages: [],
244
  isLoading: false,
245
  error: null,
246
+ }));
247
  };
248
 
249
  const handleSelectConversation = (id: string) => {
 
263
  active: conv.id === id,
264
  }))
265
  );
 
266
  };
267
 
268
+ const handleDeleteConversation = (id: string) => {
269
+ setConversations((prev) => prev.filter((conv) => conv.id !== id));
270
+ if (currentConversationId === id) {
271
+ handleNewConversation();
272
+ }
273
+ };
274
+
275
+ const handleDeleteAllConversations = () => {
276
+ setConversations([]);
277
+ handleNewConversation();
278
+ };
279
+
280
+ const sidebar = <ConversationList conversations={conversations} onNewConversation={handleNewConversation} onSelectConversation={handleSelectConversation} onDeleteConversation={handleDeleteConversation} onDeleteAllConversations={handleDeleteAllConversations} />;
281
 
 
282
  const mainContent = (
283
  <div className="flex flex-col w-full h-full relative" tabIndex={-1}>
284
  <ChatHistory messages={chatState.messages} isLoading={chatState.isLoading} />
frontend/src/components/Message.tsx CHANGED
@@ -32,11 +32,7 @@ const MarkdownComponents: Record<string, React.ComponentType<any>> = {
32
  thead: ({ children }) => <thead className="bg-muted/50">{children}</thead>,
33
  };
34
 
35
- interface MessageProps {
36
- message: MessageType;
37
- }
38
-
39
- const Message: React.FC<MessageProps> = ({ message }) => {
40
  const isUser = message.role === "user";
41
  const isProgress = message.content.includes("%)") && message.role === "assistant";
42
 
 
32
  thead: ({ children }) => <thead className="bg-muted/50">{children}</thead>,
33
  };
34
 
35
+ const Message = ({ message }: { message: MessageType }) => {
 
 
 
 
36
  const isUser = message.role === "user";
37
  const isProgress = message.content.includes("%)") && message.role === "assistant";
38
 
frontend/src/components/ui/ChatLayout.tsx CHANGED
@@ -7,6 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
7
  import { LayoutGrid, MessageCircle, Settings } from "lucide-react";
8
  import React from "react";
9
  import { ThemeToggle } from "./ThemeToggle";
 
10
 
11
  interface ChatLayoutProps {
12
  sidebar: React.ReactNode;
@@ -18,7 +19,9 @@ const ChatLayout: React.FC<ChatLayoutProps> = ({ sidebar, mainContent, settingsP
18
  return (
19
  <div className="h-screen flex flex-col">
20
  <header className="border-b-2 h-14 flex items-center px-6">
21
- <h1 className="text-xl font-semibold">KnowledgeNet: Deep Research</h1>
 
 
22
  <div className="flex-1" />
23
  <ThemeToggle />
24
  <Sheet>
 
7
  import { LayoutGrid, MessageCircle, Settings } from "lucide-react";
8
  import React from "react";
9
  import { ThemeToggle } from "./ThemeToggle";
10
+ import Link from "next/link";
11
 
12
  interface ChatLayoutProps {
13
  sidebar: React.ReactNode;
 
19
  return (
20
  <div className="h-screen flex flex-col">
21
  <header className="border-b-2 h-14 flex items-center px-6">
22
+ <Link href={"/"}>
23
+ <h1 className="text-xl font-semibold">KnowledgeNet: Deep Research</h1>
24
+ </Link>
25
  <div className="flex-1" />
26
  <ThemeToggle />
27
  <Sheet>
frontend/src/components/ui/ConversationList.tsx CHANGED
@@ -1,33 +1,26 @@
1
  "use client";
2
  import { Button } from "@/components/ui/button";
3
- import { MessageSquare, PlusCircle } from "lucide-react";
 
4
  import React from "react";
5
 
6
- interface Conversation {
7
- id: string;
8
- title: string;
9
- lastUpdated: string;
10
- active?: boolean;
11
- }
12
-
13
- interface ConversationListProps {
14
- conversations: Conversation[];
15
- onNewConversation: () => void;
16
- onSelectConversation: (id: string) => void;
17
- }
18
-
19
- const ConversationList: React.FC<ConversationListProps> = ({ conversations, onNewConversation, onSelectConversation }) => {
20
  const handleSelectConversation = (id: string) => {
21
  onSelectConversation(id);
22
  };
23
 
24
  return (
25
  <div className="flex flex-col h-full py-2">
26
- <div className="px-4 py-2">
27
- <Button onClick={onNewConversation} className="w-full justify-start" variant="outline">
28
  <PlusCircle className="mr-2 h-4 w-4" />
29
  New Chat
30
  </Button>
 
 
 
 
 
31
  </div>
32
 
33
  <div className="px-2 py-2">
@@ -37,10 +30,22 @@ const ConversationList: React.FC<ConversationListProps> = ({ conversations, onNe
37
  <p className="text-sm text-muted-foreground px-2">No conversations yet</p>
38
  ) : (
39
  conversations.map((conversation) => (
40
- <Button key={conversation.id} variant={conversation.active ? "secondary" : "ghost"} className={`w-full justify-start text-left truncate ${conversation.active ? "bg-accent" : ""}`} onClick={() => handleSelectConversation(conversation.id)}>
41
- <MessageSquare className="mr-2 h-4 w-4 shrink-0" />
42
- <span className="truncate">{conversation.title}</span>
43
- </Button>
 
 
 
 
 
 
 
 
 
 
 
 
44
  ))
45
  )}
46
  </div>
 
1
  "use client";
2
  import { Button } from "@/components/ui/button";
3
+ import { ConversationListProps } from "@/lib/types";
4
+ import { MessageSquare, PlusCircle, Trash2, XCircle } from "lucide-react";
5
  import React from "react";
6
 
7
+ const ConversationList: React.FC<ConversationListProps> = ({ conversations, onNewConversation, onSelectConversation, onDeleteConversation, onDeleteAllConversations }) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  const handleSelectConversation = (id: string) => {
9
  onSelectConversation(id);
10
  };
11
 
12
  return (
13
  <div className="flex flex-col h-full py-2">
14
+ <div className="px-4 py-2 flex gap-2">
15
+ <Button onClick={onNewConversation} className="flex-1 justify-start" variant="outline">
16
  <PlusCircle className="mr-2 h-4 w-4" />
17
  New Chat
18
  </Button>
19
+ {conversations.length > 0 && (
20
+ <Button onClick={onDeleteAllConversations} variant="destructive" size="icon">
21
+ <Trash2 className="h-4 w-4" />
22
+ </Button>
23
+ )}
24
  </div>
25
 
26
  <div className="px-2 py-2">
 
30
  <p className="text-sm text-muted-foreground px-2">No conversations yet</p>
31
  ) : (
32
  conversations.map((conversation) => (
33
+ <div key={conversation.id} className="flex items-center gap-1 px-1">
34
+ <Button variant={conversation.active ? "secondary" : "ghost"} className={`flex-1 pr-0.5 justify-start text-left truncate ${conversation.active ? "bg-accent" : ""} group`} onClick={() => handleSelectConversation(conversation.id)}>
35
+ <MessageSquare className="mr-2 h-4 w-4 shrink-0" />
36
+ <span className="truncate">{conversation.title}</span>
37
+ <Button
38
+ variant="ghost"
39
+ size="icon"
40
+ className="h-8 w-8 ml-auto hidden group-hover:flex hover:bg-destructive"
41
+ onClick={(e) => {
42
+ e.stopPropagation();
43
+ onDeleteConversation(conversation.id);
44
+ }}>
45
+ <XCircle className="h-4 w-4" />
46
+ </Button>
47
+ </Button>
48
+ </div>
49
  ))
50
  )}
51
  </div>
frontend/src/lib/types.ts CHANGED
@@ -58,3 +58,11 @@ export interface ResearchResults {
58
  research_tree: ResearchNode;
59
  metadata: ResearchMetadata;
60
  }
 
 
 
 
 
 
 
 
 
58
  research_tree: ResearchNode;
59
  metadata: ResearchMetadata;
60
  }
61
+
62
+ export interface ConversationListProps {
63
+ conversations: Conversation[];
64
+ onNewConversation: () => void;
65
+ onSelectConversation: (id: string) => void;
66
+ onDeleteConversation: (id: string) => void;
67
+ onDeleteAllConversations: () => void;
68
+ }