Skip to content

Conversation

@MODSetter
Copy link
Owner

@MODSetter MODSetter commented Oct 30, 2025

  • Replaced the use of search source connectors with document types for improved clarity and functionality.
  • Enhanced UI elements for document type selection, including better styling and loading states.
  • Updated selection logic to handle document types and their counts effectively.
  • Improved accessibility and user experience in the document and connector selection dialogs.

Description

Motivation and Context

FIX #

Screenshots

API Changes

  • This PR includes API changes

Change Type

  • Bug fix
  • New feature
  • Performance improvement
  • Refactoring
  • Documentation
  • Dependency/Build system
  • Breaking change
  • Other (specify):

Testing Performed

  • Tested locally
  • Manual/QA verification

Checklist

  • Follows project coding standards and conventions
  • Documentation updated as needed
  • Dependencies updated as needed
  • No lint/build errors or new warnings
  • All relevant tests are passing

High-level PR Summary

This PR refactors document and connector selection components by replacing search source connectors with document types, improving the clarity of the selection logic. A new useDocumentTypes hook fetches document type counts from the API, while the UI components in ChatInputGroup.tsx have been redesigned with enhanced styling, better loading states, empty states, and improved accessibility. The connector selector now displays document types with their respective counts in a cleaner, more intuitive grid layout with visual feedback for selected items.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 surfsense_web/hooks/use-document-types.ts
2 surfsense_web/components/chat/ChatInputGroup.tsx

Need help? Join our Discord

Analyze latest changes

Summary by CodeRabbit

  • New Features

    • Document-type selection interface with icons and display counts in the chat input area.
  • Improvements

    • Enhanced visual organization with dividers between selection controls.
    • Refined loading and empty state messaging.
    • Updated search scope controls with improved styling and responsive grid layout.

- Replaced the use of search source connectors with document types for improved clarity and functionality.
- Enhanced UI elements for document type selection, including better styling and loading states.
- Updated selection logic to handle document types and their counts effectively.
- Improved accessibility and user experience in the document and connector selection dialogs.
@vercel
Copy link

vercel bot commented Oct 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
surf-sense-frontend Ready Ready Preview Comment Oct 30, 2025 11:06pm

@coderabbitai
Copy link

coderabbitai bot commented Oct 30, 2025

Walkthrough

The pull request refactors the chat input component from a connector-based selection model to a document-type driven UI. A new useDocumentTypes hook fetches document type counts from the API, and the DocumentSelector and ConnectorSelector components now display document types with icons and counts instead of connectors.

Changes

Cohort / File(s) Summary
Chat Input Refactor
surfsense_web/components/chat/ChatInputGroup.tsx
Replaced connector-based selection with document-type driven UI. DocumentSelector now fetches documents via new useDocumentTypes flow. ConnectorSelector shows document-type icons and counts. Added getDisplayName helper for prettifying type names. Reworked Select All/Clear All and toggle actions to operate on documentTypes. Enhanced SearchModeSelector visuals with inline scope buttons. Added visual dividers and improved layout spacing between selector blocks.
Document Type Hook
surfsense_web/hooks/use-document-types.ts
New React hook that fetches document type counts from /api/v1/documents/type-counts/. Exports DocumentTypeCount interface with type and count fields. Returns documentTypes array, loading/loaded flags, error handling, and fetchDocumentTypes and refreshDocumentTypes functions. Supports optional searchSpaceId filter and lazy loading mode with refetch safeguards.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ChatInputGroup
    participant useDocumentTypes
    participant API as API:/api/v1/documents/type-counts/
    
    User->>ChatInputGroup: Mount/Initialize
    ChatInputGroup->>useDocumentTypes: Call useDocumentTypes(searchSpaceId)
    useDocumentTypes->>useDocumentTypes: Retrieve token from localStorage
    useDocumentTypes->>API: GET with optional search_space_id param
    API-->>useDocumentTypes: Return {type: count}
    useDocumentTypes->>useDocumentTypes: Convert to DocumentTypeCount[]
    useDocumentTypes-->>ChatInputGroup: Return documentTypes, isLoading, isLoaded, error
    ChatInputGroup->>ChatInputGroup: Render DocumentSelector with documentTypes
    User->>ChatInputGroup: Select/Toggle document types
    ChatInputGroup->>ChatInputGroup: Update selectedDocTypes state
    User->>ChatInputGroup: Trigger refresh
    ChatInputGroup->>useDocumentTypes: Call refreshDocumentTypes(spaceId)
    useDocumentTypes->>API: Re-fetch type counts
    API-->>useDocumentTypes: Updated counts
    useDocumentTypes-->>ChatInputGroup: Updated documentTypes
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • ChatInputGroup.tsx requires careful review of the new selection model and document-type driven logic, including state management changes and grid layout refactoring
  • use-document-types.ts is a straightforward new hook but involves API integration and lazy-loading logic that should be verified
  • Pay special attention to:
    • How selectedDocTypes state is initialized and updated across select/toggle/clear actions
    • Error handling and empty state rendering in DocumentSelector
    • Token retrieval and API error scenarios in the new hook
    • Lazy-loading safeguards to prevent duplicate fetches

Possibly related PRs

Poem

