feat: basic app requirements

This commit is contained in:
Joel 2025-10-24 17:29:42 +08:00
parent a7f2849e74
commit 3bf9d898c0
3 changed files with 73 additions and 13 deletions

View File

@ -8,8 +8,10 @@ import type { TryAppInfo } from '@/service/try-app'
import cn from '@/utils/classnames'
import Button from '@/app/components/base/button'
import { RiAddLine } from '@remixicon/react'
import useGetRequirements from './use-get-requirements'
type Props = {
appId: string
appDetail: TryAppInfo
category?: string
className?: string
@ -19,6 +21,7 @@ type Props = {
const headerClassName = 'system-sm-semibold-uppercase text-text-secondary mb-3'
const AppInfo: FC<Props> = ({
appId,
className,
category,
appDetail,
@ -26,6 +29,7 @@ const AppInfo: FC<Props> = ({
}) => {
const { t } = useTranslation()
const mode = appDetail?.mode
const { requirements } = useGetRequirements({ appDetail, appId })
return (
<div className={cn('flex h-full flex-col px-4 pt-2', className)}>
{/* name and icon */}
@ -68,20 +72,20 @@ const AppInfo: FC<Props> = ({
<div className='system-md-regular text-text-secondary'>{category}</div>
</div>
)}
<div className='mt-5 grow overflow-y-auto'>
<div className={headerClassName}>{t('explore.tryApp.requirements')}</div>
<div className='space-y-0.5'>
<div className='flex items-center space-x-2 py-1'>
<div className='size-5 rounded-md bg-gray-200 shadow-xs'></div>
<div className='system-md-regular w-0 grow truncate text-text-secondary'>LLM Vision supported</div>
</div>
<div className='flex items-center space-x-2 py-1'>
<div className='size-5 rounded-md bg-gray-200 shadow-xs'></div>
<div className='system-md-regular w-0 grow truncate text-text-secondary'>xxx</div>
{requirements.length > 0 && (
<div className='mt-5 grow overflow-y-auto'>
<div className={headerClassName}>{t('explore.tryApp.requirements')}</div>
<div className='space-y-0.5'>
{requirements.map(item => (
<div className='flex items-center space-x-2 py-1'>
<div className='size-5 rounded-md bg-cover shadow-xs' style={{ backgroundImage: `url(${item.iconUrl})` }} />
<div className='system-md-regular w-0 grow truncate text-text-secondary'>{item.name}</div>
</div>
))}
</div>
</div>
</div>
)}
</div>
)
}

View File

@ -0,0 +1,50 @@
import { MARKETPLACE_API_PREFIX } from '@/config'
import type { TryAppInfo } from '@/service/try-app'
import type { AgentTool } from '@/types/app'
import { uniqBy } from 'lodash-es'
type Params = {
appDetail: TryAppInfo
appId: string
}
type RequirementItem = {
name: string
iconUrl: string
}
const getIconUrl = (provider: string, tool: string) => {
return `${MARKETPLACE_API_PREFIX}/plugins/${provider}/${tool}/icon`
}
const useGetRequirements = ({ appDetail, appId }: Params) => {
const isBasic = ['chat', 'completion', 'agent-chat'].includes(appDetail.mode)
const isAgent = appDetail.mode === 'agent-chat'
const requirements: RequirementItem[] = []
if(isBasic) {
const modelProviderAndName = appDetail.model_config.model.provider.split('/')
const name = appDetail.model_config.model.provider.split('/').pop() || ''
requirements.push({
name,
iconUrl: getIconUrl(modelProviderAndName[0], modelProviderAndName[1]),
})
}
if(isAgent) {
requirements.push(...appDetail.model_config.agent_mode.tools.filter(data => (data as AgentTool).enabled).map((data) => {
const tool = data as AgentTool
const modelProviderAndName = tool.provider_id.split('/')
return {
name: tool.tool_label,
iconUrl: getIconUrl(modelProviderAndName[0], modelProviderAndName[1]),
}
}))
}
const uniqueRequirements = uniqBy(requirements, 'name')
return {
requirements: uniqueRequirements,
}
}
export default useGetRequirements

View File

@ -54,7 +54,13 @@ const TryApp: FC<Props> = ({
{/* Main content */}
<div className='mt-2 flex h-0 grow justify-between space-x-2'>
{type === TypeEnum.TRY ? <App appId={appId} appDetail={appDetail!} /> : <Preview appId={appId} appDetail={appDetail!} />}
<AppInfo className='w-[360px] shrink-0' appDetail={appDetail!} category={category} onCreate={onCreate} />
<AppInfo
className='w-[360px] shrink-0'
appDetail={appDetail!}
appId={appId}
category={category}
onCreate={onCreate}
/>
</div>
</div>
)}