mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-02 20:32:39 +02:00
feat: enhance indexing state management and inbox count formatting
- Improved indexing state management by refining the logic for handling notifications, ensuring accurate updates for in-progress, completed, and failed states. - Introduced a new utility function to format inbox counts, displaying numbers up to 999 and using "k+" for larger counts, enhancing user interface clarity. - Updated sidebar components to utilize the new inbox count formatting, improving the overall user experience.
This commit is contained in:
parent
c48ba36fa4
commit
6d14b49d3f
4 changed files with 75 additions and 44 deletions
|
|
@ -10,8 +10,9 @@ import { isConnectorIndexingMetadata } from "@/contracts/types/inbox.types";
|
|||
*
|
||||
* This provides a better UX than polling by:
|
||||
* 1. Setting indexing state immediately when user triggers indexing (optimistic)
|
||||
* 2. Clearing indexing state when Electric SQL detects last_indexed_at changed
|
||||
* 3. Clearing indexing state when a failed notification is detected
|
||||
* 2. Detecting in_progress notifications from Electric SQL to restore state after remounts
|
||||
* 3. Clearing indexing state when notifications become completed or failed
|
||||
* 4. Clearing indexing state when Electric SQL detects last_indexed_at changed
|
||||
*
|
||||
* The actual `last_indexed_at` value comes from Electric SQL/PGlite, not local state.
|
||||
*/
|
||||
|
|
@ -28,65 +29,73 @@ export function useIndexingConnectors(
|
|||
// Detect when last_indexed_at changes (indexing completed) via Electric SQL
|
||||
useEffect(() => {
|
||||
const previousValues = previousLastIndexedAtRef.current;
|
||||
const newIndexingIds = new Set(indexingConnectorIds);
|
||||
let hasChanges = false;
|
||||
|
||||
for (const connector of connectors) {
|
||||
const previousValue = previousValues.get(connector.id);
|
||||
const currentValue = connector.last_indexed_at;
|
||||
|
||||
// If last_indexed_at changed and connector was in indexing state, clear it
|
||||
// If last_indexed_at changed, clear it from indexing state
|
||||
if (
|
||||
previousValue !== undefined && // We've seen this connector before
|
||||
previousValue !== currentValue && // Value changed
|
||||
indexingConnectorIds.has(connector.id) // It was marked as indexing
|
||||
previousValue !== currentValue // Value changed
|
||||
) {
|
||||
newIndexingIds.delete(connector.id);
|
||||
hasChanges = true;
|
||||
// Use functional update to access current state
|
||||
setIndexingConnectorIds((prev) => {
|
||||
if (prev.has(connector.id)) {
|
||||
const next = new Set(prev);
|
||||
next.delete(connector.id);
|
||||
return next;
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
}
|
||||
|
||||
// Update previous value tracking
|
||||
previousValues.set(connector.id, currentValue);
|
||||
}
|
||||
}, [connectors]);
|
||||
|
||||
if (hasChanges) {
|
||||
setIndexingConnectorIds(newIndexingIds);
|
||||
}
|
||||
}, [connectors, indexingConnectorIds]);
|
||||
|
||||
// Detect failed notifications and stop indexing state
|
||||
// Detect notification status changes and update indexing state accordingly
|
||||
// This restores spinner state after component remounts and handles all status transitions
|
||||
useEffect(() => {
|
||||
if (!inboxItems || inboxItems.length === 0) return;
|
||||
|
||||
const newIndexingIds = new Set(indexingConnectorIds);
|
||||
let hasChanges = false;
|
||||
setIndexingConnectorIds((prev) => {
|
||||
const newIndexingIds = new Set(prev);
|
||||
let hasChanges = false;
|
||||
|
||||
for (const item of inboxItems) {
|
||||
// Only check connector_indexing notifications
|
||||
if (item.type !== "connector_indexing") continue;
|
||||
for (const item of inboxItems) {
|
||||
// Only check connector_indexing notifications
|
||||
if (item.type !== "connector_indexing") continue;
|
||||
|
||||
// Check if this notification indicates a failure
|
||||
const metadata = isConnectorIndexingMetadata(item.metadata)
|
||||
? item.metadata
|
||||
: null;
|
||||
if (!metadata) continue;
|
||||
const metadata = isConnectorIndexingMetadata(item.metadata)
|
||||
? item.metadata
|
||||
: null;
|
||||
if (!metadata) continue;
|
||||
|
||||
// Check if status is "failed" or if there's an error_message
|
||||
const isFailed =
|
||||
metadata.status === "failed" ||
|
||||
(metadata.error_message && metadata.error_message.trim().length > 0);
|
||||
|
||||
// If failed and connector is in indexing state, clear it
|
||||
if (isFailed && indexingConnectorIds.has(metadata.connector_id)) {
|
||||
newIndexingIds.delete(metadata.connector_id);
|
||||
hasChanges = true;
|
||||
// If status is "in_progress", add connector to indexing set
|
||||
if (metadata.status === "in_progress") {
|
||||
if (!newIndexingIds.has(metadata.connector_id)) {
|
||||
newIndexingIds.add(metadata.connector_id);
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
// If status is "completed" or "failed", remove connector from indexing set
|
||||
else if (
|
||||
metadata.status === "completed" ||
|
||||
metadata.status === "failed" ||
|
||||
(metadata.error_message && metadata.error_message.trim().length > 0)
|
||||
) {
|
||||
if (newIndexingIds.has(metadata.connector_id)) {
|
||||
newIndexingIds.delete(metadata.connector_id);
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChanges) {
|
||||
setIndexingConnectorIds(newIndexingIds);
|
||||
}
|
||||
}, [inboxItems, indexingConnectorIds]);
|
||||
return hasChanges ? newIndexingIds : prev;
|
||||
});
|
||||
}, [inboxItems]);
|
||||
|
||||
// Add a connector to the indexing set (called when indexing starts)
|
||||
const startIndexing = useCallback((connectorId: number) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue