From 261cbfff12efb98a5cf5d0bbbd3fb68f8e3bd079 Mon Sep 17 00:00:00 2001 From: yyh Date: Mon, 18 May 2026 17:26:19 +0800 Subject: [PATCH] refactor: tighten api extension modal contract --- .../__tests__/modal.spec.tsx | 20 +--------------- .../api-based-extension-page/index.tsx | 3 +-- .../api-based-extension-page/modal.tsx | 24 +++++++++---------- .../api-based-extension-page/selector.tsx | 1 - 4 files changed, 13 insertions(+), 35 deletions(-) diff --git a/web/app/components/header/account-setting/api-based-extension-page/__tests__/modal.spec.tsx b/web/app/components/header/account-setting/api-based-extension-page/__tests__/modal.spec.tsx index 2336892e73..b10ab73b3b 100644 --- a/web/app/components/header/account-setting/api-based-extension-page/__tests__/modal.spec.tsx +++ b/web/app/components/header/account-setting/api-based-extension-page/__tests__/modal.spec.tsx @@ -49,7 +49,6 @@ describe('ApiBasedExtensionModal', () => { const renderModal = (props: Partial> = {}) => render( { }) describe('Interactions', () => { - it('should work when onSave is not provided', async () => { - // Arrange - vi.mocked(addApiBasedExtension).mockResolvedValue(mockExtension({ id: 'new-id' })) - renderModal({ onSave: undefined }) - - // Act - fireEvent.change(screen.getByPlaceholderText('common.apiBasedExtension.modal.name.placeholder'), { target: { value: 'New Ext' } }) - fireEvent.change(screen.getByPlaceholderText('common.apiBasedExtension.modal.apiEndpoint.placeholder'), { target: { value: 'https://api.test' } }) - fireEvent.change(screen.getByPlaceholderText('common.apiBasedExtension.modal.apiKey.placeholder'), { target: { value: 'secret-key' } }) - fireEvent.click(screen.getByText('common.operation.save')) - - // Assert - await waitFor(() => { - expect(addApiBasedExtension).toHaveBeenCalled() - }) - }) - it('should request closing when clicking cancel button', () => { // Arrange renderModal() @@ -298,7 +280,7 @@ describe('ApiBasedExtensionModal', () => { } as unknown as ReturnType) // Act - const { container } = renderModal({ onSave: undefined }) + const { container } = renderModal() // Assert const inputs = container.querySelectorAll('input') diff --git a/web/app/components/header/account-setting/api-based-extension-page/index.tsx b/web/app/components/header/account-setting/api-based-extension-page/index.tsx index ccef2022e7..f24fa876f3 100644 --- a/web/app/components/header/account-setting/api-based-extension-page/index.tsx +++ b/web/app/components/header/account-setting/api-based-extension-page/index.tsx @@ -8,7 +8,7 @@ import Item from './item' import ApiBasedExtensionModal from './modal' type ApiBasedExtensionDialogState = { - extension: Partial + extension?: ApiBasedExtensionResponse onSave: () => void } | null @@ -19,7 +19,6 @@ const ApiBasedExtensionPage = () => { const handleOpenApiBasedExtensionModal = () => { setDialogState({ - extension: {}, onSave: () => mutate(), }) } diff --git a/web/app/components/header/account-setting/api-based-extension-page/modal.tsx b/web/app/components/header/account-setting/api-based-extension-page/modal.tsx index 887d7078ef..8a44739e82 100644 --- a/web/app/components/header/account-setting/api-based-extension-page/modal.tsx +++ b/web/app/components/header/account-setting/api-based-extension-page/modal.tsx @@ -14,10 +14,9 @@ import { addApiBasedExtension, updateApiBasedExtension } from '@/service/common' type ApiBasedExtensionModalProps = { open: boolean - extension: Partial + extension?: ApiBasedExtensionResponse onOpenChange: (open: boolean) => void - onSave?: (newData: ApiBasedExtensionResponse) => void - disablePointerDismissal?: boolean + onSave: (newData: ApiBasedExtensionResponse) => void } const ApiBasedExtensionModal = ({ @@ -25,11 +24,11 @@ const ApiBasedExtensionModal = ({ extension, onOpenChange, onSave, - disablePointerDismissal = true, }: ApiBasedExtensionModalProps) => { const { t } = useTranslation() const docLink = useDocLink() const [loading, setLoading] = useState(false) + const isEditing = !!extension const nameLabel = t('apiBasedExtension.modal.name.title', { ns: 'common' }) const apiEndpointLabel = t('apiBasedExtension.modal.apiEndpoint.title', { ns: 'common' }) const apiKeyLabel = t('apiBasedExtension.modal.apiKey.title', { ns: 'common' }) @@ -44,7 +43,7 @@ const ApiBasedExtensionModal = ({ api_key: formValues.api_key, } - const res = extension.id + const res = extension ? await updateApiBasedExtension({ url: `/api-based-extension/${extension.id}`, body: { @@ -57,11 +56,10 @@ const ApiBasedExtensionModal = ({ body: payload, }) - if (extension.id) + if (extension) toast.success(t('actionMsg.modifiedSuccessfully', { ns: 'common' })) - if (onSave) - onSave(res) + onSave(res) } finally { setLoading(false) @@ -69,7 +67,7 @@ const ApiBasedExtensionModal = ({ } return ( - + - {extension.name + {isEditing ? t('apiBasedExtension.modal.editTitle', { ns: 'common' }) : t('apiBasedExtension.modal.title', { ns: 'common' })} @@ -86,7 +84,7 @@ const ApiBasedExtensionModal = ({ {nameLabel} {t('errorMsg.fieldRequired', { ns: 'common', field: nameLabel })} @@ -96,7 +94,7 @@ const ApiBasedExtensionModal = ({ {apiEndpointLabel} @@ -125,7 +123,7 @@ const ApiBasedExtensionModal = ({ {apiKeyLabel} {t('errorMsg.fieldRequired', { ns: 'common', field: apiKeyLabel })} diff --git a/web/app/components/header/account-setting/api-based-extension-page/selector.tsx b/web/app/components/header/account-setting/api-based-extension-page/selector.tsx index e98ff593cf..fb89210cbc 100644 --- a/web/app/components/header/account-setting/api-based-extension-page/selector.tsx +++ b/web/app/components/header/account-setting/api-based-extension-page/selector.tsx @@ -131,7 +131,6 @@ const ApiBasedExtensionSelector = ({ addModalOpen && (