From 163df8fda7a878e9d27864552c9fda14ce38b36d Mon Sep 17 00:00:00 2001
From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com>
Date: Wed, 31 Dec 2025 17:21:26 +0530
Subject: [PATCH] feat: Enhance connector management UI with improved loading
states, add document count display for connectors, and implement indexing
progress indicators for better user feedback.
---
surfsense_backend/app/routes/logs_routes.py | 4 +
.../documents/(manage)/page.tsx | 24 ++--
.../[search_space_id]/logs/(manage)/page.tsx | 35 ++++-
.../assistant-ui/connector-popup.tsx | 37 +++---
.../components/connector-card.tsx | 71 +++++++++-
.../tabs/active-connectors-tab.tsx | 16 +--
.../tabs/all-connectors-tab.tsx | 124 +++++++++++-------
.../utils/connector-document-mapping.ts | 64 +++++++++
surfsense_web/contracts/types/log.types.ts | 1 +
surfsense_web/tailwind.config.js | 6 +
10 files changed, 287 insertions(+), 95 deletions(-)
create mode 100644 surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts
diff --git a/surfsense_backend/app/routes/logs_routes.py b/surfsense_backend/app/routes/logs_routes.py
index e7e00280e..b82e02077 100644
--- a/surfsense_backend/app/routes/logs_routes.py
+++ b/surfsense_backend/app/routes/logs_routes.py
@@ -322,6 +322,9 @@ async def get_logs_summary(
document_id = (
log.log_metadata.get("document_id") if log.log_metadata else None
)
+ connector_id = (
+ log.log_metadata.get("connector_id") if log.log_metadata else None
+ )
summary["active_tasks"].append(
{
"id": log.id,
@@ -330,6 +333,7 @@ async def get_logs_summary(
"started_at": log.created_at,
"source": log.source,
"document_id": document_id,
+ "connector_id": connector_id,
}
)
diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx
index c61fcfe78..019f5796a 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx
@@ -125,14 +125,22 @@ export default function DocumentsTable() {
setColumnVisibility((prev) => ({ ...prev, [id]: checked }));
};
+ const [isRefreshing, setIsRefreshing] = useState(false);
+
const refreshCurrentView = useCallback(async () => {
- if (debouncedSearch.trim()) {
- await refetchSearch();
- } else {
- await refetchDocuments();
+ if (isRefreshing) return;
+ setIsRefreshing(true);
+ try {
+ if (debouncedSearch.trim()) {
+ await refetchSearch();
+ } else {
+ await refetchDocuments();
+ }
+ toast.success(t("refresh_success") || "Documents refreshed");
+ } finally {
+ setIsRefreshing(false);
}
- toast.success(t("refresh_success") || "Documents refreshed");
- }, [debouncedSearch, refetchSearch, refetchDocuments, t]);
+ }, [debouncedSearch, refetchSearch, refetchDocuments, t, isRefreshing]);
// Set up smart polling for active tasks - only polls when tasks are in progress
const { summary } = useLogsSummary(searchSpaceId, 24, {
@@ -230,8 +238,8 @@ export default function DocumentsTable() {
{t("title")}
{t("subtitle")}
-