/* * @Author: ZhaoYing * @Date: 2026-02-03 14:10:15 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-27 15:03:09 */ import { type FC, useState, useRef } from 'react'; import type { MenuInfo } from 'rc-menu/lib/interface'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Row, Col, Flex, Space, App, Tooltip, Dropdown } from 'antd' import SearchInput from '@/components/SearchInput'; import OntologyModal from './components/OntologyModal' import type { OntologyModalRef, OntologyItem, Query, OntologyImportModalRef, OntologyExportModalRef } from './types' import RbCard from '@/components/RbCard' import Tag from '@/components/Tag' import PageScrollList, { type PageScrollListRef } from '@/components/PageScrollList' import { getOntologyScenesUrl, deleteOntologyScene } from '@/api/ontology' import { formatDateTime } from '@/utils/format' import OntologyImportModal from './components/OntologyImportModal' import OntologyExportModal from './components/OntologyExportModal' import RbButton from '@/components/RbButton' /** * Ontology management page component * Displays a list of ontology scenes with search, create, import, export functionality */ const Ontology: FC = () => { // Hooks const { t } = useTranslation(); const navigate = useNavigate() const { modal, message } = App.useApp(); // State const [query, setQuery] = useState({}); // Refs const scrollListRef = useRef(null) const entityModalRef = useRef(null) const ontologyImportModalRef = useRef(null) const ontologyExportModalRef = useRef(null) /** * Open modal to create a new ontology scene */ const handleCreate = () => { entityModalRef.current?.handleOpen() } /** * Open modal to edit an existing ontology scene * @param record - The ontology item to edit * @param e - Mouse event to prevent propagation */ const handleEdit = (record: OntologyItem, e: MenuInfo) => { e.domEvent.stopPropagation(); entityModalRef.current?.handleOpen(record) } /** * Delete an ontology scene with confirmation * @param item - The ontology item to delete * @param e - Menu click info */ const handleDelete = (item: OntologyItem, e: MenuInfo) => { e.domEvent.stopPropagation(); modal.confirm({ title: t('common.confirmDeleteDesc', { name: item.scene_name }), okText: t('common.delete'), cancelText: t('common.cancel'), okType: 'danger', onOk: () => { deleteOntologyScene(item.scene_id) .then(() => { message.success(t('common.deleteSuccess')) scrollListRef.current?.refresh() }) } }) } /** * Navigate to ontology detail page * @param record - The ontology item to view */ const handleJump = (record: OntologyItem) => { navigate(`/ontology/${record.scene_id}`) } /** * Refresh the ontology list */ const handleRefresh = () => { scrollListRef.current?.refresh() } /** * Open export modal */ const handleExport = () => { ontologyExportModalRef.current?.handleOpen() } /** * Open import modal */ const handleImport = () => { ontologyImportModalRef.current?.handleOpen() } return ( <> setQuery({ scene_name: value })} /> {t('ontology.export')} {t('ontology.import')} + {t('ontology.create')} ref={scrollListRef} url={getOntologyScenesUrl} query={query} column={3} renderItem={(item) =>( {item.scene_name} {item.type_num} {t('ontology.typeCount')} {item.is_system_default && {t('common.default')}} , label: t('common.edit'), onClick: (e: MenuInfo) => handleEdit(item, e), }, { key: 'delete', icon:
, label: t('common.delete'), onClick: (e: MenuInfo) => handleDelete(item, e), }, ] }} placement="bottomRight" >
e.stopPropagation()} className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]">
} isNeedTooltip={false} headerClassName="rb:pb-0!" onClick={() => handleJump(item)} className="rb:cursor-pointer!" >
{item.scene_description}
{item.entity_type?.map((type, i) => ( {type} ))} {item.type_num > 3 && ( +{item.type_num - 3} )} {(['created_at', 'updated_at'] as const).map(key => (
{t(`ontology.${key}`)}
{formatDateTime(item[key])}
))}
)} /> ) } export default Ontology