useQuery for endpoints

This commit is contained in:
JzoNg 2024-11-09 14:44:48 +08:00
parent 1e62768eed
commit 5e81150b22
6 changed files with 212 additions and 140 deletions

View File

@ -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 (
<div className='p-0.5 bg-background-section-burn rounded-xl'>
@ -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={<div>{t('plugin.detailPanel.endpointDeleteContent', { name: data.name })}</div>}
onCancel={hideDeleteConfirm}
onConfirm={handleDelete}
onConfirm={() => deleteEndpoint(endpointID)}
/>
)}
{isShowEndpointModal && (

View File

@ -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) => {
<EndpointCard
key={index}
data={item}
handleChange={mutate}
handleChange={() => invalidateEndpointList(pluginDetail.plugin_id)}
/>
))}
</div>

View File

@ -194,19 +194,10 @@ export type GitHubUrlInfo = {
}
// endpoint
export type CreateEndpointRequest = {
plugin_unique_identifier: string
settings: Record<string, any>
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

View File

@ -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<EndpointOperationResponse, { url: string; body: CreateEndpointRequest }> = ({ url, body }) => {
// url = /workspaces/current/endpoints/create
return post<EndpointOperationResponse>(url, { body })
}
export const fetchEndpointList: Fetcher<EndpointsResponse, { url: string; params?: EndpointsRequest }> = ({ url, params }) => {
// url = /workspaces/current/endpoints/list/plugin?plugin_id=xxx
return get<EndpointsResponse>(url, { params })
}
export const deleteEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => {
// url = /workspaces/current/endpoints/delete
return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } })
}
export const updateEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: UpdateEndpointRequest }> = ({ url, body }) => {
// url = /workspaces/current/endpoints/update
return post<EndpointOperationResponse>(url, { body })
}
export const enableEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => {
// url = /workspaces/current/endpoints/enable
return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } })
}
export const disableEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => {
// url = /workspaces/current/endpoints/disable
return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } })
}
export const uploadPackageFile = async (file: File) => {
const formData = new FormData()
formData.append('pkg', file)

View File

@ -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<EndpointsResponse>('/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<string, any> }) => {
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<string, any> }) => {
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,
})
}

View File

@ -74,6 +74,7 @@ export const useUpdateProviderCredentials = ({
onSuccess?: () => void
}) => {
return useMutation({
mutationKey: [NAME_SPACE, 'update-provider-credentials'],
mutationFn: (payload: { providerName: string, credentials: Record<string, any> }) => {
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: {},