endpoints data binding

This commit is contained in:
JzoNg 2024-10-19 14:18:51 +08:00
parent 64067e1f20
commit 5e077e4ce8
6 changed files with 126 additions and 71 deletions

View File

@ -0,0 +1,60 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { RiLoginCircleLine } from '@remixicon/react'
import CopyBtn from '@/app/components/base/copy-btn'
import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
const EndpointCard = () => {
const { t } = useTranslation()
return (
<div className='p-0.5 bg-background-section-burn rounded-xl'>
<div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'>
<div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'>
<RiLoginCircleLine className='w-4 h-4' />
<div>Endpoint for Unreal workspace</div>
</div>
<div className='h-6 flex items-center'>
<div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div>
<div className='group grow flex items-center text-text-secondary system-xs-regular truncate'>
<div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div>
<CopyBtn
className='hidden shrink-0 ml-2 group-hover:block'
value={'https://extension.dify.ai/a1b2c3d4/onStart'}
isPlain
/>
</div>
</div>
<div className='h-6 flex items-center'>
<div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div>
<div className='group grow flex items-center text-text-secondary system-xs-regular truncate'>
<div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div>
<CopyBtn
className='hidden shrink-0 ml-2 group-hover:block'
value={'https://extension.dify.ai/a1b2c3d4/onFinish'}
isPlain
/>
</div>
</div>
</div>
<div className='px-3 py-2 flex items-center justify-between'>
<div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'>
<Indicator color='green' />
{t('plugin.detailPanel.serviceOk')}
</div>
{/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'>
<Indicator color='gray' />
{t('plugin.detailPanel.disabled')}
</div> */}
<Switch
className='ml-3'
defaultValue={true}
onChange={() => {}}
size='sm'
/>
</div>
</div>
)
}
export default EndpointCard

View File

@ -1,65 +1,19 @@
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { RiAddLine, RiLoginCircleLine } from '@remixicon/react' import { RiAddLine } from '@remixicon/react'
import EndpointCard from './endpoint-card'
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 Indicator from '@/app/components/header/indicator'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import Switch from '@/app/components/base/switch'
const EndpointCard = () => { type Props = {
const { t } = useTranslation() declaration: any
return ( list: any[]
<div className='p-0.5 bg-background-section-burn rounded-xl'>
<div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'>
<div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'>
<RiLoginCircleLine className='w-4 h-4' />
<div>Endpoint for Unreal workspace</div>
</div>
<div className='h-6 flex items-center'>
<div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div>
<div className='group grow flex items-center text-text-secondary system-xs-regular truncate'>
<div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div>
<CopyBtn
className='hidden shrink-0 ml-2 group-hover:block'
value={'https://extension.dify.ai/a1b2c3d4/onStart'}
isPlain
/>
</div>
</div>
<div className='h-6 flex items-center'>
<div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div>
<div className='group grow flex items-center text-text-secondary system-xs-regular truncate'>
<div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div>
<CopyBtn
className='hidden shrink-0 ml-2 group-hover:block'
value={'https://extension.dify.ai/a1b2c3d4/onFinish'}
isPlain
/>
</div>
</div>
</div>
<div className='px-3 py-2 flex items-center justify-between'>
<div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'>
<Indicator color='green' />
{t('plugin.detailPanel.serviceOk')}
</div>
{/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'>
<Indicator color='gray' />
{t('plugin.detailPanel.disabled')}
</div> */}
<Switch
className='ml-3'
defaultValue={true}
onChange={() => {}}
size='sm'
/>
</div>
</div>
)
} }
const EndpointList = () => { const EndpointList = ({
declaration,
list,
}: Props) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<div className='px-4 py-2 border-t border-divider-subtle'> <div className='px-4 py-2 border-t border-divider-subtle'>
@ -80,11 +34,13 @@ const EndpointList = () => {
<RiAddLine className='w-4 h-4' /> <RiAddLine className='w-4 h-4' />
</ActionButton> </ActionButton>
</div> </div>
{list.length === 0 && (
<div className='mb-1 p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointsEmpty')}</div> <div className='mb-1 p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointsEmpty')}</div>
)}
<div className='flex flex-col gap-2'> <div className='flex flex-col gap-2'>
<EndpointCard /> {list.map((item, index) => (
<EndpointCard /> <EndpointCard key={index} />
<EndpointCard /> ))}
</div> </div>
</div> </div>
) )

