mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 11:42:29 +08:00
endpoints api
This commit is contained in:
parent
f498686c3a
commit
f70c23dd7a
|
@ -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') })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 (
|
||||
<div className='px-4 py-2 border-t border-divider-subtle'>
|
||||
<div className={cn('px-4 py-2 border-divider-subtle', showTopBorder && 'border-t')}>
|
||||
<div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'>
|
||||
<div className='flex items-center gap-0.5'>
|
||||
{t('plugin.detailPanel.endpoints')}
|
||||
|
@ -81,6 +92,7 @@ const EndpointList = () => {
|
|||
<EndpointCard
|
||||
key={index}
|
||||
data={item}
|
||||
handleChange={mutate}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -42,8 +42,8 @@ const PluginDetailPanel: FC<Props> = ({
|
|||
onDelete={onDelete}
|
||||
/>
|
||||
<div className='grow overflow-y-auto'>
|
||||
{!!pluginDetail.declaration.endpoint && <EndpointList />}
|
||||
{!!pluginDetail.declaration.tool && <ActionList />}
|
||||
{!!pluginDetail.declaration.endpoint && <EndpointList showTopBorder={!!pluginDetail.declaration.tool} />}
|
||||
{!!pluginDetail.declaration.model && <ModelList />}
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -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/<app_id>', 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/<app_id>', method: 'GET' },
|
||||
{ path: '/neko', method: 'GET' },
|
||||
],
|
||||
},
|
||||
name: 'default',
|
||||
enabled: true,
|
||||
url: 'http://localhost:5002/e/45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8',
|
||||
hook_id: '45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8',
|
||||
},
|
||||
]
|
21
web/app/components/plugins/plugin-detail-panel/utils.ts
Normal file
21
web/app/components/plugins/plugin-detail-panel/utils.ts
Normal file
|
@ -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,
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<EndpointsResponse, { url: string; params
|
|||
|
||||
export const deleteEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => {
|
||||
// url = /workspaces/current/endpoints/delete
|
||||
return del<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } })
|
||||
return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } })
|
||||
}
|
||||
|
||||
export const updateEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: UpdateEndpointRequest }> = ({ url, body }) => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user