plugin detail header data binding

This commit is contained in:
JzoNg 2024-10-16 17:30:51 +08:00
parent 7c5c35600c
commit 10190a9aa5
6 changed files with 125 additions and 24 deletions

View File

@ -3,19 +3,26 @@ import React, { useMemo } from 'react'
import type { FC } from 'react' import type { FC } from 'react'
import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' import {
import type { Plugin } from '../types' RiBugLine,
// import { PluginType } from '../types' RiCloseLine,
import Badge from '../../base/badge' RiHardDrive3Line,
import Description from '../card/base/description' // RiVerifiedBadgeLine,
} from '@remixicon/react'
import type { PluginDetail } from '../types'
import { PluginSource } from '../types'
// import Description from '../card/base/description'
import Icon from '../card/base/card-icon' import Icon from '../card/base/card-icon'
import Title from '../card/base/title' import Title from '../card/base/title'
import OrgInfo from '../card/base/org-info'
import OperationDropdown from './operation-dropdown' import OperationDropdown from './operation-dropdown'
import EndpointList from './endpoint-list' import EndpointList from './endpoint-list'
import ActionList from './action-list' import ActionList from './action-list'
import ModelList from './model-list' import ModelList from './model-list'
// import type { Locale } from '@/i18n' import Badge from '@/app/components/base/badge'
import Tooltip from '@/app/components/base/tooltip'
import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin'
import { Github } from '@/app/components/base/icons/src/public/common'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import ActionButton from '@/app/components/base/action-button' import ActionButton from '@/app/components/base/action-button'
import Drawer from '@/app/components/base/drawer' import Drawer from '@/app/components/base/drawer'
@ -24,7 +31,7 @@ import I18n from '@/context/i18n'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
type Props = { type Props = {
pluginDetail: Plugin | undefined pluginDetail: PluginDetail | undefined
onHide: () => void onHide: () => void
} }
@ -38,7 +45,8 @@ const PluginDetailPanel: FC<Props> = ({
const hasNewVersion = useMemo(() => { const hasNewVersion = useMemo(() => {
if (!pluginDetail) if (!pluginDetail)
return false return false
return pluginDetail.latest_version !== pluginDetail.version return false // TODO
// return pluginDetail.latest_version !== pluginDetail.version
}, [pluginDetail]) }, [pluginDetail])
const handleUpdate = () => {} const handleUpdate = () => {}
@ -61,11 +69,11 @@ const PluginDetailPanel: FC<Props> = ({
<> <>
<div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}>
<div className="flex"> <div className="flex">
<Icon src={pluginDetail.icon} /> <Icon src={pluginDetail.declaration.icon} />
<div className="ml-3 w-0 grow"> <div className="ml-3 w-0 grow">
<div className="flex items-center h-5"> <div className="flex items-center h-5">
<Title title={pluginDetail.label[locale]} /> <Title title={pluginDetail.declaration.label[locale]} />
<RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> {/* <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> */}
<Badge <Badge
className='mx-1' className='mx-1'
text={pluginDetail.version} text={pluginDetail.version}
@ -77,9 +85,33 @@ const PluginDetailPanel: FC<Props> = ({
</div> </div>
<div className='mb-1 flex justify-between items-center h-4'> <div className='mb-1 flex justify-between items-center h-4'>
<div className='flex items-center'> <div className='flex items-center'>
<div className='text-text-tertiary system-xs-regular'>{pluginDetail.org}</div> <OrgInfo
<div className='ml-1 text-text-quaternary system-xs-regular'>·</div> className="mt-0.5"
<BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary' /> packageNameClassName='w-auto'
orgName={pluginDetail.declaration.author}
packageName={pluginDetail.declaration.name}
/>
<div className='ml-1 mr-0.5 text-text-quaternary system-xs-regular'>·</div>
{pluginDetail.source === PluginSource.marketplace && (
<Tooltip popupContent={t('plugin.detailPanel.categoryTip.marketplace')} >
<BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary hover:text-text-accent' />
</Tooltip>
)}
{pluginDetail.source === PluginSource.github && (
<Tooltip popupContent={t('plugin.detailPanel.categoryTip.github')} >
<Github className='w-3.5 h-3.5 text-text-secondary hover:text-text-primary' />
</Tooltip>
)}
{pluginDetail.source === PluginSource.local && (
<Tooltip popupContent={t('plugin.detailPanel.categoryTip.local')} >
<RiHardDrive3Line className='w-3.5 h-3.5 text-text-tertiary' />
</Tooltip>
)}
{pluginDetail.source === PluginSource.debugging && (
<Tooltip popupContent={t('plugin.detailPanel.categoryTip.debugging')} >
<RiBugLine className='w-3.5 h-3.5 text-text-tertiary hover:text-text-warning' />
</Tooltip>
)}
</div> </div>
</div> </div>
</div> </div>
@ -90,7 +122,8 @@ const PluginDetailPanel: FC<Props> = ({
</ActionButton> </ActionButton>
</div> </div>
</div> </div>
<Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> {/* category === extension TODO */}
{/* <Description className='mt-3' text={pluginDetail.declaration.brief[locale]} descriptionLineRows={2}></Description> */}
</div> </div>
<div className='grow overflow-y-auto'> <div className='grow overflow-y-auto'>
<ActionList /> <ActionList />

View File

@ -0,0 +1,36 @@
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 页面搜索',
},
brief: {
'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: {},
tool: {}, // TODO
},
installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg',
tenant_id: 'jflkdsjoewingljlsadjgoijg',
endpoints_setups: 2,
endpoints_active: 1,
version: '1.2.0',
source: PluginSource.marketplace,
meta: null,
}

View File

@ -1,12 +1,8 @@
'use client' 'use client'
import { useState } from 'react' import { useState } from 'react'
import type { Plugin } from '../types' import type { PluginDetail } from '../types'
import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel'
import { import { toolNotion } from '@/app/components/plugins/plugin-detail-panel/mock'
// extensionDallE,
// modelGPT4,
toolNotion,
} from '@/app/components/plugins/card/card-mock'
import type { FilterState } from './filter-management' import type { FilterState } from './filter-management'
import FilterManagement from './filter-management' import FilterManagement from './filter-management'
@ -17,7 +13,7 @@ const PluginsPanel = () => {
// //
} }
const [currentPluginDetail, setCurrentPluginDetail] = useState<Plugin | undefined>(toolNotion as any) const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>(toolNotion 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'>

View File

@ -14,17 +14,41 @@ export enum PluginSource {
debugging = 'remote', debugging = 'remote',
} }
export type PluginToolDeclaration = {
identity: {
author: string
name: string
description: Record<Locale, string>
icon: string
label: Record<Locale, string>
tags: string[]
}
credentials_schema: CredentialFormSchemaBase[] // TODO
}
export type PluginEndpointDeclaration = {
settings: CredentialFormSchemaBase[]
endpoint: EndpointItem[]
}
export type EndpointItem = {
path: string
method: string
}
export type PluginDeclaration = { export type PluginDeclaration = {
version: string version: string
author: string author: string
icon: string icon: string
name: string name: string
category: PluginType
label: Record<Locale, string> label: Record<Locale, string>
brief: Record<Locale, string>
created_at: string created_at: string
resource: any // useless in frontend resource: any // useless in frontend
plugins: any // useless in frontend plugins: any // useless in frontend
tool: any // TODO tool: PluginToolDeclaration
endpoint: any // TODO endpoint: PluginEndpointDeclaration
model: any // TODO model: any // TODO
} }

View File

@ -3,6 +3,12 @@ const translation = {
fromMarketplace: 'From Marketplace', fromMarketplace: 'From Marketplace',
endpointsEnabled: '{{num}} sets of endpoints enabled', endpointsEnabled: '{{num}} sets of endpoints enabled',
detailPanel: { detailPanel: {
categoryTip: {
marketplace: 'Installed from Marketplace',
github: 'Installed from Github',
local: 'Local Plugin',
debugging: 'Debugging Plugin',
},
operation: { operation: {
install: 'Install', install: 'Install',
detail: 'Detail', detail: 'Detail',

View File

@ -3,6 +3,12 @@ const translation = {
fromMarketplace: '来自市场', fromMarketplace: '来自市场',
endpointsEnabled: '{{num}} 组端点已启用', endpointsEnabled: '{{num}} 组端点已启用',
detailPanel: { detailPanel: {
categoryTip: {
marketplace: '从 Marketplace 安装',
github: '从 Github 安装',
local: '本地插件',
debugging: '调试插件',
},
operation: { operation: {
install: '安装', install: '安装',
detail: '详情', detail: '详情',