From db652116d6b5d22f758837b4f803af6b000e5b70 Mon Sep 17 00:00:00 2001 From: "DESKTOP-RTLN3BA\\$punk" Date: Mon, 9 Feb 2026 16:49:11 -0800 Subject: [PATCH] chore: linting --- .../app/agents/new_chat/chat_deepagent.py | 2 +- .../app/agents/new_chat/tools/registry.py | 4 +- .../agents/new_chat/tools/shared_memory.py | 4 +- .../app/routes/documents_routes.py | 2 +- .../app/routes/new_chat_routes.py | 1 - surfsense_backend/app/schemas/__init__.py | 2 +- .../app/tasks/chat/stream_new_chat.py | 1 + surfsense_backend/app/utils/content_utils.py | 11 +- .../(manage)/components/DocumentTypeIcon.tsx | 4 +- .../components/DocumentsTableShell.tsx | 2 +- .../[search_space_id]/more-pages/page.tsx | 2 +- surfsense_web/components/UserDropdown.tsx | 2 +- .../components/assistant-ui/thread.tsx | 20 +- .../components/homepage/hero-section.tsx | 22 +- .../components/json-metadata-viewer.tsx | 2 +- .../layout/providers/LayoutDataProvider.tsx | 3 +- .../layout/ui/icon-rail/SearchSpaceAvatar.tsx | 2 +- .../layout/ui/shell/LayoutShell.tsx | 18 +- .../ui/sidebar/AllPrivateChatsSidebar.tsx | 417 +++++++++--------- .../ui/sidebar/AllSharedChatsSidebar.tsx | 417 +++++++++--------- .../layout/ui/sidebar/InboxSidebar.tsx | 2 +- .../components/layout/ui/sidebar/Sidebar.tsx | 2 +- .../ui/sidebar/SidebarSlideOutPanel.tsx | 6 +- .../layout/ui/sidebar/SidebarUserProfile.tsx | 2 +- .../public-chat/public-chat-view.tsx | 2 +- .../settings/image-model-manager.tsx | 2 +- .../lib/apis/documents-api.service.ts | 7 +- .../lib/apis/image-gen-config-api.service.ts | 6 +- 28 files changed, 491 insertions(+), 476 deletions(-) diff --git a/surfsense_backend/app/agents/new_chat/chat_deepagent.py b/surfsense_backend/app/agents/new_chat/chat_deepagent.py index 97fe33f0c..d58a0fadb 100644 --- a/surfsense_backend/app/agents/new_chat/chat_deepagent.py +++ b/surfsense_backend/app/agents/new_chat/chat_deepagent.py @@ -228,7 +228,7 @@ async def create_surfsense_deep_agent( import logging logging.warning(f"Failed to discover available connectors/document types: {e}") - + # Build dependencies dict for the tools registry visibility = thread_visibility or ChatVisibility.PRIVATE dependencies = { diff --git a/surfsense_backend/app/agents/new_chat/tools/registry.py b/surfsense_backend/app/agents/new_chat/tools/registry.py index 30201e8df..8092a6104 100644 --- a/surfsense_backend/app/agents/new_chat/tools/registry.py +++ b/surfsense_backend/app/agents/new_chat/tools/registry.py @@ -43,6 +43,8 @@ from typing import Any from langchain_core.tools import BaseTool +from app.db import ChatVisibility + from .display_image import create_display_image_tool from .generate_image import create_generate_image_tool from .knowledge_base import create_search_knowledge_base_tool @@ -57,8 +59,6 @@ from .shared_memory import ( ) from .user_memory import create_recall_memory_tool, create_save_memory_tool -from app.db import ChatVisibility - # ============================================================================= # Tool Definition # ============================================================================= diff --git a/surfsense_backend/app/agents/new_chat/tools/shared_memory.py b/surfsense_backend/app/agents/new_chat/tools/shared_memory.py index aa4a738ce..8cd4148ba 100644 --- a/surfsense_backend/app/agents/new_chat/tools/shared_memory.py +++ b/surfsense_backend/app/agents/new_chat/tools/shared_memory.py @@ -126,7 +126,9 @@ async def recall_shared_memory( } for m in rows ] - created_by_ids = list({m["created_by_id"] for m in memory_list if m["created_by_id"]}) + created_by_ids = list( + {m["created_by_id"] for m in memory_list if m["created_by_id"]} + ) created_by_map: dict[str, str] = {} if created_by_ids: uuids = [UUID(uid) for uid in created_by_ids] diff --git a/surfsense_backend/app/routes/documents_routes.py b/surfsense_backend/app/routes/documents_routes.py index 52989d27f..c8aeac0c9 100644 --- a/surfsense_backend/app/routes/documents_routes.py +++ b/surfsense_backend/app/routes/documents_routes.py @@ -18,9 +18,9 @@ from app.db import ( ) from app.schemas import ( DocumentRead, + DocumentsCreate, DocumentStatusBatchResponse, DocumentStatusItemRead, - DocumentsCreate, DocumentStatusSchema, DocumentTitleRead, DocumentTitleSearchResponse, diff --git a/surfsense_backend/app/routes/new_chat_routes.py b/surfsense_backend/app/routes/new_chat_routes.py index bfb5e109d..ecb1c2a6f 100644 --- a/surfsense_backend/app/routes/new_chat_routes.py +++ b/surfsense_backend/app/routes/new_chat_routes.py @@ -1326,4 +1326,3 @@ async def regenerate_response( status_code=500, detail=f"An unexpected error occurred during regeneration: {e!s}", ) from None - diff --git a/surfsense_backend/app/schemas/__init__.py b/surfsense_backend/app/schemas/__init__.py index 7c363e41f..b015cf715 100644 --- a/surfsense_backend/app/schemas/__init__.py +++ b/surfsense_backend/app/schemas/__init__.py @@ -10,9 +10,9 @@ from .chunks import ChunkBase, ChunkCreate, ChunkRead, ChunkUpdate from .documents import ( DocumentBase, DocumentRead, + DocumentsCreate, DocumentStatusBatchResponse, DocumentStatusItemRead, - DocumentsCreate, DocumentStatusSchema, DocumentTitleRead, DocumentTitleSearchResponse, diff --git a/surfsense_backend/app/tasks/chat/stream_new_chat.py b/surfsense_backend/app/tasks/chat/stream_new_chat.py index a8560ecba..31e67c7ff 100644 --- a/surfsense_backend/app/tasks/chat/stream_new_chat.py +++ b/surfsense_backend/app/tasks/chat/stream_new_chat.py @@ -36,6 +36,7 @@ from app.services.connector_service import ConnectorService from app.services.new_streaming_service import VercelStreamingService from app.utils.content_utils import bootstrap_history_from_db + def format_mentioned_documents_as_context(documents: list[Document]) -> str: """ Format mentioned documents as context for the agent. diff --git a/surfsense_backend/app/utils/content_utils.py b/surfsense_backend/app/utils/content_utils.py index 9a417075d..536e63851 100644 --- a/surfsense_backend/app/utils/content_utils.py +++ b/surfsense_backend/app/utils/content_utils.py @@ -9,11 +9,16 @@ Message content in new_chat_messages can be stored in various formats: These utilities help extract and transform content for different use cases. """ +from typing import TYPE_CHECKING + from langchain_core.messages import AIMessage, HumanMessage from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload +if TYPE_CHECKING: + from app.db import ChatVisibility + def extract_text_content(content: str | dict | list) -> str: """Extract plain text content from various message formats.""" @@ -39,7 +44,7 @@ def extract_text_content(content: str | dict | list) -> str: async def bootstrap_history_from_db( session: AsyncSession, thread_id: int, - thread_visibility: "ChatVisibility | None" = None, + thread_visibility: ChatVisibility | None = None, ) -> list[HumanMessage | AIMessage]: """ Load message history from database and convert to LangChain format. @@ -80,8 +85,8 @@ async def bootstrap_history_from_db( if msg.role == "user": if is_shared: author_name = ( - (msg.author.display_name if msg.author else None) or "A team member" - ) + msg.author.display_name if msg.author else None + ) or "A team member" text_content = f"**[{author_name}]:** {text_content}" langchain_messages.append(HumanMessage(content=text_content)) elif msg.role == "assistant": diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon.tsx index 1a3e343ac..dfd2c6d85 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon.tsx @@ -1,9 +1,9 @@ "use client"; import type React from "react"; -import { useRef, useState, useEffect } from "react"; -import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; +import { useEffect, useRef, useState } from "react"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; +import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; export function getDocumentTypeIcon(type: string, className?: string): React.ReactNode { return getConnectorIcon(type, className); diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx index f7c8663e5..02c359be9 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx @@ -17,7 +17,7 @@ import { } from "lucide-react"; import { motion } from "motion/react"; import { useTranslations } from "next-intl"; -import React, { useRef, useState, useEffect, useCallback } from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup"; import { JsonMetadataViewer } from "@/components/json-metadata-viewer"; import { MarkdownViewer } from "@/components/markdown-viewer"; diff --git a/surfsense_web/app/dashboard/[search_space_id]/more-pages/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/more-pages/page.tsx index f9dbf64ef..446e209a2 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/more-pages/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/more-pages/page.tsx @@ -8,7 +8,6 @@ import Link from "next/link"; import { useEffect } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; -import { Spinner } from "@/components/ui/spinner"; import { Card, CardContent } from "@/components/ui/card"; import { Dialog, @@ -20,6 +19,7 @@ import { } from "@/components/ui/dialog"; import { Separator } from "@/components/ui/separator"; import { Skeleton } from "@/components/ui/skeleton"; +import { Spinner } from "@/components/ui/spinner"; import type { IncentiveTaskInfo } from "@/contracts/types/incentive-tasks.types"; import { incentiveTasksApiService } from "@/lib/apis/incentive-tasks-api.service"; import { diff --git a/surfsense_web/components/UserDropdown.tsx b/surfsense_web/components/UserDropdown.tsx index 39896825e..5b398ae0b 100644 --- a/surfsense_web/components/UserDropdown.tsx +++ b/surfsense_web/components/UserDropdown.tsx @@ -5,7 +5,6 @@ import { useRouter } from "next/navigation"; import { useState } from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; -import { Spinner } from "@/components/ui/spinner"; import { DropdownMenu, DropdownMenuContent, @@ -15,6 +14,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Spinner } from "@/components/ui/spinner"; import { logout } from "@/lib/auth-utils"; import { cleanupElectric } from "@/lib/electric/client"; import { resetUser, trackLogout } from "@/lib/posthog/events"; diff --git a/surfsense_web/components/assistant-ui/thread.tsx b/surfsense_web/components/assistant-ui/thread.tsx index bc9755dfd..c8f00d02e 100644 --- a/surfsense_web/components/assistant-ui/thread.tsx +++ b/surfsense_web/components/assistant-ui/thread.tsx @@ -246,7 +246,9 @@ const Composer: FC = () => { const [mentionedDocuments, setMentionedDocuments] = useAtom(mentionedDocumentsAtom); const [showDocumentPopover, setShowDocumentPopover] = useState(false); const [mentionQuery, setMentionQuery] = useState(""); - const [uploadedMentionDocs, setUploadedMentionDocs] = useState>({}); + const [uploadedMentionDocs, setUploadedMentionDocs] = useState< + Record + >({}); const [isUploadingDocs, setIsUploadingDocs] = useState(false); const editorRef = useRef(null); const editorContainerRef = useRef(null); @@ -755,11 +757,7 @@ const ComposerAction: FC = ({ {blockingUploadedMentionsCount > 0 && (
- {hasFailedUploadedMentions ? ( - - ) : ( - - )} + {hasFailedUploadedMentions ? : } {hasFailedUploadedMentions ? "Remove or retry failed uploads" @@ -788,11 +786,11 @@ const ComposerAction: FC = ({ ? "Waiting for uploaded files to finish indexing" : isUploadingDocs ? "Uploading documents..." - : !hasModelConfigured - ? "Please select a model from the header to start chatting" - : isComposerEmpty - ? "Enter a message to send" - : "Send message" + : !hasModelConfigured + ? "Please select a model from the header to start chatting" + : isComposerEmpty + ? "Enter a message to send" + : "Send message" } side="bottom" type="submit" diff --git a/surfsense_web/components/homepage/hero-section.tsx b/surfsense_web/components/homepage/hero-section.tsx index a8f3ad47e..ef9a529c3 100644 --- a/surfsense_web/components/homepage/hero-section.tsx +++ b/surfsense_web/components/homepage/hero-section.tsx @@ -86,19 +86,19 @@ export function HeroSection() {

- {isNotebookLMVariant ? ( -
-
- NotebookLM with Superpowers + {isNotebookLMVariant ? ( +
+
+ NotebookLM with Superpowers +
-
- ) : ( -
-
- NotebookLM for Teams + ) : ( +
+
+ NotebookLM for Teams +
-
- )} + )}

{/* // TODO:aCTUAL DESCRITION */} diff --git a/surfsense_web/components/json-metadata-viewer.tsx b/surfsense_web/components/json-metadata-viewer.tsx index 0438abfa0..cc87a75c5 100644 --- a/surfsense_web/components/json-metadata-viewer.tsx +++ b/surfsense_web/components/json-metadata-viewer.tsx @@ -2,7 +2,6 @@ import { FileJson } from "lucide-react"; import React from "react"; import { defaultStyles, JsonView } from "react-json-view-lite"; import { Button } from "@/components/ui/button"; -import { Spinner } from "@/components/ui/spinner"; import { Dialog, DialogContent, @@ -10,6 +9,7 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; +import { Spinner } from "@/components/ui/spinner"; import "react-json-view-lite/dist/index.css"; interface JsonMetadataViewerProps { diff --git a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx index e40fe28ad..ed96b84ca 100644 --- a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx +++ b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx @@ -25,14 +25,15 @@ import { Input } from "@/components/ui/input"; import { isPageLimitExceededMetadata } from "@/contracts/types/inbox.types"; import { useInbox } from "@/hooks/use-inbox"; import { searchSpacesApiService } from "@/lib/apis/search-spaces-api.service"; -import { deleteThread, fetchThreads, updateThread } from "@/lib/chat/thread-persistence"; import { logout } from "@/lib/auth-utils"; +import { deleteThread, fetchThreads, updateThread } from "@/lib/chat/thread-persistence"; import { cleanupElectric } from "@/lib/electric/client"; import { resetUser, trackLogout } from "@/lib/posthog/events"; import { cacheKeys } from "@/lib/query-client/cache-keys"; import type { ChatItem, NavItem, SearchSpace } from "../types/layout.types"; import { CreateSearchSpaceDialog } from "../ui/dialogs"; import { LayoutShell } from "../ui/shell"; + interface LayoutDataProviderProps { searchSpaceId: string; children: React.ReactNode; diff --git a/surfsense_web/components/layout/ui/icon-rail/SearchSpaceAvatar.tsx b/surfsense_web/components/layout/ui/icon-rail/SearchSpaceAvatar.tsx index 1686f3a46..134c109dd 100644 --- a/surfsense_web/components/layout/ui/icon-rail/SearchSpaceAvatar.tsx +++ b/surfsense_web/components/layout/ui/icon-rail/SearchSpaceAvatar.tsx @@ -1,8 +1,8 @@ "use client"; import { Settings, Trash2, Users } from "lucide-react"; -import { useCallback, useRef, useState } from "react"; import { useTranslations } from "next-intl"; +import { useCallback, useRef, useState } from "react"; import { ContextMenu, ContextMenuContent, diff --git a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx index e3d608b82..2d5a3bba5 100644 --- a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx +++ b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx @@ -84,8 +84,16 @@ interface LayoutShellProps { inbox?: InboxProps; isLoadingChats?: boolean; // All chats panel props - allSharedChatsPanel?: { open: boolean; onOpenChange: (open: boolean) => void; searchSpaceId: string }; - allPrivateChatsPanel?: { open: boolean; onOpenChange: (open: boolean) => void; searchSpaceId: string }; + allSharedChatsPanel?: { + open: boolean; + onOpenChange: (open: boolean) => void; + searchSpaceId: string; + }; + allPrivateChatsPanel?: { + open: boolean; + onOpenChange: (open: boolean) => void; + searchSpaceId: string; + }; } export function LayoutShell({ @@ -129,7 +137,11 @@ export function LayoutShell({ const isMobile = useIsMobile(); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const { isCollapsed, setIsCollapsed, toggleCollapsed } = useSidebarState(defaultCollapsed); - const { sidebarWidth, handleMouseDown: onResizeMouseDown, isDragging: isResizing } = useSidebarResize(); + const { + sidebarWidth, + handleMouseDown: onResizeMouseDown, + isDragging: isResizing, + } = useSidebarResize(); // Memoize context value to prevent unnecessary re-renders const sidebarContextValue = useMemo( diff --git a/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx index c78adfef1..3dd77ea1d 100644 --- a/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx @@ -204,217 +204,214 @@ export function AllPrivateChatsSidebar({ ariaLabel={t("chats") || "Private Chats"} >
-
- -

{t("chats") || "Private Chats"}

-
- -
- - setSearchQuery(e.target.value)} - className="pl-9 pr-8 h-9" - /> - {searchQuery && ( - - )} -
-
- - {!isSearchMode && ( - setShowArchived(value === "archived")} - className="shrink-0 mx-4" - > - - - - - Active - - {activeCount} - - - - - - - Archived - - {archivedCount} - - - - - - )} - -
- {isLoading ? ( -
- {[75, 90, 55, 80, 65, 85].map((titleWidth, i) => ( -
- - -
- ))} -
- ) : error ? ( -
- {t("error_loading_chats") || "Error loading chats"} -
- ) : threads.length > 0 ? ( -
- {threads.map((thread) => { - const isDeleting = deletingThreadId === thread.id; - const isArchiving = archivingThreadId === thread.id; - const isBusy = isDeleting || isArchiving; - const isActive = currentChatId === thread.id; - - return ( -
- {isMobile ? ( - - ) : ( - - - - - -

- {t("updated") || "Updated"}:{" "} - {format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")} -

-
-
- )} - - setOpenDropdownId(isOpen ? thread.id : null)} - > - - - - - handleToggleArchive(thread.id, thread.archived)} - disabled={isArchiving} - > - {thread.archived ? ( - <> - - {t("unarchive") || "Restore"} - - ) : ( - <> - - {t("archive") || "Archive"} - - )} - - - handleDeleteThread(thread.id)} - className="text-destructive focus:text-destructive" - > - - {t("delete") || "Delete"} - - - -
- ); - })} -
- ) : isSearchMode ? ( -
- -

- {t("no_chats_found") || "No chats found"} -

-

- {t("try_different_search") || "Try a different search term"} -

-
- ) : ( -
- -

- {showArchived - ? t("no_archived_chats") || "No archived chats" - : t("no_chats") || "No private chats"} -

- {!showArchived && ( -

- {t("start_new_chat_hint") || "Start a new chat from the chat page"} -

- )} -
- )} +
+ +

{t("chats") || "Private Chats"}

+ +
+ + setSearchQuery(e.target.value)} + className="pl-9 pr-8 h-9" + /> + {searchQuery && ( + + )} +
+
+ + {!isSearchMode && ( + setShowArchived(value === "archived")} + className="shrink-0 mx-4" + > + + + + + Active + + {activeCount} + + + + + + + Archived + + {archivedCount} + + + + + + )} + +
+ {isLoading ? ( +
+ {[75, 90, 55, 80, 65, 85].map((titleWidth, i) => ( +
+ + +
+ ))} +
+ ) : error ? ( +
+ {t("error_loading_chats") || "Error loading chats"} +
+ ) : threads.length > 0 ? ( +
+ {threads.map((thread) => { + const isDeleting = deletingThreadId === thread.id; + const isArchiving = archivingThreadId === thread.id; + const isBusy = isDeleting || isArchiving; + const isActive = currentChatId === thread.id; + + return ( +
+ {isMobile ? ( + + ) : ( + + + + + +

+ {t("updated") || "Updated"}:{" "} + {format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")} +

+
+
+ )} + + setOpenDropdownId(isOpen ? thread.id : null)} + > + + + + + handleToggleArchive(thread.id, thread.archived)} + disabled={isArchiving} + > + {thread.archived ? ( + <> + + {t("unarchive") || "Restore"} + + ) : ( + <> + + {t("archive") || "Archive"} + + )} + + + handleDeleteThread(thread.id)} + className="text-destructive focus:text-destructive" + > + + {t("delete") || "Delete"} + + + +
+ ); + })} +
+ ) : isSearchMode ? ( +
+ +

+ {t("no_chats_found") || "No chats found"} +

+

+ {t("try_different_search") || "Try a different search term"} +

+
+ ) : ( +
+ +

+ {showArchived + ? t("no_archived_chats") || "No archived chats" + : t("no_chats") || "No private chats"} +

+ {!showArchived && ( +

+ {t("start_new_chat_hint") || "Start a new chat from the chat page"} +

+ )} +
+ )} +
); } diff --git a/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx index ed22b819d..fae9fb05e 100644 --- a/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx @@ -204,217 +204,214 @@ export function AllSharedChatsSidebar({ ariaLabel={t("shared_chats") || "Shared Chats"} >
-
- -

{t("shared_chats") || "Shared Chats"}

-
- -
- - setSearchQuery(e.target.value)} - className="pl-9 pr-8 h-9" - /> - {searchQuery && ( - - )} -
-
- - {!isSearchMode && ( - setShowArchived(value === "archived")} - className="shrink-0 mx-4" - > - - - - - Active - - {activeCount} - - - - - - - Archived - - {archivedCount} - - - - - - )} - -
- {isLoading ? ( -
- {[75, 90, 55, 80, 65, 85].map((titleWidth, i) => ( -
- - -
- ))} -
- ) : error ? ( -
- {t("error_loading_chats") || "Error loading chats"} -
- ) : threads.length > 0 ? ( -
- {threads.map((thread) => { - const isDeleting = deletingThreadId === thread.id; - const isArchiving = archivingThreadId === thread.id; - const isBusy = isDeleting || isArchiving; - const isActive = currentChatId === thread.id; - - return ( -
- {isMobile ? ( - - ) : ( - - - - - -

- {t("updated") || "Updated"}:{" "} - {format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")} -

-
-
- )} - - setOpenDropdownId(isOpen ? thread.id : null)} - > - - - - - handleToggleArchive(thread.id, thread.archived)} - disabled={isArchiving} - > - {thread.archived ? ( - <> - - {t("unarchive") || "Restore"} - - ) : ( - <> - - {t("archive") || "Archive"} - - )} - - - handleDeleteThread(thread.id)} - className="text-destructive focus:text-destructive" - > - - {t("delete") || "Delete"} - - - -
- ); - })} -
- ) : isSearchMode ? ( -
- -

- {t("no_chats_found") || "No chats found"} -

-

- {t("try_different_search") || "Try a different search term"} -

-
- ) : ( -
- -

- {showArchived - ? t("no_archived_chats") || "No archived chats" - : t("no_shared_chats") || "No shared chats"} -

- {!showArchived && ( -

- Share a chat to collaborate with your team -

- )} -
- )} +
+ +

