mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 17:26:23 +02:00
refactor: update LayoutDataProvider and NavSection components to use DocumentsProcessingStatus for improved document processing status handling
This commit is contained in:
parent
0a1d0035e6
commit
2adf5750df
4 changed files with 122 additions and 34 deletions
|
|
@ -132,8 +132,8 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
|||
|
||||
const totalUnreadCount = commentsInbox.unreadCount + statusInbox.unreadCount;
|
||||
|
||||
// Whether any documents are currently being uploaded/indexed — drives sidebar spinner
|
||||
const isDocumentsProcessing = useDocumentsProcessing(numericSpaceId);
|
||||
// Document processing status — drives sidebar status indicator (spinner / check / error)
|
||||
const documentsProcessingStatus = useDocumentsProcessing(numericSpaceId);
|
||||
|
||||
// Track seen notification IDs to detect new page_limit_exceeded notifications
|
||||
const seenPageLimitNotifications = useRef<Set<number>>(new Set());
|
||||
|
|
@ -271,7 +271,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
|||
url: "#documents",
|
||||
icon: SquareLibrary,
|
||||
isActive: isDocumentsSidebarOpen,
|
||||
showSpinner: isDocumentsProcessing,
|
||||
statusIndicator: documentsProcessingStatus,
|
||||
},
|
||||
{
|
||||
title: "Announcements",
|
||||
|
|
@ -287,7 +287,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
|||
totalUnreadCount,
|
||||
isAnnouncementsSidebarOpen,
|
||||
announcementUnreadCount,
|
||||
isDocumentsProcessing,
|
||||
documentsProcessingStatus,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { LucideIcon } from "lucide-react";
|
||||
import type { DocumentsProcessingStatus } from "@/hooks/use-documents-processing";
|
||||
|
||||
export interface SearchSpace {
|
||||
id: number;
|
||||
|
|
@ -21,7 +22,7 @@ export interface NavItem {
|
|||
icon: LucideIcon;
|
||||
isActive?: boolean;
|
||||
badge?: string | number;
|
||||
showSpinner?: boolean;
|
||||
statusIndicator?: DocumentsProcessingStatus;
|
||||
}
|
||||
|
||||
export interface ChatItem {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { CheckCircle2, CircleAlert } from "lucide-react";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
@ -11,13 +12,55 @@ interface NavSectionProps {
|
|||
isCollapsed?: boolean;
|
||||
}
|
||||
|
||||
function StatusBadge({ status }: { status: NavItem["statusIndicator"] }) {
|
||||
if (status === "processing") {
|
||||
return (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center h-[14px] w-[14px] rounded-full bg-primary/15">
|
||||
<Spinner size="xs" className="text-primary" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (status === "success") {
|
||||
return (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center h-[14px] w-[14px] rounded-full bg-emerald-500/15 animate-in fade-in duration-300">
|
||||
<CheckCircle2 className="h-[10px] w-[10px] text-emerald-500" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (status === "error") {
|
||||
return (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center h-[14px] w-[14px] rounded-full bg-destructive/15 animate-in fade-in duration-300">
|
||||
<CircleAlert className="h-[10px] w-[10px] text-destructive" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function StatusIcon({ status, FallbackIcon, className }: {
|
||||
status: NavItem["statusIndicator"];
|
||||
FallbackIcon: NavItem["icon"];
|
||||
className?: string;
|
||||
}) {
|
||||
if (status === "processing") {
|
||||
return <Spinner size="sm" className={cn("shrink-0 text-primary", className)} />;
|
||||
}
|
||||
if (status === "success") {
|
||||
return <CheckCircle2 className={cn("shrink-0 text-emerald-500 animate-in fade-in duration-300", className)} />;
|
||||
}
|
||||
if (status === "error") {
|
||||
return <CircleAlert className={cn("shrink-0 text-destructive animate-in fade-in duration-300", className)} />;
|
||||
}
|
||||
return <FallbackIcon className={cn("shrink-0", className)} />;
|
||||
}
|
||||
|
||||
export function NavSection({ items, onItemClick, isCollapsed = false }: NavSectionProps) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-0.5 py-2", isCollapsed && "items-center")}>
|
||||
{items.map((item) => {
|
||||
const Icon = item.icon;
|
||||
const indicator = item.statusIndicator;
|
||||
|
||||
// Add data-joyride for onboarding tour
|
||||
const joyrideAttr =
|
||||
item.title === "Documents" || item.title.toLowerCase().includes("documents")
|
||||
? { "data-joyride": "documents-sidebar" }
|
||||
|
|
@ -40,10 +83,8 @@ export function NavSection({ items, onItemClick, isCollapsed = false }: NavSecti
|
|||
{...joyrideAttr}
|
||||
>
|
||||
<Icon className="h-4 w-4" />
|
||||
{item.showSpinner ? (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center h-[14px] w-[14px] rounded-full bg-primary/15">
|
||||
<Spinner size="xs" className="text-primary" />
|
||||
</span>
|
||||
{indicator && indicator !== "idle" ? (
|
||||
<StatusBadge status={indicator} />
|
||||
) : item.badge ? (
|
||||
<span className="absolute top-0.5 right-0.5 inline-flex items-center justify-center min-w-[14px] h-[14px] px-0.5 rounded-full bg-red-500 text-white text-[9px] font-medium">
|
||||
{item.badge}
|
||||
|
|
@ -72,11 +113,11 @@ export function NavSection({ items, onItemClick, isCollapsed = false }: NavSecti
|
|||
)}
|
||||
{...joyrideAttr}
|
||||
>
|
||||
{item.showSpinner ? (
|
||||
<Spinner size="sm" className="shrink-0 text-primary" />
|
||||
) : (
|
||||
<Icon className="h-4 w-4 shrink-0" />
|
||||
)}
|
||||
<StatusIcon
|
||||
status={indicator}
|
||||
FallbackIcon={Icon}
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
<span className="flex-1 truncate">{item.title}</span>
|
||||
{item.badge && (
|
||||
<span className="inline-flex items-center justify-center min-w-4 h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-medium">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue