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 1a984b4eda..14e9abef9b 100644
--- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx
+++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx
@@ -13,11 +13,11 @@ import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
import Toast from '@/app/components/base/toast'
import {
- deleteEndpoint,
- disableEndpoint,
- enableEndpoint,
- updateEndpoint,
-} from '@/service/plugins'
+ useDeleteEndpoint,
+ useDisableEndpoint,
+ useEnableEndpoint,
+ useUpdateEndpoint,
+} from '@/service/use-endpoints'
type Props = {
data: EndpointListItem
@@ -32,43 +32,34 @@ const EndpointCard = ({
const [active, setActive] = useState(data.enabled)
const endpointID = data.id
+ // switch
const [isShowDisableConfirm, {
setTrue: showDisableConfirm,
setFalse: hideDisableConfirm,
}] = useBoolean(false)
- const activeEndpoint = async () => {
- try {
- await enableEndpoint({
- url: '/workspaces/current/endpoints/enable',
- endpointID,
- })
+ const { mutate: enableEndpoint } = useEnableEndpoint({
+ onSuccess: async () => {
await handleChange()
- }
- catch (error: any) {
- console.error(error)
+ },
+ onError: () => {
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
setActive(false)
- }
- }
- const inactiveEndpoint = async () => {
- try {
- await disableEndpoint({
- url: '/workspaces/current/endpoints/disable',
- endpointID,
- })
+ },
+ })
+ const { mutate: disableEndpoint } = useDisableEndpoint({
+ onSuccess: async () => {
await handleChange()
hideDisableConfirm()
- }
- catch (error) {
- console.error(error)
+ },
+ onError: () => {
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
- setActive(true)
- }
- }
+ setActive(false)
+ },
+ })
const handleSwitch = (state: boolean) => {
if (state) {
setActive(true)
- activeEndpoint()
+ enableEndpoint(endpointID)
}
else {
setActive(false)
@@ -76,30 +67,26 @@ const EndpointCard = ({
}
}
+ // delete
const [isShowDeleteConfirm, {
setTrue: showDeleteConfirm,
setFalse: hideDeleteConfirm,
}] = useBoolean(false)
- const handleDelete = async () => {
- try {
- await deleteEndpoint({
- url: '/workspaces/current/endpoints/delete',
- endpointID,
- })
+ const { mutate: deleteEndpoint } = useDeleteEndpoint({
+ onSuccess: async () => {
await handleChange()
hideDeleteConfirm()
- }
- catch (error) {
- console.error(error)
+ },
+ onError: () => {
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
- }
- }
+ },
+ })
+ // update
const [isShowEndpointModal, {
setTrue: showEndpointModalConfirm,
setFalse: hideEndpointModalConfirm,
}] = useBoolean(false)
-
const formSchemas = useMemo(() => {
return toolCredentialToFormSchemas([NAME_FIELD, ...data.declaration.settings])
}, [data.declaration.settings])
@@ -110,27 +97,19 @@ const EndpointCard = ({
}
return addDefaultValue(formValue, formSchemas)
}, [data.name, data.settings, formSchemas])
-
- const handleUpdate = async (state: any) => {
- const newName = state.name
- delete state.name
- try {
- await updateEndpoint({
- url: '/workspaces/current/endpoints/update',
- body: {
- endpoint_id: data.id,
- settings: state,
- name: newName,
- },
- })
+ const { mutate: updateEndpoint } = useUpdateEndpoint({
+ onSuccess: async () => {
await handleChange()
hideEndpointModalConfirm()
- }
- catch (error) {
- console.error(error)
+ },
+ onError: () => {
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
- }
- }
+ },
+ })
+ const handleUpdate = (state: any) => updateEndpoint({
+ endpointID,
+ state,
+ })
return (
@@ -192,7 +171,7 @@ const EndpointCard = ({
hideDisableConfirm()
setActive(true)
}}
- onConfirm={inactiveEndpoint}
+ onConfirm={() => disableEndpoint(endpointID)}
/>
)}
{isShowDeleteConfirm && (
@@ -201,7 +180,7 @@ const EndpointCard = ({
title={t('plugin.detailPanel.endpointDeleteTip')}
content={
{t('plugin.detailPanel.endpointDeleteContent', { name: data.name })}
}
onCancel={hideDeleteConfirm}
- onConfirm={handleDelete}
+ onConfirm={() => deleteEndpoint(endpointID)}
/>
)}
{isShowEndpointModal && (
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 6323e42365..b5f5d2768e 100644
--- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx
+++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx
@@ -1,6 +1,5 @@
import React, { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
-import useSWR from 'swr'
import { useBoolean } from 'ahooks'
import { RiAddLine } from '@remixicon/react'
import EndpointModal from './endpoint-modal'
@@ -12,9 +11,10 @@ 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'
+ useCreateEndpoint,
+ useEndpointList,
+ useInvalidateEndpointList,
+} from '@/service/use-endpoints'
import cn from '@/utils/classnames'
type Props = {
@@ -25,17 +25,9 @@ const EndpointList = ({ showTopBorder }: Props) => {
const pluginDetail = usePluginPageContext(v => v.currentPluginDetail)
const pluginUniqueID = pluginDetail.plugin_unique_identifier
const declaration = pluginDetail.declaration.endpoint
- const { data, mutate } = useSWR(
- {
- url: '/workspaces/current/endpoints/list/plugin',
- params: {
- plugin_id: pluginDetail.plugin_id,
- page: 1,
- page_size: 100,
- },
- },
- fetchEndpointList,
- )
+ const { data } = useEndpointList(pluginDetail.plugin_id)
+ const invalidateEndpointList = useInvalidateEndpointList()
+
const [isShowEndpointModal, {
setTrue: showEndpointModal,
setFalse: hideEndpointModal,
@@ -45,26 +37,20 @@ const EndpointList = ({ showTopBorder }: Props) => {
return toolCredentialToFormSchemas([NAME_FIELD, ...declaration.settings])
}, [declaration.settings])
- const handleCreate = async (state: any) => {
- const newName = state.name
- delete state.name
- try {
- await createEndpoint({
- url: '/workspaces/current/endpoints/create',
- body: {
- plugin_unique_identifier: pluginUniqueID,
- settings: state,
- name: newName,
- },
- })
- await mutate()
+ const { mutate: createEndpoint } = useCreateEndpoint({
+ onSuccess: async () => {
+ await invalidateEndpointList(pluginDetail.plugin_id)
hideEndpointModal()
- }
- catch (error) {
- console.error(error)
+ },
+ onError: () => {
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
- }
- }
+ },
+ })
+
+ const handleCreate = (state: any) => createEndpoint({
+ pluginUniqueID,
+ state,
+ })
if (!data)
return null
@@ -92,7 +78,7 @@ const EndpointList = ({ showTopBorder }: Props) => {
invalidateEndpointList(pluginDetail.plugin_id)}
/>
))}
diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts
index 629b9b7582..40627f67a3 100644
--- a/web/app/components/plugins/types.ts
+++ b/web/app/components/plugins/types.ts
@@ -194,19 +194,10 @@ export type GitHubUrlInfo = {
}
// endpoint
-export type CreateEndpointRequest = {
- plugin_unique_identifier: string
- settings: Record
- name: string
-}
export type EndpointOperationResponse = {
result: 'success' | 'error'
}
-export type EndpointsRequest = {
- page_size: number
- page: number
- plugin_id: string
-}
+
export type EndpointsResponse = {
endpoints: EndpointListItem[]
has_more: boolean
diff --git a/web/service/plugins.ts b/web/service/plugins.ts
index 3e5d872bf2..999ed4f1b9 100644
--- a/web/service/plugins.ts
+++ b/web/service/plugins.ts
@@ -1,10 +1,6 @@
import type { Fetcher } from 'swr'
import { get, getMarketplace, post, upload } from './base'
import type {
- CreateEndpointRequest,
- EndpointOperationResponse,
- EndpointsRequest,
- EndpointsResponse,
InstallPackageResponse,
Permissions,
PluginDeclaration,
@@ -12,7 +8,6 @@ import type {
PluginTasksResponse,
TaskStatusResponse,
UninstallPluginResponse,
- UpdateEndpointRequest,
uploadGitHubResponse,
} from '@/app/components/plugins/types'
import type {
@@ -20,36 +15,6 @@ import type {
MarketplaceCollectionsResponse,
} from '@/app/components/plugins/marketplace/types'
-export const createEndpoint: Fetcher = ({ url, body }) => {
- // url = /workspaces/current/endpoints/create
- return post(url, { body })
-}
-
-export const fetchEndpointList: Fetcher = ({ url, params }) => {
- // url = /workspaces/current/endpoints/list/plugin?plugin_id=xxx
- return get(url, { params })
-}
-
-export const deleteEndpoint: Fetcher = ({ url, endpointID }) => {
- // url = /workspaces/current/endpoints/delete
- return post(url, { body: { endpoint_id: endpointID } })
-}
-
-export const updateEndpoint: Fetcher = ({ url, body }) => {
- // url = /workspaces/current/endpoints/update
- return post(url, { body })
-}
-
-export const enableEndpoint: Fetcher = ({ url, endpointID }) => {
- // url = /workspaces/current/endpoints/enable
- return post(url, { body: { endpoint_id: endpointID } })
-}
-
-export const disableEndpoint: Fetcher = ({ url, endpointID }) => {
- // url = /workspaces/current/endpoints/disable
- return post(url, { body: { endpoint_id: endpointID } })
-}
-
export const uploadPackageFile = async (file: File) => {
const formData = new FormData()
formData.append('pkg', file)
diff --git a/web/service/use-endpoints.ts b/web/service/use-endpoints.ts
new file mode 100644
index 0000000000..43a82480b9
--- /dev/null
+++ b/web/service/use-endpoints.ts
@@ -0,0 +1,149 @@
+import { get, post } from './base'
+import type {
+ EndpointsResponse,
+} from '@/app/components/plugins/types'
+import {
+ useMutation,
+ useQuery,
+ useQueryClient,
+} from '@tanstack/react-query'
+
+const NAME_SPACE = 'endpoints'
+
+export const useEndpointList = (pluginID: string) => {
+ return useQuery({
+ queryKey: [NAME_SPACE, 'list', pluginID],
+ queryFn: () => get('/workspaces/current/endpoints/list/plugin', {
+ params: {
+ plugin_id: pluginID,
+ page: 1,
+ page_size: 100,
+ },
+ }),
+ })
+}
+
+export const useInvalidateEndpointList = () => {
+ const queryClient = useQueryClient()
+ return (pluginID: string) => {
+ queryClient.invalidateQueries(
+ {
+ queryKey: [NAME_SPACE, 'list', pluginID],
+ })
+ }
+}
+
+export const useCreateEndpoint = ({
+ onSuccess,
+ onError,
+}: {
+ onSuccess?: () => void
+ onError?: (error: any) => void
+}) => {
+ return useMutation({
+ mutationKey: [NAME_SPACE, 'create'],
+ mutationFn: (payload: { pluginUniqueID: string, state: Record }) => {
+ const { pluginUniqueID, state } = payload
+ const newName = state.name
+ delete state.name
+ return post('/workspaces/current/endpoints/create', {
+ body: {
+ plugin_unique_identifier: pluginUniqueID,
+ settings: state,
+ name: newName,
+ },
+ })
+ },
+ onSuccess,
+ onError,
+ })
+}
+
+export const useUpdateEndpoint = ({
+ onSuccess,
+ onError,
+}: {
+ onSuccess?: () => void
+ onError?: (error: any) => void
+}) => {
+ return useMutation({
+ mutationKey: [NAME_SPACE, 'update'],
+ mutationFn: (payload: { endpointID: string, state: Record }) => {
+ const { endpointID, state } = payload
+ const newName = state.name
+ delete state.name
+ return post('/workspaces/current/endpoints/update', {
+ body: {
+ endpoint_id: endpointID,
+ settings: state,
+ name: newName,
+ },
+ })
+ },
+ onSuccess,
+ onError,
+ })
+}
+
+export const useDeleteEndpoint = ({
+ onSuccess,
+ onError,
+}: {
+ onSuccess?: () => void
+ onError?: (error: any) => void
+}) => {
+ return useMutation({
+ mutationKey: [NAME_SPACE, 'delete'],
+ mutationFn: (endpointID: string) => {
+ return post('/workspaces/current/endpoints/delete', {
+ body: {
+ endpoint_id: endpointID,
+ },
+ })
+ },
+ onSuccess,
+ onError,
+ })
+}
+
+export const useEnableEndpoint = ({
+ onSuccess,
+ onError,
+}: {
+ onSuccess?: () => void
+ onError?: (error: any) => void
+}) => {
+ return useMutation({
+ mutationKey: [NAME_SPACE, 'enable'],
+ mutationFn: (endpointID: string) => {
+ return post('/workspaces/current/endpoints/enable', {
+ body: {
+ endpoint_id: endpointID,
+ },
+ })
+ },
+ onSuccess,
+ onError,
+ })
+}
+
+export const useDisableEndpoint = ({
+ onSuccess,
+ onError,
+}: {
+ onSuccess?: () => void
+ onError?: (error: any) => void
+}) => {
+ return useMutation({
+ mutationKey: [NAME_SPACE, 'disable'],
+ mutationFn: (endpointID: string) => {
+ return post('/workspaces/current/endpoints/disable', {
+ body: {
+ endpoint_id: endpointID,
+ },
+ })
+ },
+ onSuccess,
+ onError,
+ })
+}
diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts
index 0d0f816b3e..3c34de3be9 100644
--- a/web/service/use-tools.ts
+++ b/web/service/use-tools.ts
@@ -74,6 +74,7 @@ export const useUpdateProviderCredentials = ({
onSuccess?: () => void
}) => {
return useMutation({
+ mutationKey: [NAME_SPACE, 'update-provider-credentials'],
mutationFn: (payload: { providerName: string, credentials: Record }) => {
const { providerName, credentials } = payload
return post(`/workspaces/current/tool-provider/builtin/${providerName}/update`, {
@@ -92,6 +93,7 @@ export const useRemoveProviderCredentials = ({
onSuccess?: () => void
}) => {
return useMutation({
+ mutationKey: [NAME_SPACE, 'remove-provider-credentials'],
mutationFn: (providerName: string) => {
return post(`/workspaces/current/tool-provider/builtin/${providerName}/delete`, {
body: {},