From ea6fd447c108b58f31d522b4ccb5c8facb213625 Mon Sep 17 00:00:00 2001 From: shiyu Date: Sat, 3 Oct 2026 08:14:42 +0800 Subject: [PATCH] fix: keep vector database settings usable after connection failures --- .../components/VectorDbSettingsTab.tsx | 212 +++++++++--------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/web/src/pages/SystemSettingsPage/components/VectorDbSettingsTab.tsx b/web/src/pages/SystemSettingsPage/components/VectorDbSettingsTab.tsx index 798c64e..e19b7c1 100644 --- a/web/src/pages/SystemSettingsPage/components/VectorDbSettingsTab.tsx +++ b/web/src/pages/SystemSettingsPage/components/VectorDbSettingsTab.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { Form, Button, Card, Space, Spin, Empty, Alert, Select, Input, Modal, message } from 'antd'; import { vectorDBApi, type VectorDBStats, type VectorDBProviderMeta, type VectorDBCurrentConfig } from '../../../api/vectorDB'; import { useI18n } from '../../../i18n'; @@ -55,19 +55,26 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro const [vectorConfigSaving, setVectorConfigSaving] = useState(false); const [vectorMetaError, setVectorMetaError] = useState(null); const [selectedProviderType, setSelectedProviderType] = useState(null); + const initialLoadStarted = useRef(false); + const statsRequestId = useRef(0); const fetchVectorStats = useCallback(async () => { + const requestId = ++statsRequestId.current; setVectorStatsLoading(true); setVectorStatsError(null); try { const data = await vectorDBApi.getStats(); - setVectorStats(data); + if (requestId === statsRequestId.current) { + setVectorStats(data); + } } catch (e: any) { - const msg = e?.message || t('Load failed'); - setVectorStatsError(msg); - message.error(msg); + if (requestId === statsRequestId.current) { + setVectorStatsError(e?.message || t('Load failed')); + } } finally { - setVectorStatsLoading(false); + if (requestId === statsRequestId.current) { + setVectorStatsLoading(false); + } } }, [t]); @@ -101,7 +108,6 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro } catch (e: any) { const msg = e?.message || t('Load failed'); setVectorMetaError(msg); - message.error(msg); } finally { setVectorConfigLoading(false); } @@ -127,8 +133,11 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro .map(([key, val]) => [key, String(val)]), ); const response = await vectorDBApi.updateConfig({ type: values.type, config: configPayload }); + // Ignore statistics from the previous provider if its request is still pending. + statsRequestId.current += 1; setVectorConfig(response.config); setVectorStats(response.stats); + setVectorStatsLoading(false); setVectorStatsError(null); setSelectedProviderType(response.config.type); const provider = vectorProviders.find((item) => item.type === response.config.type); @@ -163,26 +172,14 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro }, [fetchVectorMeta, fetchVectorStats, t]); useEffect(() => { - if (!isActive) { + if (!isActive || initialLoadStarted.current) { return; } - if (!vectorProviders.length && !vectorConfigLoading) { - fetchVectorMeta(); - } - if (!vectorStats && !vectorStatsLoading) { - fetchVectorStats(); - } - }, [ - isActive, - fetchVectorMeta, - fetchVectorStats, - vectorProviders.length, - vectorConfigLoading, - vectorStats, - vectorStatsLoading, - ]); + initialLoadStarted.current = true; + void fetchVectorMeta(); + void fetchVectorStats(); + }, [isActive, fetchVectorMeta, fetchVectorStats]); - const vectorSectionLoading = vectorStatsLoading || vectorConfigLoading; const selectedProvider = vectorProviders.find( (item) => item.type === selectedProviderType || (!selectedProviderType && item.enabled), ); @@ -197,15 +194,18 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro {t('Refresh')} - {vectorSectionLoading ? ( + {vectorMetaError ? ( + + ) : null} + {vectorStatsError ? ( + + ) : null} + {vectorStatsLoading ? (
) : ( <> - {vectorMetaError ? ( - - ) : null} {vectorStats ? (
@@ -271,87 +271,87 @@ export default function VectorDbSettingsTab({ isActive }: VectorDbSettingsTabPro {t('Estimated memory is calculated as vectors x dimension x 4 bytes (float32).')}
- ) : vectorStatsError ? ( -
{vectorStatsError}
- ) : ( + ) : !vectorStatsError ? ( - )} -
- - - )} - - ))} - {selectedProvider && !selectedProvider.enabled ? ( - - ) : null} - - - - - - - + ) : null} )} +
+ + + )} + + ))} + {selectedProvider && !selectedProvider.enabled ? ( + + ) : null} + + + + + + +