resolve conflicts

This commit is contained in:
Manoj Aggarwal 2026-01-16 15:39:57 -08:00
commit 11b160cee9
85 changed files with 8411 additions and 4637 deletions

View file

@ -508,20 +508,23 @@ export const useConnectorDialog = () => {
// Handle submitting connect form
const handleSubmitConnectForm = useCallback(
async (formData: {
name: string;
connector_type: string;
config: Record<string, unknown>;
is_indexable: boolean;
last_indexed_at: null;
periodic_indexing_enabled: boolean;
indexing_frequency_minutes: number | null;
next_scheduled_at: null;
startDate?: Date;
endDate?: Date;
periodicEnabled?: boolean;
frequencyMinutes?: string;
}) => {
async (
formData: {
name: string;
connector_type: string;
config: Record<string, unknown>;
is_indexable: boolean;
last_indexed_at: null;
periodic_indexing_enabled: boolean;
indexing_frequency_minutes: number | null;
next_scheduled_at: null;
startDate?: Date;
endDate?: Date;
periodicEnabled?: boolean;
frequencyMinutes?: string;
},
onIndexingStart?: (connectorId: number) => void
) => {
if (!searchSpaceId || !connectingConnectorType) return;
// Prevent multiple submissions using ref for immediate check
@ -621,6 +624,11 @@ export const useConnectorDialog = () => {
});
}
// Notify caller that indexing is starting (for UI syncing state)
if (onIndexingStart) {
onIndexingStart(connector.id);
}
// Start indexing (backend will use defaults if dates are undefined)
const startDateStr = startDateForIndexing
? format(startDateForIndexing, "yyyy-MM-dd")

View file

@ -1,6 +1,6 @@
"use client";
import { useMemo } from "react";
import { useCallback, useMemo } from "react";
import {
type ConnectorStatusConfig,
connectorStatusConfig,
@ -14,34 +14,43 @@ export function useConnectorStatus() {
/**
* Get status configuration for a specific connector type
*/
const getConnectorStatus = (connectorType: string | undefined): ConnectorStatusConfig => {
if (!connectorType) {
return getDefaultConnectorStatus();
}
const getConnectorStatus = useCallback(
(connectorType: string | undefined): ConnectorStatusConfig => {
if (!connectorType) {
return getDefaultConnectorStatus();
}
return connectorStatusConfig.connectorStatuses[connectorType] || getDefaultConnectorStatus();
};
return connectorStatusConfig.connectorStatuses[connectorType] || getDefaultConnectorStatus();
},
[]
);
/**
* Check if a connector is enabled
*/
const isConnectorEnabled = (connectorType: string | undefined): boolean => {
return getConnectorStatus(connectorType).enabled;
};
const isConnectorEnabled = useCallback(
(connectorType: string | undefined): boolean => {
return getConnectorStatus(connectorType).enabled;
},
[getConnectorStatus]
);
/**
* Get status message for a connector
*/
const getConnectorStatusMessage = (connectorType: string | undefined): string | null => {
return getConnectorStatus(connectorType).statusMessage || null;
};
const getConnectorStatusMessage = useCallback(
(connectorType: string | undefined): string | null => {
return getConnectorStatus(connectorType).statusMessage || null;
},
[getConnectorStatus]
);
/**
* Check if warnings should be shown globally
*/
const shouldShowWarnings = (): boolean => {
const shouldShowWarnings = useCallback((): boolean => {
return connectorStatusConfig.globalSettings.showWarnings;
};
}, []);
return useMemo(
() => ({
@ -50,6 +59,6 @@ export function useConnectorStatus() {
getConnectorStatusMessage,
shouldShowWarnings,
}),
[]
[getConnectorStatus, isConnectorEnabled, getConnectorStatusMessage, shouldShowWarnings]
);
}

View file

@ -0,0 +1,81 @@
"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
/**
* Hook to track which connectors are currently indexing using local state.
*
* 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
*
* The actual `last_indexed_at` value comes from Electric SQL/PGlite, not local state.
*/
export function useIndexingConnectors(connectors: SearchSourceConnector[]) {
// Set of connector IDs that are currently indexing
const [indexingConnectorIds, setIndexingConnectorIds] = useState<Set<number>>(new Set());
// Track previous last_indexed_at values to detect changes
const previousLastIndexedAtRef = useRef<Map<number, string | null>>(new Map());
// 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 (
previousValue !== undefined && // We've seen this connector before
previousValue !== currentValue && // Value changed
indexingConnectorIds.has(connector.id) // It was marked as indexing
) {
newIndexingIds.delete(connector.id);
hasChanges = true;
}
// Update previous value tracking
previousValues.set(connector.id, currentValue);
}
if (hasChanges) {
setIndexingConnectorIds(newIndexingIds);
}
}, [connectors, indexingConnectorIds]);
// Add a connector to the indexing set (called when indexing starts)
const startIndexing = useCallback((connectorId: number) => {
setIndexingConnectorIds((prev) => {
const next = new Set(prev);
next.add(connectorId);
return next;
});
}, []);
// Remove a connector from the indexing set (called manually if needed)
const stopIndexing = useCallback((connectorId: number) => {
setIndexingConnectorIds((prev) => {
const next = new Set(prev);
next.delete(connectorId);
return next;
});
}, []);
// Check if a connector is currently indexing
const isIndexing = useCallback(
(connectorId: number) => indexingConnectorIds.has(connectorId),
[indexingConnectorIds]
);
return {
indexingConnectorIds,
startIndexing,
stopIndexing,
isIndexing,
};
}