Skip to content

Commit 7a23d03

Browse files
committed
fix(ui): resolve state synchronization bug in settings popover
1 parent 643bc40 commit 7a23d03

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

webview-ui/src/components/chat/CodeIndexPopover.tsx

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -198,40 +198,44 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
198198
setIndexingStatus(externalIndexingStatus)
199199
}, [externalIndexingStatus])
200200

201-
// Initialize settings from global state
201+
// Initializes the settings from the global state when it changes
202202
useEffect(() => {
203203
if (codebaseIndexConfig) {
204+
const provider = codebaseIndexConfig.codebaseIndexEmbedderProvider || "openai"
205+
const modelId = codebaseIndexConfig.codebaseIndexEmbedderModelId || ""
206+
const modelProfile = codebaseIndexModels?.[provider]?.[modelId]
207+
204208
const settings = {
205209
codebaseIndexEnabled: codebaseIndexConfig.codebaseIndexEnabled ?? true,
206210
codebaseIndexQdrantUrl: codebaseIndexConfig.codebaseIndexQdrantUrl || "",
207-
codebaseIndexEmbedderProvider: codebaseIndexConfig.codebaseIndexEmbedderProvider || "openai",
211+
codebaseIndexEmbedderProvider: provider,
208212
codebaseIndexEmbedderBaseUrl: codebaseIndexConfig.codebaseIndexEmbedderBaseUrl || "",
209-
codebaseIndexEmbedderModelId: codebaseIndexConfig.codebaseIndexEmbedderModelId || "",
213+
codebaseIndexEmbedderModelId: modelId,
214+
// Determines the dimension exclusively from the global configuration and model profiles.
215+
// The local 'currentSettings' state is no longer read here.
210216
codebaseIndexEmbedderModelDimension:
211-
// This order is critical to prevent a UI race condition. After saving,
212-
// the component's local `currentSettings` is updated immediately, while
213-
// the global `codebaseIndexConfig` might still be stale. Prioritizing
214-
// `currentSettings` ensures the UI reflects the saved value instantly.
215-
currentSettings.codebaseIndexEmbedderModelDimension ||
216-
codebaseIndexConfig.codebaseIndexEmbedderModelDimension ||
217-
undefined,
217+
codebaseIndexConfig.codebaseIndexEmbedderModelDimension || modelProfile?.defaultDimension,
218218
codebaseIndexSearchMaxResults:
219-
codebaseIndexConfig.codebaseIndexSearchMaxResults ?? CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS,
219+
codebaseIndexConfig.codebaseIndexSearchMaxResults ??
220+
CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_RESULTS,
220221
codebaseIndexSearchMinScore:
221-
codebaseIndexConfig.codebaseIndexSearchMinScore ?? CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE,
222+
codebaseIndexConfig.codebaseIndexSearchMinScore ??
223+
CODEBASE_INDEX_DEFAULTS.DEFAULT_SEARCH_MIN_SCORE,
224+
// Keys are initially set to empty and populated by a separate effect.
222225
codeIndexOpenAiKey: "",
223226
codeIndexQdrantApiKey: "",
224-
codebaseIndexOpenAiCompatibleBaseUrl: codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl || "",
227+
codebaseIndexOpenAiCompatibleBaseUrl:
228+
codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl || "",
225229
codebaseIndexOpenAiCompatibleApiKey: "",
226230
codebaseIndexGeminiApiKey: "",
227231
}
228232
setInitialSettings(settings)
229233
setCurrentSettings(settings)
230234

231-
// Request secret status to check if secrets exist
235+
// Requests the status of the secrets to display placeholders correctly.
232236
vscode.postMessage({ type: "requestCodeIndexSecretStatus" })
233237
}
234-
}, [codebaseIndexConfig, currentSettings.codebaseIndexEmbedderModelDimension])
238+
}, [codebaseIndexConfig, codebaseIndexModels]) // Dependencies are now correct and complete.
235239

236240
// Request initial indexing status
237241
useEffect(() => {
@@ -373,6 +377,27 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
373377
}
374378
}
375379

380+
// Handles model changes, ensuring dimension is reset correctly
381+
const handleModelChange = (newModelId: string) => {
382+
const provider = currentSettings.codebaseIndexEmbedderProvider
383+
const modelProfile = codebaseIndexModels?.[provider]?.[newModelId]
384+
const defaultDimension = modelProfile?.defaultDimension
385+
386+
setCurrentSettings((prev) => ({
387+
...prev,
388+
codebaseIndexEmbedderModelId: newModelId,
389+
codebaseIndexEmbedderModelDimension: defaultDimension,
390+
}))
391+
392+
// Clear validation errors for model and dimension
393+
setFormErrors((prev) => {
394+
const newErrors = { ...prev }
395+
delete newErrors.codebaseIndexEmbedderModelId
396+
delete newErrors.codebaseIndexEmbedderModelDimension
397+
return newErrors
398+
})
399+
}
400+
376401
// Validation function
377402
const validateSettings = (): boolean => {
378403
const schema = createValidationSchema(currentSettings.codebaseIndexEmbedderProvider, t, codebaseIndexModels)
@@ -910,9 +935,7 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
910935
</label>
911936
<VSCodeDropdown
912937
value={currentSettings.codebaseIndexEmbedderModelId}
913-
onChange={(e: any) =>
914-
updateSetting("codebaseIndexEmbedderModelId", e.target.value)
915-
}
938+
onChange={(e: any) => handleModelChange(e.target.value)}
916939
className={cn("w-full", {
917940
"border-red-500": formErrors.codebaseIndexEmbedderModelId,
918941
})}>

0 commit comments

Comments
 (0)