{t("shared_chats") || "Shared Chats"}

+ +
+ + setSearchQuery(e.target.value)} + className="pl-9 pr-8 h-9" + /> + {searchQuery && ( + + )} +
+
+ + {!isSearchMode && ( + setShowArchived(value === "archived")} + className="shrink-0 mx-4" + > + + + + + Active + + {activeCount} + + + + + + + Archived + + {archivedCount} + + + + + + )} + +
+ {isLoading ? ( +
+ {[75, 90, 55, 80, 65, 85].map((titleWidth, i) => ( +
+ + +
+ ))} +
+ ) : error ? ( +
+ {t("error_loading_chats") || "Error loading chats"} +
+ ) : threads.length > 0 ? ( +
+ {threads.map((thread) => { + const isDeleting = deletingThreadId === thread.id; + const isArchiving = archivingThreadId === thread.id; + const isBusy = isDeleting || isArchiving; + const isActive = currentChatId === thread.id; + + return ( +
+ {isMobile ? ( + + ) : ( + + + + + +

+ {t("updated") || "Updated"}:{" "} + {format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")} +

+
+
+ )} + + setOpenDropdownId(isOpen ? thread.id : null)} + > + + + + + handleToggleArchive(thread.id, thread.archived)} + disabled={isArchiving} + > + {thread.archived ? ( + <> + + {t("unarchive") || "Restore"} + + ) : ( + <> + + {t("archive") || "Archive"} + + )} + + + handleDeleteThread(thread.id)} + className="text-destructive focus:text-destructive" + > + + {t("delete") || "Delete"} + + + +
+ ); + })} +
+ ) : isSearchMode ? ( +
+ +

+ {t("no_chats_found") || "No chats found"} +

+

+ {t("try_different_search") || "Try a different search term"} +

+
+ ) : ( +
+ +

+ {showArchived + ? t("no_archived_chats") || "No archived chats" + : t("no_shared_chats") || "No shared chats"} +

+ {!showArchived && ( +

+ Share a chat to collaborate with your team +

+ )} +
+ )} +
); } diff --git a/surfsense_web/components/layout/ui/sidebar/InboxSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/InboxSidebar.tsx index c459141d6..ce64adae9 100644 --- a/surfsense_web/components/layout/ui/sidebar/InboxSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/InboxSidebar.tsx @@ -52,8 +52,8 @@ import { isNewMentionMetadata, isPageLimitExceededMetadata, } from "@/contracts/types/inbox.types"; -import type { InboxItem } from "@/hooks/use-inbox"; import { useDebouncedValue } from "@/hooks/use-debounced-value"; +import type { InboxItem } from "@/hooks/use-inbox"; import { useMediaQuery } from "@/hooks/use-media-query"; import { notificationsApiService } from "@/lib/apis/notifications-api.service"; import { cacheKeys } from "@/lib/query-client/cache-keys"; diff --git a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx index f5589ba1c..aee98a290 100644 --- a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx @@ -6,8 +6,8 @@ import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; -import type { ChatItem, NavItem, PageUsage, SearchSpace, User } from "../../types/layout.types"; import { SIDEBAR_MIN_WIDTH } from "../../hooks/useSidebarResize"; +import type { ChatItem, NavItem, PageUsage, SearchSpace, User } from "../../types/layout.types"; import { ChatListItem } from "./ChatListItem"; import { NavSection } from "./NavSection"; import { PageUsageDisplay } from "./PageUsageDisplay"; diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx index 9d74c01f1..beb1c81c0 100644 --- a/surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx +++ b/surfsense_web/components/layout/ui/sidebar/SidebarSlideOutPanel.tsx @@ -1,8 +1,8 @@ "use client"; import { AnimatePresence, motion } from "motion/react"; -import { cn } from "@/lib/utils"; import { useMediaQuery } from "@/hooks/use-media-query"; +import { cn } from "@/lib/utils"; import { useSidebarContextSafe } from "../../hooks"; const SIDEBAR_COLLAPSED_WIDTH = 60; @@ -40,8 +40,8 @@ export function SidebarSlideOutPanel({ {open && ( <> - {/* Click-away layer - covers the full container including the sidebar */} -