From c67c6fc740a6ce58f625167fe36d9e2404b39201 Mon Sep 17 00:00:00 2001 From: yyhhyyyyyy Date: Mon, 15 Jun 2026 16:56:36 +0800 Subject: [PATCH] fix(channels): remove effect-driven test dialog state resets --- .../dialogs/channel-test-dialog.tsx | 104 ++++++++++++------ 1 file changed, 70 insertions(+), 34 deletions(-) diff --git a/web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx b/web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx index a63817bf..e42eb8c6 100644 --- a/web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx +++ b/web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx @@ -16,7 +16,7 @@ along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ -import { useCallback, useEffect, useMemo, useState } from 'react' +import { type ChangeEvent, useCallback, useMemo, useState } from 'react' import { useQueryClient } from '@tanstack/react-query' import { type ColumnDef, @@ -73,7 +73,11 @@ import { formatResponseTime, handleTestChannel, } from '../../lib' -import type { GetChannelsResponse, SearchChannelsResponse } from '../../types' +import type { + Channel, + GetChannelsResponse, + SearchChannelsResponse, +} from '../../types' import { useChannels } from '../channels-provider' type ChannelTestDialogProps = { @@ -81,6 +85,10 @@ type ChannelTestDialogProps = { onOpenChange: (open: boolean) => void } +type ChannelTestDialogContentProps = ChannelTestDialogProps & { + currentRow: Channel +} + type ModelRow = { model: string } @@ -257,10 +265,30 @@ export function ChannelTestDialog({ open, onOpenChange, }: ChannelTestDialogProps) { - const { t } = useTranslation() const { currentRow } = useChannels() + + if (!currentRow) { + return null + } + + return ( + + ) +} + +function ChannelTestDialogContent({ + open, + onOpenChange, + currentRow, +}: ChannelTestDialogContentProps) { + const { t } = useTranslation() const queryClient = useQueryClient() - const currentChannelId = currentRow?.id + const currentChannelId = currentRow.id const [endpointType, setEndpointType] = useState('auto') const [isStreamTest, setIsStreamTest] = useState(false) const [searchTerm, setSearchTerm] = useState('') @@ -297,23 +325,30 @@ export function ChannelTestDialog({ setPagination({ pageIndex: 0, pageSize: 10 }) }, []) - useEffect(() => { - if (open && currentRow) { - resetState() - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [open, currentRow?.id, resetState]) - const streamDisabled = STREAM_INCOMPATIBLE_ENDPOINTS.has(endpointType) + const effectiveStreamTest = !streamDisabled && isStreamTest - useEffect(() => { - if (streamDisabled) { + const handleEndpointTypeChange = useCallback((value: string | null) => { + if (value === null) return + + setEndpointType(value) + if (STREAM_INCOMPATIBLE_ENDPOINTS.has(value)) { setIsStreamTest(false) } - }, [streamDisabled]) + }, []) - const modelsValue = currentRow?.models ?? '' - const defaultTestModel = currentRow?.test_model?.trim() + const handleSearchTermChange = useCallback( + (event: ChangeEvent) => { + setSearchTerm(event.target.value) + setPagination((prev) => + prev.pageIndex === 0 ? prev : { ...prev, pageIndex: 0 } + ) + }, + [] + ) + + const modelsValue = currentRow.models + const defaultTestModel = currentRow.test_model?.trim() const models = useMemo(() => { if (!modelsValue) return [] @@ -329,10 +364,6 @@ export function ChannelTestDialog({ return models.filter((model) => model.toLowerCase().includes(keyword)) }, [models, searchTerm]) - useEffect(() => { - setPagination((prev) => ({ ...prev, pageIndex: 0 })) - }, [searchTerm, modelsValue]) - const tableData = useMemo( () => filteredModels.map((model) => ({ model })), [filteredModels] @@ -360,7 +391,7 @@ export function ChannelTestDialog({ const updateChannelTestCache = useCallback( (patch?: ChannelTestCachePatch) => { - if (!patch || currentChannelId === undefined) return + if (!patch) return queryClient.setQueriesData( { queryKey: channelsQueryKeys.lists() }, @@ -424,7 +455,7 @@ export function ChannelTestDialog({ { testModel: model, endpointType: endpointType === 'auto' ? undefined : endpointType, - stream: isStreamTest || undefined, + stream: effectiveStreamTest || undefined, silent, }, (success, responseTime, error, errorCode) => { @@ -462,7 +493,7 @@ export function ChannelTestDialog({ [ currentRow, endpointType, - isStreamTest, + effectiveStreamTest, markModelTesting, refreshChannelLists, t, @@ -518,10 +549,19 @@ export function ChannelTestDialog({ [refreshChannelLists, t, testSingleModel] ) - const handleClose = () => { + const handleClose = useCallback(() => { resetState() onOpenChange(false) - } + }, [onOpenChange, resetState]) + + const handleDialogOpenChange = useCallback( + (nextOpen: boolean) => { + if (!nextOpen) { + handleClose() + } + }, + [handleClose] + ) const isAnyTesting = testingModels.size > 0 || isBatchTesting @@ -641,15 +681,11 @@ export function ChannelTestDialog({ withFacetedRowModel: false, }) - if (!currentRow) { - return null - } - return ( <> @@ -675,7 +711,7 @@ export function ChannelTestDialog({ setSearchTerm(e.target.value)} + onChange={handleSearchTermChange} className='sm:w-64' />