From f70c23dd7a27b82d20008e4a7c90fdb294ba3b45 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Fri, 8 Nov 2024 16:11:19 +0800 Subject: [PATCH] endpoints api --- .../plugin-detail-panel/endpoint-card.tsx | 37 ++++-- .../plugin-detail-panel/endpoint-list.tsx | 28 +++-- .../plugins/plugin-detail-panel/index.tsx | 2 +- .../plugins/plugin-detail-panel/mock.ts | 105 ------------------ .../plugins/plugin-detail-panel/utils.ts | 21 ++++ web/app/components/tools/types.ts | 2 +- web/service/plugins.ts | 4 +- 7 files changed, 74 insertions(+), 125 deletions(-) delete mode 100644 web/app/components/plugins/plugin-detail-panel/mock.ts create mode 100644 web/app/components/plugins/plugin-detail-panel/utils.ts diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 948cbdd225..1a984b4eda 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -4,12 +4,14 @@ import { useBoolean } from 'ahooks' import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react' import type { EndpointListItem } from '../types' import EndpointModal from './endpoint-modal' +import { NAME_FIELD } from './utils' import { addDefaultValue, toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import ActionButton from '@/app/components/base/action-button' import CopyBtn from '@/app/components/base/copy-btn' import Confirm from '@/app/components/base/confirm' import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' +import Toast from '@/app/components/base/toast' import { deleteEndpoint, disableEndpoint, @@ -19,10 +21,12 @@ import { type Props = { data: EndpointListItem + handleChange: () => void } const EndpointCard = ({ data, + handleChange, }: Props) => { const { t } = useTranslation() const [active, setActive] = useState(data.enabled) @@ -38,9 +42,11 @@ const EndpointCard = ({ url: '/workspaces/current/endpoints/enable', endpointID, }) + await handleChange() } - catch (error) { + catch (error: any) { console.error(error) + Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) setActive(false) } } @@ -50,9 +56,12 @@ const EndpointCard = ({ url: '/workspaces/current/endpoints/disable', endpointID, }) + await handleChange() + hideDisableConfirm() } catch (error) { console.error(error) + Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) setActive(true) } } @@ -77,9 +86,12 @@ const EndpointCard = ({ url: '/workspaces/current/endpoints/delete', endpointID, }) + await handleChange() + hideDeleteConfirm() } catch (error) { console.error(error) + Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) } } @@ -89,25 +101,34 @@ const EndpointCard = ({ }] = useBoolean(false) const formSchemas = useMemo(() => { - return toolCredentialToFormSchemas(data.declaration.settings) + return toolCredentialToFormSchemas([NAME_FIELD, ...data.declaration.settings]) }, [data.declaration.settings]) const formValue = useMemo(() => { - return addDefaultValue(data.settings, formSchemas) - }, [data.settings, formSchemas]) + const formValue = { + name: data.name, + ...data.settings, + } + return addDefaultValue(formValue, formSchemas) + }, [data.name, data.settings, formSchemas]) - const handleUpdate = (state: any) => { + const handleUpdate = async (state: any) => { + const newName = state.name + delete state.name try { - updateEndpoint({ - url: '/workspaces/current/endpoints', + await updateEndpoint({ + url: '/workspaces/current/endpoints/update', body: { endpoint_id: data.id, settings: state, - name: state.name, + name: newName, }, }) + await handleChange() + hideEndpointModalConfirm() } catch (error) { console.error(error) + Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) } } diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 495d451f90..6323e42365 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -5,21 +5,27 @@ import { useBoolean } from 'ahooks' import { RiAddLine } from '@remixicon/react' import EndpointModal from './endpoint-modal' import EndpointCard from './endpoint-card' +import { NAME_FIELD } from './utils' import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' +import Toast from '@/app/components/base/toast' import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import { createEndpoint, fetchEndpointList, } from '@/service/plugins' +import cn from '@/utils/classnames' -const EndpointList = () => { +type Props = { + showTopBorder?: boolean +} +const EndpointList = ({ showTopBorder }: Props) => { const { t } = useTranslation() const pluginDetail = usePluginPageContext(v => v.currentPluginDetail) const pluginUniqueID = pluginDetail.plugin_unique_identifier const declaration = pluginDetail.declaration.endpoint - const { data } = useSWR( + const { data, mutate } = useSWR( { url: '/workspaces/current/endpoints/list/plugin', params: { @@ -36,22 +42,27 @@ const EndpointList = () => { }] = useBoolean(false) const formSchemas = useMemo(() => { - return toolCredentialToFormSchemas(declaration.settings) + return toolCredentialToFormSchemas([NAME_FIELD, ...declaration.settings]) }, [declaration.settings]) - const handleCreate = (state: any) => { + const handleCreate = async (state: any) => { + const newName = state.name + delete state.name try { - createEndpoint({ - url: '/workspaces/current/endpoints', + await createEndpoint({ + url: '/workspaces/current/endpoints/create', body: { plugin_unique_identifier: pluginUniqueID, settings: state, - name: state.name, + name: newName, }, }) + await mutate() + hideEndpointModal() } catch (error) { console.error(error) + Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) } } @@ -59,7 +70,7 @@ const EndpointList = () => { return null return ( -
+
{t('plugin.detailPanel.endpoints')} @@ -81,6 +92,7 @@ const EndpointList = () => { ))}
diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 0dd85a4f87..7bd1849625 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -42,8 +42,8 @@ const PluginDetailPanel: FC = ({ onDelete={onDelete} />
- {!!pluginDetail.declaration.endpoint && } {!!pluginDetail.declaration.tool && } + {!!pluginDetail.declaration.endpoint && } {!!pluginDetail.declaration.model && }
diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts deleted file mode 100644 index dffe753922..0000000000 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { PluginSource, PluginType } from '../types' - -export const toolNotion = { - id: 'dlfajkgjdga-dfjalksjfglkds-dfjakld', - created_at: '2024-10-16 16:05:33', - updated_at: '2024-10-16 16:05:33', - name: 'notion page search', - plugin_id: 'Notion/notion-page-search', - plugin_unique_identifier: 'Notion/notion-page-search:1.2.0@fldsjflkdsajfldsakajfkls', - declaration: { - version: '1.2.0', - author: 'Notion', - name: 'notion page search', - category: PluginType.tool, - icon: 'https://via.placeholder.com/150', - label: { - 'en-US': 'Notion Page Search', - 'zh-Hans': 'Notion 页面搜索', - }, - description: { - 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', - 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', - }, - created_at: '2024-10-16 16:05:33', - resource: {}, - plugins: {}, - endpoint: { - settings: [ - { - type: 'secret-input', - name: 'api-key', - required: true, - default: null, - options: null, - label: { - en_US: 'API-key', - zh_Hans: 'API-key', - }, - help: null, - url: null, - placeholder: { - en_US: 'Please input your API key', - zh_Hans: '请输入你的 API key', - }, - }, - ], - endpoints: [ - { path: '/duck/', method: 'GET' }, - { path: '/neko', method: 'GET' }, - ], - }, - tool: null, // TODO - verified: true, - }, - installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg', - tenant_id: 'jflkdsjoewingljlsadjgoijg', - endpoints_setups: 2, - endpoints_active: 1, - version: '1.2.0', - source: PluginSource.marketplace, - meta: null, -} - -export const toolNotionEndpoints = [ - { - id: 'dlfajkgjdga-dfjalksjfglkds-dfjakld', - created_at: '2024-10-16 16:05:33', - updated_at: '2024-10-16 16:05:33', - settings: { - 'api-key': '*******', - }, - tenant_id: 'jflkdsjoewingljlsadjgoijg', - plugin_id: 'Notion/notion-page-search', - expired_at: '2024-10-16 16:05:33', - declaration: { - settings: [ - { - type: 'secret-input', - name: 'api-key', - required: true, - default: null, - options: null, - label: { - en_US: 'API-key', - zh_Hans: 'API-key', - }, - help: null, - url: null, - placeholder: { - en_US: 'Please input your API key', - zh_Hans: '请输入你的 API key', - }, - }, - ], - endpoints: [ - { path: '/duck/', method: 'GET' }, - { path: '/neko', method: 'GET' }, - ], - }, - name: 'default', - enabled: true, - url: 'http://localhost:5002/e/45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8', - hook_id: '45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8', - }, -] diff --git a/web/app/components/plugins/plugin-detail-panel/utils.ts b/web/app/components/plugins/plugin-detail-panel/utils.ts new file mode 100644 index 0000000000..fd51142a38 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/utils.ts @@ -0,0 +1,21 @@ +import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' + +export const NAME_FIELD = { + type: FormTypeEnum.textInput, + name: 'name', + label: { + en_US: 'Endpoint Name', + zh_Hans: '端点名称', + ja_JP: 'エンドポイント名', + pt_BR: 'Nome do ponto final', + }, + placeholder: { + en_US: 'Endpoint Name', + zh_Hans: '端点名称', + ja_JP: 'エンドポイント名', + pt_BR: 'Nome do ponto final', + }, + required: true, + default: '', + help: null, +} diff --git a/web/app/components/tools/types.ts b/web/app/components/tools/types.ts index 9e899489bb..34cc491481 100644 --- a/web/app/components/tools/types.ts +++ b/web/app/components/tools/types.ts @@ -80,7 +80,7 @@ export type Tool = { export type ToolCredential = { name: string label: TypeWithI18N - help: TypeWithI18N + help: TypeWithI18N | null placeholder: TypeWithI18N type: string required: boolean diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 6d246e9239..b7d5125f2e 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -1,5 +1,5 @@ import type { Fetcher } from 'swr' -import { del, get, getMarketplace, post, upload } from './base' +import { get, getMarketplace, post, upload } from './base' import type { CreateEndpointRequest, EndpointOperationResponse, @@ -32,7 +32,7 @@ export const fetchEndpointList: Fetcher = ({ url, endpointID }) => { // url = /workspaces/current/endpoints/delete - return del(url, { body: { endpoint_id: endpointID } }) + return post(url, { body: { endpoint_id: endpointID } }) } export const updateEndpoint: Fetcher = ({ url, body }) => {