mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-07-19 22:44:26 +08:00
endpoint form
This commit is contained in:
parent
d2190e9c3a
commit
ebaf8766ef
@ -1,9 +1,10 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useBoolean } from 'ahooks'
|
import { useBoolean } from 'ahooks'
|
||||||
import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react'
|
import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react'
|
||||||
import type { EndpointListItem } from '../types'
|
import type { EndpointListItem } from '../types'
|
||||||
import EndpointModal from './endpoint-modal'
|
import EndpointModal from './endpoint-modal'
|
||||||
|
import { addDefaultValue, toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
|
||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import CopyBtn from '@/app/components/base/copy-btn'
|
import CopyBtn from '@/app/components/base/copy-btn'
|
||||||
import Confirm from '@/app/components/base/confirm'
|
import Confirm from '@/app/components/base/confirm'
|
||||||
@ -86,6 +87,13 @@ const EndpointCard = ({
|
|||||||
setFalse: hideEndpointModalConfirm,
|
setFalse: hideEndpointModalConfirm,
|
||||||
}] = useBoolean(false)
|
}] = useBoolean(false)
|
||||||
|
|
||||||
|
const formSchemas = useMemo(() => {
|
||||||
|
return toolCredentialToFormSchemas(data.declaration.settings)
|
||||||
|
}, [data.declaration.settings])
|
||||||
|
const formValue = useMemo(() => {
|
||||||
|
return addDefaultValue(data.settings, formSchemas)
|
||||||
|
}, [data.settings, formSchemas])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-0.5 bg-background-section-burn rounded-xl'>
|
<div className='p-0.5 bg-background-section-burn rounded-xl'>
|
||||||
<div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'>
|
<div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'>
|
||||||
@ -160,6 +168,9 @@ const EndpointCard = ({
|
|||||||
)}
|
)}
|
||||||
{isShowEndpointModal && (
|
{isShowEndpointModal && (
|
||||||
<EndpointModal
|
<EndpointModal
|
||||||
|
id={data.id}
|
||||||
|
formSchemas={formSchemas}
|
||||||
|
defaultValues={formValue}
|
||||||
onCancel={hideEndpointModalConfirm}
|
onCancel={hideEndpointModalConfirm}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -1,21 +1,36 @@
|
|||||||
import React from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useBoolean } from 'ahooks'
|
||||||
import { RiAddLine } from '@remixicon/react'
|
import { RiAddLine } from '@remixicon/react'
|
||||||
import type { EndpointListItem, PluginEndpointDeclaration } from '../types'
|
import type { EndpointListItem, PluginEndpointDeclaration } from '../types'
|
||||||
|
import EndpointModal from './endpoint-modal'
|
||||||
import EndpointCard from './endpoint-card'
|
import EndpointCard from './endpoint-card'
|
||||||
|
import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
|
||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
pluginUniqueID: string
|
||||||
declaration: PluginEndpointDeclaration
|
declaration: PluginEndpointDeclaration
|
||||||
list: EndpointListItem[]
|
list: EndpointListItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const EndpointList = ({
|
const EndpointList = ({
|
||||||
|
pluginUniqueID,
|
||||||
declaration,
|
declaration,
|
||||||
list,
|
list,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const [isShowEndpointModal, {
|
||||||
|
setTrue: showEndpointModal,
|
||||||
|
setFalse: hideEndpointModal,
|
||||||
|
}] = useBoolean(false)
|
||||||
|
|
||||||
|
const formSchemas = useMemo(() => {
|
||||||
|
return toolCredentialToFormSchemas(declaration.settings)
|
||||||
|
}, [declaration.settings])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='px-4 py-2 border-t border-divider-subtle'>
|
<div className='px-4 py-2 border-t border-divider-subtle'>
|
||||||
<div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'>
|
<div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'>
|
||||||
@ -27,7 +42,7 @@ const EndpointList = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ActionButton>
|
<ActionButton onClick={showEndpointModal}>
|
||||||
<RiAddLine className='w-4 h-4' />
|
<RiAddLine className='w-4 h-4' />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
@ -42,6 +57,13 @@ const EndpointList = ({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
{isShowEndpointModal && (
|
||||||
|
<EndpointModal
|
||||||
|
id={pluginUniqueID}
|
||||||
|
formSchemas={formSchemas}
|
||||||
|
onCancel={hideEndpointModal}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,27 +2,33 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import Drawer from '@/app/components/base/drawer'
|
import { RiArrowRightUpLine, RiCloseLine } from '@remixicon/react'
|
||||||
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
|
import Drawer from '@/app/components/base/drawer'
|
||||||
|
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
|
||||||
// import Toast from '@/app/components/base/toast'
|
// import Toast from '@/app/components/base/toast'
|
||||||
// import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
|
|
||||||
// import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
|
|
||||||
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
id: string
|
||||||
|
formSchemas: any
|
||||||
|
defaultValues?: any
|
||||||
onCancel: () => void
|
onCancel: () => void
|
||||||
// onSaved: (value: Record<string, any>) => void
|
// onSaved: (value: Record<string, any>) => void
|
||||||
onRemove?: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EndpointModal: FC<Props> = ({
|
const EndpointModal: FC<Props> = ({
|
||||||
|
id,
|
||||||
|
formSchemas,
|
||||||
|
defaultValues = {},
|
||||||
onCancel,
|
onCancel,
|
||||||
// onSaved,
|
// onSaved,
|
||||||
onRemove = () => { },
|
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
|
const [tempCredential, setTempCredential] = React.useState<any>(defaultValues)
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// for (const field of credentialSchema) {
|
// for (const field of credentialSchema) {
|
||||||
@ -45,12 +51,23 @@ const EndpointModal: FC<Props> = ({
|
|||||||
panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
|
panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
{/* <Form
|
<div className='p-4 pb-2'>
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='text-text-primary system-xl-semibold'>{t('plugin.detailPanel.endpointModalTitle')}</div>
|
||||||
|
<ActionButton onClick={onCancel}>
|
||||||
|
<RiCloseLine className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
<div className='mt-0.5 text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointModalDesc')}</div>
|
||||||
|
</div>
|
||||||
|
<div className='grow overflow-y-auto'>
|
||||||
|
<div className='px-4 py-2'>
|
||||||
|
<Form
|
||||||
value={tempCredential}
|
value={tempCredential}
|
||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
setTempCredential(v)
|
setTempCredential(v)
|
||||||
}}
|
}}
|
||||||
formSchemas={credentialSchema}
|
formSchemas={formSchemas}
|
||||||
isEditMode={true}
|
isEditMode={true}
|
||||||
showOnVariableMap={{}}
|
showOnVariableMap={{}}
|
||||||
validating={false}
|
validating={false}
|
||||||
@ -59,19 +76,21 @@ const EndpointModal: FC<Props> = ({
|
|||||||
? (<a
|
? (<a
|
||||||
href={item.url}
|
href={item.url}
|
||||||
target='_blank' rel='noopener noreferrer'
|
target='_blank' rel='noopener noreferrer'
|
||||||
className='inline-flex items-center text-xs text-primary-600'
|
className='inline-flex items-center body-xs-regular text-text-accent-secondary'
|
||||||
>
|
>
|
||||||
{t('tools.howToGet')}
|
{t('tools.howToGet')}
|
||||||
<LinkExternal02 className='ml-1 w-3 h-3' />
|
<RiArrowRightUpLine className='ml-1 w-3 h-3' />
|
||||||
</a>)
|
</a>)
|
||||||
: null}
|
: null}
|
||||||
/> */}
|
/>
|
||||||
<div className={cn('mt-2 flex justify-end')} >
|
</div>
|
||||||
< div className='flex space-x-2'>
|
<div className={cn('p-4 pt-0 flex justify-end')} >
|
||||||
|
<div className='flex gap-2'>
|
||||||
<Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
|
<Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
|
||||||
<Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
|
<Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
)
|
)
|
||||||
|
@ -48,6 +48,7 @@ const PluginDetailPanel: FC<Props> = ({
|
|||||||
<div className='grow overflow-y-auto'>
|
<div className='grow overflow-y-auto'>
|
||||||
{!!pluginDetail.declaration.endpoint && (
|
{!!pluginDetail.declaration.endpoint && (
|
||||||
<EndpointList
|
<EndpointList
|
||||||
|
pluginUniqueID={pluginDetail.plugin_unique_identifier}
|
||||||
list={endpointList}
|
list={endpointList}
|
||||||
declaration={pluginDetail.declaration.endpoint}
|
declaration={pluginDetail.declaration.endpoint}
|
||||||
/>
|
/>
|
||||||
|
@ -33,14 +33,14 @@ export const toolNotion = {
|
|||||||
default: null,
|
default: null,
|
||||||
options: null,
|
options: null,
|
||||||
label: {
|
label: {
|
||||||
'en-US': 'API-key',
|
en_US: 'API-key',
|
||||||
'zh-Hans': 'API-key',
|
zh_Hans: 'API-key',
|
||||||
},
|
},
|
||||||
help: null,
|
help: null,
|
||||||
url: null,
|
url: null,
|
||||||
placeholder: {
|
placeholder: {
|
||||||
'en-US': 'Please input your API key',
|
en_US: 'Please input your API key',
|
||||||
'zh-Hans': '请输入你的 API key',
|
zh_Hans: '请输入你的 API key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -81,14 +81,14 @@ export const toolNotionEndpoints = [
|
|||||||
default: null,
|
default: null,
|
||||||
options: null,
|
options: null,
|
||||||
label: {
|
label: {
|
||||||
'en-US': 'API-key',
|
en_US: 'API-key',
|
||||||
'zh-Hans': 'API-key',
|
zh_Hans: 'API-key',
|
||||||
},
|
},
|
||||||
help: null,
|
help: null,
|
||||||
url: null,
|
url: null,
|
||||||
placeholder: {
|
placeholder: {
|
||||||
'en-US': 'Please input your API key',
|
en_US: 'Please input your API key',
|
||||||
'zh-Hans': '请输入你的 API key',
|
zh_Hans: '请输入你的 API key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { CredentialFormSchemaBase } from '../header/account-setting/model-provider-page/declarations'
|
import type { CredentialFormSchemaBase } from '../header/account-setting/model-provider-page/declarations'
|
||||||
|
import type { ToolCredential } from '@/app/components/tools/types'
|
||||||
import type { Locale } from '@/i18n'
|
import type { Locale } from '@/i18n'
|
||||||
|
|
||||||
export enum PluginType {
|
export enum PluginType {
|
||||||
@ -23,11 +24,11 @@ export type PluginToolDeclaration = {
|
|||||||
label: Record<Locale, string>
|
label: Record<Locale, string>
|
||||||
tags: string[]
|
tags: string[]
|
||||||
}
|
}
|
||||||
credentials_schema: CredentialFormSchemaBase[] // TODO
|
credentials_schema: ToolCredential[] // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PluginEndpointDeclaration = {
|
export type PluginEndpointDeclaration = {
|
||||||
settings: CredentialFormSchemaBase[]
|
settings: ToolCredential[]
|
||||||
endpoints: EndpointItem[]
|
endpoints: EndpointItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ const translation = {
|
|||||||
endpointDisableContent: 'Would you like to disable {{name}}? ',
|
endpointDisableContent: 'Would you like to disable {{name}}? ',
|
||||||
endpointDeleteTip: 'Remove Endpoint',
|
endpointDeleteTip: 'Remove Endpoint',
|
||||||
endpointDeleteContent: 'Would you like to remove {{name}}? ',
|
endpointDeleteContent: 'Would you like to remove {{name}}? ',
|
||||||
|
endpointModalTitle: 'Setup endpoint',
|
||||||
|
endpointModalDesc: 'After configuring form, all members within the workspace can use this endpoint when orchestrating applications.',
|
||||||
serviceOk: 'Service OK',
|
serviceOk: 'Service OK',
|
||||||
disabled: 'Disabled',
|
disabled: 'Disabled',
|
||||||
modelNum: '{{num}} MODELS INCLUDED',
|
modelNum: '{{num}} MODELS INCLUDED',
|
||||||
|
@ -25,6 +25,8 @@ const translation = {
|
|||||||
endpointDisableContent: '是否要停用 {{name}} 的 Endpoint ?',
|
endpointDisableContent: '是否要停用 {{name}} 的 Endpoint ?',
|
||||||
endpointDeleteTip: '移除 Endpoint',
|
endpointDeleteTip: '移除 Endpoint',
|
||||||
endpointDeleteContent: '是否要移除 {{name}} ?',
|
endpointDeleteContent: '是否要移除 {{name}} ?',
|
||||||
|
endpointModalTitle: '设置 Endpoint',
|
||||||
|
endpointModalDesc: '配置表单后,工作区内的所有成员都可以在编排应用时使用此端点。',
|
||||||
serviceOk: '服务正常',
|
serviceOk: '服务正常',
|
||||||
disabled: '停用',
|
disabled: '停用',
|
||||||
modelNum: '{{num}} 模型已包含',
|
modelNum: '{{num}} 模型已包含',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user