🐰 A document-type dance, so neat,
Icons and counts in grids we meet!
The hook hops data down from on high,
No more connectors—let types apply!
Selection's sleek, the UI's complete.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "refactor: update Document and Connector selection components" directly identifies the primary components being modified in this pull request. The changeset centers on refactoring the ChatInputGroup.tsx file's document and connector selection UI, which the title accurately captures. While the title uses the somewhat broad term "update," it is sufficiently specific and not vague—it clearly indicates that these selection components are undergoing changes. A teammate scanning the PR history would understand that the primary change involves modifications to the Document and Connector selection components, even if the title doesn't specify the architectural shift from connector-based to document-type driven logic.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MODSetter MODSetter merged commit 3435307 into main Oct 30, 2025
7 of 9 checks passed
Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by RecurseML

🔍 Review performed on a09309a..4302493

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (1)

surfsense_web/components/chat/ChatInputGroup.tsx

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a09309a and 4302493.

📒 Files selected for processing (2)
  • surfsense_web/components/chat/ChatInputGroup.tsx (6 hunks)
  • surfsense_web/hooks/use-document-types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.rules/require_unique_id_props.mdc)

**/*.{jsx,tsx}: When mapping arrays to React elements in JSX/TSX, each rendered element must include a unique key prop
Keys used for React list items should be stable, predictable, and unique among siblings

Files:

  • surfsense_web/components/chat/ChatInputGroup.tsx
🧬 Code graph analysis (1)
surfsense_web/components/chat/ChatInputGroup.tsx (2)
surfsense_web/hooks/use-document-types.ts (1)
  • useDocumentTypes (13-97)
surfsense_web/contracts/enums/connectorIcons.tsx (1)
  • getConnectorIcon (22-80)

Comment on lines +19 to +66
const fetchDocumentTypes = useCallback(
async (spaceId?: number) => {
if (isLoaded && lazy) return;

try {
setIsLoading(true);
setError(null);
const token = localStorage.getItem("surfsense_bearer_token");

if (!token) {
throw new Error("No authentication token found");
}

// Build URL with optional search_space_id query parameter
const url = new URL(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/type-counts/`
);
if (spaceId !== undefined) {
url.searchParams.append("search_space_id", spaceId.toString());
}

const response = await fetch(url.toString(), {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});

if (!response.ok) {
throw new Error(`Failed to fetch document types: ${response.statusText}`);
}

const data = await response.json();

// Convert the object to an array of DocumentTypeCount
const typeCounts: DocumentTypeCount[] = Object.entries(data).map(([type, count]) => ({
type,
count: count as number,
}));

setDocumentTypes(typeCounts);
setIsLoaded(true);

return typeCounts;
} catch (err) {
setError(err instanceof Error ? err : new Error("An unknown error occurred"));
console.error("Error fetching document types:", err);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't skip refetch when the search space changes.

With lazy=true, isLoaded stays true after the first fetch. When the user switches to a different search_space_id, we still call fetchDocumentTypes(newId), but the guard if (isLoaded && lazy) return; fires before we compare the IDs, so the hook keeps returning the stale counts for the previous space. Users opening the selector for a new space will never see the correct document types until a full reload. Please gate the early return on the same space (or reset isLoaded when the space changes). One way:

-	const fetchDocumentTypes = useCallback(
-		async (spaceId?: number) => {
-			if (isLoaded && lazy) return;
+	const [lastFetchedSpaceId, setLastFetchedSpaceId] = useState<number | undefined>(undefined);
+
+	const fetchDocumentTypes = useCallback(
+		async (spaceId?: number) => {
+			const resolvedSpaceId = spaceId ?? searchSpaceId;
+			if (isLoaded && lazy && resolvedSpaceId === lastFetchedSpaceId) return;
@@
-				if (spaceId !== undefined) {
-					url.searchParams.append("search_space_id", spaceId.toString());
+				if (resolvedSpaceId !== undefined) {
+					url.searchParams.append("search_space_id", resolvedSpaceId.toString());
@@
-				setDocumentTypes(typeCounts);
-				setIsLoaded(true);
+				setDocumentTypes(typeCounts);
+				setIsLoaded(true);
+				setLastFetchedSpaceId(resolvedSpaceId);
 			} catch (err) {
@@
-		},
-		[isLoaded, lazy]
+		},
+		[isLoaded, lazy, searchSpaceId, lastFetchedSpaceId]
 	);
@@
 	const refreshDocumentTypes = useCallback(
 		async (spaceId?: number) => {
 			setIsLoaded(false);
-			await fetchDocumentTypes(spaceId !== undefined ? spaceId : searchSpaceId);
+			setLastFetchedSpaceId(undefined);
+			await fetchDocumentTypes(spaceId !== undefined ? spaceId : searchSpaceId);
 		},
 		[fetchDocumentTypes, searchSpaceId]
 	);

This keeps the cached behavior for the same space but correctly refetches when the user changes spaces.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In surfsense_web/hooks/use-document-types.ts around lines 19–66, the
early-return guard `if (isLoaded && lazy) return;` prevents refetch when the
search_space_id changes; modify the logic to track the last fetched space and
only skip when the requested space matches the cached one: add a ref or state
(e.g., lastFetchedSpaceId) and change the guard to `if (isLoaded && lazy &&
lastFetchedSpaceId === spaceId) return;` and update lastFetchedSpaceId when a
successful fetch completes (or alternatively reset isLoaded/lastFetchedSpaceId
in a useEffect when spaceId changes) so switching spaces triggers a new fetch
while preserving lazy caching for the same space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants