feat: Enhance connector management UI with improved loading states, add document count display for connectors, and implement indexing progress indicators for better user feedback.

This commit is contained in:
Anish Sarkar 2025-12-31 17:21:26 +05:30
parent 3ac806dcdf
commit 163df8fda7
10 changed files with 287 additions and 95 deletions

View file

@ -1,9 +1,10 @@
"use client";
import { Loader2 } from "lucide-react";
import { FileText, Loader2 } from "lucide-react";
import { type FC } from "react";
import { Button } from "@/components/ui/button";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import type { LogActiveTask } from "@/contracts/types/log.types";
interface ConnectorCardProps {
id: string;
@ -12,10 +13,24 @@ interface ConnectorCardProps {
connectorType: string;
isConnected?: boolean;
isConnecting?: boolean;
documentCount?: number;
isIndexing?: boolean;
activeTask?: LogActiveTask;
onConnect?: () => void;
onManage?: () => void;
}
/**
* Extract a number from the active task message for display
* Looks for patterns like "45 indexed", "Processing 123", etc.
*/
function extractIndexedCount(message: string | undefined): number | null {
if (!message) return null;
// Try to find a number in the message
const match = message.match(/(\d+)/);
return match ? parseInt(match[1], 10) : null;
}
export const ConnectorCard: FC<ConnectorCardProps> = ({
id,
title,
@ -23,9 +38,53 @@ export const ConnectorCard: FC<ConnectorCardProps> = ({
connectorType,
isConnected = false,
isConnecting = false,
documentCount,
isIndexing = false,
activeTask,
onConnect,
onManage,
}) => {
// Extract count from active task message during indexing
const indexingCount = extractIndexedCount(activeTask?.message);
// Determine the status content to display
const getStatusContent = () => {
if (isIndexing) {
return (
<div className="flex items-center gap-2 w-full max-w-[200px]">
<span className="text-[11px] text-primary font-medium whitespace-nowrap">
{indexingCount !== null ? (
<>{indexingCount.toLocaleString()} indexed</>
) : (
"Syncing..."
)}
</span>
{/* Indeterminate progress bar with animation */}
<div className="relative flex-1 h-1 overflow-hidden rounded-full bg-primary/20">
<div className="absolute h-full bg-primary rounded-full animate-progress-indeterminate" />
</div>
</div>
);
}
if (isConnected) {
if (documentCount !== undefined && documentCount > 0) {
return (
<span className="inline-flex items-center gap-1.5">
<FileText className="size-3 flex-shrink-0" />
<span className="whitespace-nowrap">
{documentCount.toLocaleString()} document{documentCount !== 1 ? "s" : ""}
</span>
</span>
);
}
// Fallback for connected but no documents yet
return <span className="whitespace-nowrap">No documents indexed</span>;
}
return description;
};
return (
<div className="group relative flex items-center gap-4 p-4 rounded-xl text-left transition-all duration-200 w-full border border-border bg-slate-400/5 dark:bg-white/5 hover:bg-slate-400/10 dark:hover:bg-white/10">
<div className="flex h-12 w-12 items-center justify-center rounded-lg transition-colors flex-shrink-0 bg-slate-400/5 dark:bg-white/5 border border-slate-400/5 dark:border-white/5">
@ -35,19 +94,21 @@ export const ConnectorCard: FC<ConnectorCardProps> = ({
<div className="flex items-center gap-2">
<span className="text-[14px] font-semibold leading-tight">{title}</span>
</div>
<p className="text-[11px] text-muted-foreground truncate mt-1">
{isConnected ? "Connected" : description}
</p>
<div className="text-[11px] text-muted-foreground mt-1">
{getStatusContent()}
</div>
</div>
<Button
size="sm"
variant={isConnected ? "outline" : "default"}
className="h-8 text-[11px] px-3 rounded-lg flex-shrink-0 font-medium"
onClick={isConnected ? onManage : onConnect}
disabled={isConnecting}
disabled={isConnecting || isIndexing}
>
{isConnecting ? (
<Loader2 className="size-3 animate-spin" />
) : isIndexing ? (
"Syncing..."
) : isConnected ? (
"Manage"
) : (