Files
MemoryBear/web/src/views/ModelManagement/index.tsx
2026-03-23 11:37:04 +08:00

152 lines
5.0 KiB
TypeScript

/*
* @Author: ZhaoYing
* @Date: 2026-02-03 16:50:05
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-03-20 19:02:31
*/
/**
* Model Management Main Page
* Manages AI models with three views: group models, model list, and model square
* Supports filtering, searching, and CRUD operations
*/
import { useState, useRef, type FC } from 'react';
import { Button, Flex, Space, type SegmentedProps, Form } from 'antd'
import { useTranslation } from 'react-i18next';
import GroupModelModal from './components/GroupModelModal'
import type { ModelListItem, GroupModelModalRef, CustomModelModalRef, BaseRef, Query } from './types'
import SearchInput from '@/components/SearchInput'
import PageTabs from '@/components/PageTabs'
import GroupModel from './Group'
import ModelList from './List'
import ModelSquare from './Square'
import CustomModelModal from './components/CustomModelModal'
import CustomSelect from '@/components/CustomSelect'
import { modelTypeUrl, modelProviderUrl } from '@/api/models'
/**
* Available tab keys
*/
const tabKeys = ['group', 'list', 'square']
/**
* Model management main component
*/const ModelManagement: FC = () => {
const { t } = useTranslation();
const [activeTab, setActiveTab] = useState('group');
const configModalRef = useRef<GroupModelModalRef>(null)
const customModelModalRef = useRef<CustomModelModalRef>(null)
const groupRef = useRef<BaseRef>(null)
const modelListRef = useRef<BaseRef>(null)
const [form] = Form.useForm<Query>()
const query = Form.useWatch([], form)
/** Format tab items with translations */
const formatTabItems = () => {
return tabKeys.map(value => ({
value,
label: t(`modelNew.${value}`),
}))
}
/** Handle tab change */
const handleChangeTab = (value: SegmentedProps['value']) => {
setActiveTab(value as string);
form.resetFields()
}
/** Open edit modal based on active tab */
const handleEdit = (vo?: ModelListItem | ModelListItem) => {
switch(activeTab) {
case 'group':
configModalRef?.current?.handleOpen(vo as ModelListItem)
break
case 'list':
customModelModalRef?.current?.handleOpen(vo as ModelListItem)
break
}
}
/** Refresh list based on active tab */
const handleRefresh = (isEdit?: boolean) => {
switch (activeTab) {
case 'group':
groupRef.current?.getList()
break
case 'list':
console.log('isEdit', isEdit)
if (isEdit) {
modelListRef.current?.modelListDetailRefresh?.()
} else {
modelListRef.current?.getList()
}
break
}
}
return (
<Flex vertical gap={16}>
<Flex justify="space-between" align="center">
<PageTabs
value={activeTab}
options={formatTabItems()}
onChange={handleChangeTab}
/>
<Form form={form}>
<Space size={12}>
{activeTab === 'list' &&
<Form.Item name="type" noStyle>
<CustomSelect
url={modelTypeUrl}
hasAll={false}
format={(items) => items.map((item) => ({ label: t(`modelNew.${item}`), value: String(item) }))}
className="rb:w-40"
allowClear={true}
placeholder={t('modelNew.type')}
/>
</Form.Item>
}
{activeTab === 'list' &&
<Form.Item name="provider" noStyle>
<CustomSelect
url={modelProviderUrl}
hasAll={false}
format={(items) => items.map((item) => ({ label: t(`modelNew.${item}`), value: String(item) }))}
className="rb:w-40"
allowClear={true}
placeholder={t('modelNew.provider')}
/>
</Form.Item>
}
{activeTab !== 'list' &&
<Form.Item name="search" noStyle>
<SearchInput
maxLength={50}
placeholder={t(`modelNew.${activeTab}SearchPlaceholder`)}
/>
</Form.Item>
}
{activeTab === 'group' && <Button type="primary" onClick={() => handleEdit()}>+ {t('modelNew.createGroupModel')}</Button>}
{activeTab === 'list' && <Button type="primary" onClick={() => handleEdit()}>+ {t('modelNew.createCustomModel')}</Button>}
</Space>
</Form>
</Flex>
<div className="rb:w-full rb:h-[calc(100vh-125px)] rb:overflow-y-auto">
{activeTab === 'group' && <GroupModel ref={groupRef} query={query} handleEdit={handleEdit} />}
{activeTab === 'list' && <ModelList ref={modelListRef} query={query} handleEdit={handleEdit} />}
{activeTab === 'square' && <ModelSquare query={query} />}
</div>
<GroupModelModal
ref={configModalRef}
refresh={handleRefresh}
/>
<CustomModelModal
ref={customModelModalRef}
refresh={handleRefresh}
/>
</Flex>
)
}
export default ModelManagement