endpoint form

This commit is contained in:
JzoNg 2024-10-19 17:23:26 +08:00
parent d2190e9c3a
commit ebaf8766ef
8 changed files with 101 additions and 43 deletions

View File

@ -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}
/> />
)} )}

View File

@ -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>
) )
} }

View File

@ -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>
) )

View File

@ -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}
/> />

View File

@ -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',
}, },
}, },
], ],

View File

@ -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[]
} }

View File

@ -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',

View File

@ -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}} 模型已包含',