View File

@ -2,7 +2,7 @@
import React from 'react' import React from 'react'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import type { PluginDetail } from '../types' import type { EndpointListItem, PluginDetail } from '../types'
import DetailHeader from './detail-header' import DetailHeader from './detail-header'
import EndpointList from './endpoint-list' import EndpointList from './endpoint-list'
import ActionList from './action-list' import ActionList from './action-list'
@ -13,11 +13,13 @@ import cn from '@/utils/classnames'
type Props = { type Props = {
pluginDetail: PluginDetail | undefined pluginDetail: PluginDetail | undefined
endpointList: EndpointListItem[]
onHide: () => void onHide: () => void
} }
const PluginDetailPanel: FC<Props> = ({ const PluginDetailPanel: FC<Props> = ({
pluginDetail, pluginDetail,
endpointList = [],
onHide, onHide,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
@ -46,9 +48,14 @@ const PluginDetailPanel: FC<Props> = ({
onDelete={handleDelete} onDelete={handleDelete}
/> />
<div className='grow overflow-y-auto'> <div className='grow overflow-y-auto'>
<ActionList /> {!!pluginDetail.declaration.endpoint && (
<EndpointList /> <EndpointList
<ModelList /> list={endpointList}
declaration={pluginDetail.declaration.endpoint}
/>
)}
{!!pluginDetail.declaration.tool && <ActionList />}
{!!pluginDetail.declaration.model && <ModelList />}
</div> </div>
</> </>
)} )}

View File

@ -24,7 +24,32 @@ export const toolNotion = {
created_at: '2024-10-16 16:05:33', created_at: '2024-10-16 16:05:33',
resource: {}, resource: {},
plugins: {}, plugins: {},
tool: {}, // TODO 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, verified: true,
}, },
installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg', installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg',
@ -67,7 +92,7 @@ export const toolNotionEndpoints = [
}, },
}, },
], ],
endpoint: [ endpoints: [
{ path: '/duck/<app_id>', method: 'GET' }, { path: '/duck/<app_id>', method: 'GET' },
{ path: '/neko', method: 'GET' }, { path: '/neko', method: 'GET' },
], ],

View File

@ -1,12 +1,11 @@
'use client' 'use client'
import { useState } from 'react' import { useState } from 'react'
import type { PluginDetail } from '../types' import type { EndpointListItem, PluginDetail } from '../types'
import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel'
import { toolNotion } from '@/app/components/plugins/plugin-detail-panel/mock'
import type { FilterState } from './filter-management' import type { FilterState } from './filter-management'
import FilterManagement from './filter-management' import FilterManagement from './filter-management'
import List from './list' import List from './list'
import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel'
import { toolNotion, toolNotionEndpoints } from '@/app/components/plugins/plugin-detail-panel/mock'
const PluginsPanel = () => { const PluginsPanel = () => {
const handleFilterChange = (filters: FilterState) => { const handleFilterChange = (filters: FilterState) => {
@ -14,6 +13,7 @@ const PluginsPanel = () => {
} }
const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>(toolNotion as any) const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>(toolNotion as any)
const [currentPluginEndpoints, setCurrentEndpoints] = useState<EndpointListItem[]>(toolNotionEndpoints as any)
return ( return (
<> <>
<div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'>
@ -27,7 +27,14 @@ const PluginsPanel = () => {
<List /> <List />
</div> </div>
</div> </div>
<PluginDetailPanel pluginDetail={currentPluginDetail} onHide={() => setCurrentPluginDetail(undefined)} /> <PluginDetailPanel
pluginDetail={currentPluginDetail}
endpointList={currentPluginEndpoints}
onHide={() => {
setCurrentPluginDetail(undefined)
setCurrentEndpoints([])
}}
/>
</> </>
) )
} }

View File

@ -63,8 +63,8 @@ export type PluginDeclaration = {
resource: any // useless in frontend resource: any // useless in frontend
plugins: any // useless in frontend plugins: any // useless in frontend
verified: boolean verified: boolean
tool: PluginToolDeclaration
endpoint: PluginEndpointDeclaration endpoint: PluginEndpointDeclaration
tool: PluginToolDeclaration
model: any // TODO model: any // TODO
} }