From b0e7e7752f183d0453d214fc27293a4530a12e98 Mon Sep 17 00:00:00 2001 From: yangzheli <43645580+yangzheli@users.noreply.github.com> Date: Thu, 13 Nov 2025 11:44:21 +0800 Subject: [PATCH] refactor(web): reuse the same edit-custom-collection-modal component, and fix the pop up error (#28003) --- .../edit-custom-collection-modal/index.tsx | 3 + .../edit-custom-collection-modal/modal.tsx | 361 ------------------ .../workflow/block-selector/tool-picker.tsx | 4 +- 3 files changed, 5 insertions(+), 363 deletions(-) delete mode 100644 web/app/components/tools/edit-custom-collection-modal/modal.tsx diff --git a/web/app/components/tools/edit-custom-collection-modal/index.tsx b/web/app/components/tools/edit-custom-collection-modal/index.tsx index 95a204c1ec..48801b018f 100644 --- a/web/app/components/tools/edit-custom-collection-modal/index.tsx +++ b/web/app/components/tools/edit-custom-collection-modal/index.tsx @@ -24,6 +24,7 @@ import Toast from '@/app/components/base/toast' type Props = { positionLeft?: boolean + dialogClassName?: string payload: any onHide: () => void onAdd?: (payload: CustomCollectionBackend) => void @@ -33,6 +34,7 @@ type Props = { // Add and Edit const EditCustomCollectionModal: FC = ({ positionLeft, + dialogClassName = '', payload, onHide, onAdd, @@ -186,6 +188,7 @@ const EditCustomCollectionModal: FC = ({ positionCenter={isAdd && !positionLeft} onHide={onHide} title={t(`tools.createTool.${isAdd ? 'title' : 'editTitle'}`)!} + dialogClassName={dialogClassName} panelClassName='mt-2 !w-[640px]' maxWidthClassName='!max-w-[640px]' height='calc(100vh - 16px)' diff --git a/web/app/components/tools/edit-custom-collection-modal/modal.tsx b/web/app/components/tools/edit-custom-collection-modal/modal.tsx deleted file mode 100644 index 3e278f7b53..0000000000 --- a/web/app/components/tools/edit-custom-collection-modal/modal.tsx +++ /dev/null @@ -1,361 +0,0 @@ -'use client' -import type { FC } from 'react' -import React, { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useDebounce, useGetState } from 'ahooks' -import { produce } from 'immer' -import { LinkExternal02, Settings01 } from '../../base/icons/src/vender/line/general' -import type { Credential, CustomCollectionBackend, CustomParamSchema, Emoji } from '../types' -import { AuthHeaderPrefix, AuthType } from '../types' -import GetSchema from './get-schema' -import ConfigCredentials from './config-credentials' -import TestApi from './test-api' -import cn from '@/utils/classnames' -import Input from '@/app/components/base/input' -import Textarea from '@/app/components/base/textarea' -import EmojiPicker from '@/app/components/base/emoji-picker' -import AppIcon from '@/app/components/base/app-icon' -import { parseParamsSchema } from '@/service/tools' -import LabelSelector from '@/app/components/tools/labels/selector' -import Toast from '@/app/components/base/toast' -import Modal from '../../base/modal' -import Button from '@/app/components/base/button' - -type Props = { - positionLeft?: boolean - payload: any - onHide: () => void - onAdd?: (payload: CustomCollectionBackend) => void - onRemove?: () => void - onEdit?: (payload: CustomCollectionBackend) => void -} -// Add and Edit -const EditCustomCollectionModal: FC = ({ - payload, - onHide, - onAdd, - onEdit, - onRemove, -}) => { - const { t } = useTranslation() - const isAdd = !payload - const isEdit = !!payload - - const [editFirst, setEditFirst] = useState(!isAdd) - const [paramsSchemas, setParamsSchemas] = useState(payload?.tools || []) - const [customCollection, setCustomCollection, getCustomCollection] = useGetState(isAdd - ? { - provider: '', - credentials: { - auth_type: AuthType.none, - api_key_header: 'Authorization', - api_key_header_prefix: AuthHeaderPrefix.basic, - }, - icon: { - content: '🕵️', - background: '#FEF7C3', - }, - schema_type: '', - schema: '', - } - : payload) - - const originalProvider = isEdit ? payload.provider : '' - - const [showEmojiPicker, setShowEmojiPicker] = useState(false) - const emoji = customCollection.icon - const setEmoji = (emoji: Emoji) => { - const newCollection = produce(customCollection, (draft) => { - draft.icon = emoji - }) - setCustomCollection(newCollection) - } - const schema = customCollection.schema - const debouncedSchema = useDebounce(schema, { wait: 500 }) - const setSchema = (schema: any) => { - const newCollection = produce(customCollection, (draft) => { - draft.schema = schema - }) - setCustomCollection(newCollection) - } - - useEffect(() => { - if (!debouncedSchema) - return - if (isEdit && editFirst) { - setEditFirst(false) - return - } - (async () => { - try { - const { parameters_schema, schema_type } = await parseParamsSchema(debouncedSchema) - const customCollection = getCustomCollection() - const newCollection = produce(customCollection, (draft) => { - draft.schema_type = schema_type - }) - setCustomCollection(newCollection) - setParamsSchemas(parameters_schema) - } - catch { - const customCollection = getCustomCollection() - const newCollection = produce(customCollection, (draft) => { - draft.schema_type = '' - }) - setCustomCollection(newCollection) - setParamsSchemas([]) - } - })() - }, [debouncedSchema]) - - const [credentialsModalShow, setCredentialsModalShow] = useState(false) - const credential = customCollection.credentials - const setCredential = (credential: Credential) => { - const newCollection = produce(customCollection, (draft) => { - draft.credentials = credential - }) - setCustomCollection(newCollection) - } - - const [currTool, setCurrTool] = useState(null) - const [isShowTestApi, setIsShowTestApi] = useState(false) - - const [labels, setLabels] = useState(payload?.labels || []) - const handleLabelSelect = (value: string[]) => { - setLabels(value) - } - - const handleSave = () => { - // const postData = clone(customCollection) - const postData = produce(customCollection, (draft) => { - delete draft.tools - - if (draft.credentials.auth_type === AuthType.none) { - delete draft.credentials.api_key_header - delete draft.credentials.api_key_header_prefix - delete draft.credentials.api_key_value - } - - draft.labels = labels - }) - - let errorMessage = '' - if (!postData.provider) - errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') }) - - if (!postData.schema) - errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.schema') }) - - if (errorMessage) { - Toast.notify({ - type: 'error', - message: errorMessage, - }) - return - } - - if (isAdd) { - onAdd?.(postData) - return - } - - onEdit?.({ - ...postData, - original_provider: originalProvider, - }) - } - - const getPath = (url: string) => { - if (!url) - return '' - - try { - const path = decodeURI(new URL(url).pathname) - return path || '' - } - catch { - return url - } - } - - return ( - <> - -
-
- {t('tools.createTool.title')} -
-
-
-
{t('tools.createTool.name')} *
-
- { setShowEmojiPicker(true) }} className='cursor-pointer' icon={emoji.content} background={emoji.background} /> - { - const newCollection = produce(customCollection, (draft) => { - draft.provider = e.target.value - }) - setCustomCollection(newCollection) - }} - /> -
-
- - {/* Schema */} -
-
-
-
{t('tools.createTool.schema')}*
-
- -
{t('tools.createTool.viewSchemaSpec')}
- -
-
- - -
-