Changed navigation to add files by regex

This commit is contained in:
Lucas Oliveira 2025-10-23 18:26:54 -03:00
parent 6065037c72
commit 54a1fc3247

View file

@ -22,6 +22,7 @@ import {
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { type EndpointType, useChat } from "@/contexts/chat-context"; import { type EndpointType, useChat } from "@/contexts/chat-context";
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context"; import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
import { FILES_REGEX } from "@/lib/constants";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useLoadingStore } from "@/stores/loadingStore"; import { useLoadingStore } from "@/stores/loadingStore";
import { DeleteSessionModal } from "./delete-session-modal"; import { DeleteSessionModal } from "./delete-session-modal";
@ -81,6 +82,7 @@ export function Navigation({
setCurrentConversationId, setCurrentConversationId,
startNewConversation, startNewConversation,
conversationDocs, conversationDocs,
conversationData,
addConversationDoc, addConversationDoc,
refreshConversations, refreshConversations,
placeholderConversation, placeholderConversation,
@ -110,7 +112,7 @@ export function Navigation({
) { ) {
// Filter out the deleted conversation and find the next one // Filter out the deleted conversation and find the next one
const remainingConversations = conversations.filter( const remainingConversations = conversations.filter(
conv => conv.response_id !== conversationToDelete.response_id (conv) => conv.response_id !== conversationToDelete.response_id,
); );
if (remainingConversations.length > 0) { if (remainingConversations.length > 0) {
@ -131,7 +133,7 @@ export function Navigation({
setDeleteModalOpen(false); setDeleteModalOpen(false);
setConversationToDelete(null); setConversationToDelete(null);
}, },
onError: error => { onError: (error) => {
toast.error(`Failed to delete conversation: ${error.message}`); toast.error(`Failed to delete conversation: ${error.message}`);
}, },
}); });
@ -163,7 +165,7 @@ export function Navigation({
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("fileUploadStart", { new CustomEvent("fileUploadStart", {
detail: { filename: file.name }, detail: { filename: file.name },
}) }),
); );
try { try {
@ -187,7 +189,7 @@ export function Navigation({
filename: file.name, filename: file.name,
error: "Failed to process document", error: "Failed to process document",
}, },
}) }),
); );
// Trigger loading end event // Trigger loading end event
@ -207,7 +209,7 @@ export function Navigation({
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("fileUploaded", { new CustomEvent("fileUploaded", {
detail: { file, result }, detail: { file, result },
}) }),
); );
// Trigger loading end event // Trigger loading end event
@ -221,7 +223,7 @@ export function Navigation({
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("fileUploadError", { new CustomEvent("fileUploadError", {
detail: { filename: file.name, error: "Failed to process document" }, detail: { filename: file.name, error: "Failed to process document" },
}) }),
); );
} }
}; };
@ -243,7 +245,7 @@ export function Navigation({
const handleDeleteConversation = ( const handleDeleteConversation = (
conversation: ChatConversation, conversation: ChatConversation,
event?: React.MouseEvent event?: React.MouseEvent,
) => { ) => {
if (event) { if (event) {
event.preventDefault(); event.preventDefault();
@ -255,7 +257,7 @@ export function Navigation({
const handleContextMenuAction = ( const handleContextMenuAction = (
action: string, action: string,
conversation: ChatConversation conversation: ChatConversation,
) => { ) => {
switch (action) { switch (action) {
case "delete": case "delete":
@ -329,11 +331,19 @@ export function Navigation({
setCurrentConversationId, setCurrentConversationId,
]); ]);
const newConversationFiles = conversationData?.messages
.filter(
(message) =>
message.role === "user" &&
(message.content.match(FILES_REGEX)?.[0] ?? null) !== null,
)
.map((message) => message.content.match(FILES_REGEX)?.[0] ?? null);
return ( return (
<div className="flex flex-col h-full bg-background"> <div className="flex flex-col h-full bg-background">
<div className="px-4 py-2 flex-shrink-0"> <div className="px-4 py-2 flex-shrink-0">
<div className="space-y-1"> <div className="space-y-1">
{routes.map(route => ( {routes.map((route) => (
<div key={route.href}> <div key={route.href}>
<Link <Link
href={route.href} href={route.href}
@ -341,7 +351,7 @@ export function Navigation({
"text-[13px] group flex p-3 w-full justify-start font-medium cursor-pointer hover:bg-accent hover:text-accent-foreground rounded-lg transition-all", "text-[13px] group flex p-3 w-full justify-start font-medium cursor-pointer hover:bg-accent hover:text-accent-foreground rounded-lg transition-all",
route.active route.active
? "bg-accent text-accent-foreground shadow-sm" ? "bg-accent text-accent-foreground shadow-sm"
: "text-foreground hover:text-accent-foreground" : "text-foreground hover:text-accent-foreground",
)} )}
> >
<div className="flex items-center flex-1"> <div className="flex items-center flex-1">
@ -350,7 +360,7 @@ export function Navigation({
"h-[18px] w-[18px] mr-2 shrink-0", "h-[18px] w-[18px] mr-2 shrink-0",
route.active route.active
? "text-muted-foreground" ? "text-muted-foreground"
: "text-muted-foreground group-hover:text-muted-foreground" : "text-muted-foreground group-hover:text-muted-foreground",
)} )}
/> />
{route.label} {route.label}
@ -428,7 +438,7 @@ export function Navigation({
No conversations yet No conversations yet
</div> </div>
) : ( ) : (
conversations.map(conversation => ( conversations.map((conversation) => (
<button <button
key={conversation.response_id} key={conversation.response_id}
type="button" type="button"
@ -466,10 +476,10 @@ export function Navigation({
title="More options" title="More options"
role="button" role="button"
tabIndex={0} tabIndex={0}
onClick={e => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
}} }}
onKeyDown={e => { onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") { if (e.key === "Enter" || e.key === " ") {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -483,14 +493,14 @@ export function Navigation({
side="bottom" side="bottom"
align="end" align="end"
className="w-48" className="w-48"
onClick={e => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<DropdownMenuItem <DropdownMenuItem
onClick={e => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
handleContextMenuAction( handleContextMenuAction(
"delete", "delete",
conversation conversation,
); );
}} }}
className="cursor-pointer text-destructive focus:text-destructive" className="cursor-pointer text-destructive focus:text-destructive"
@ -508,7 +518,7 @@ export function Navigation({
)} )}
</div> </div>
{/* Conversation Knowledge Section - appears right after last conversation */} {/* Conversation Knowledge Section - appears right after last conversation
<div className="flex-shrink-0 mt-4"> <div className="flex-shrink-0 mt-4">
<div className="flex items-center justify-between mb-3 mx-3"> <div className="flex items-center justify-between mb-3 mx-3">
<h3 className="text-xs font-medium text-muted-foreground"> <h3 className="text-xs font-medium text-muted-foreground">
@ -551,6 +561,28 @@ export function Navigation({
)) ))
)} )}
</div> </div>
</div> */}
<div className="flex-shrink-0 mt-4">
<div className="flex items-center justify-between mb-3 mx-3">
<h3 className="text-xs font-medium text-muted-foreground">
Files
</h3>
</div>
<div className="overflow-y-auto scrollbar-hide space-y-1">
{newConversationFiles?.length === 0 ? (
<div className="text-[13px] text-muted-foreground py-2 px-3">
No documents yet
</div>
) : (
newConversationFiles?.map((file) => (
<div key={`${file}`} className="flex-1 min-w-0 px-3">
<div className="text-mmd font-medium text-foreground truncate">
{file}
</div>
</div>
))
)}
</div>
</div> </div>
</div> </div>
</div> </div>