/* * @Author: ZhaoYing * @Date: 2026-02-03 16:50:14 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-25 12:19:24 */ /** * Model Square View * Displays public model marketplace grouped by provider * Allows adding models and viewing details */ import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import { Button, Space, App, Flex, Tooltip } from 'antd' import { UsergroupAddOutlined } from '@ant-design/icons'; import { useTranslation } from 'react-i18next'; import clsx from 'clsx'; import type { ModelPlaza, ModelPlazaItem, BaseRef } from './types' import RbCard from '@/components/RbCard' import { getModelPlaza, addModelPlaza } from '@/api/models' import PageEmpty from '@/components/Empty/PageEmpty'; import Tag from '@/components/Tag'; import { getLogoUrl } from './utils' /** * Model square component */ const ModelSquare = forwardRef (({ query }, ref) => { const { t } = useTranslation(); const { message } = App.useApp() const [list, setList] = useState([]) useEffect(() => { getList() }, [query]) /** Fetch model plaza list */ const getList = () => { getModelPlaza(query) .then(res => { const response = res as ModelPlaza[] setList(response || []) if (!activeProvider) { setActiveProvider(response[0]?.provider || null) } }) } /** Add model to workspace */ const handleAdd = (item: ModelPlazaItem) => { addModelPlaza(item.id) .then(() => { message.success(`${item.name}${t('modelNew.addSuccess')}`) getList() }) } /** Expose methods to parent component */ useImperativeHandle(ref, () => ({ getList, })); const [activeProvider, setActiveProvider] = useState(null) return ( <> {list.length === 0 ? : <> {list.map(vo => (
setActiveProvider(vo.provider)} >{String(vo.provider).charAt(0).toUpperCase() + String(vo.provider).slice(1)}
))}
{list.filter(vo => vo.provider === activeProvider).map(vo => (
{vo.models.map(item => (
{item.name}
{t(`modelNew.${item.type}`)} {item.is_official && {t(`modelNew.official`)}}
} isNeedTooltip={false} footer={ @{String(item.provider).charAt(0).toUpperCase() + String(item.provider).slice(1)} {item.add_count} } >
{item.description}
{item.tags?.slice(0, 2).map((type, i) => (
{type}
))}
{item.tags.length > 2 && ( {item.tags?.slice(2, item.tags.length).map((type, i) => (
{type}
))}
} color="white" placement="bottom" >
+{item.tags.length - 2}
)}
))}
))} } ) }) export default ModelSquare