/* * @Author: ZhaoYing * @Date: 2026-02-03 18:32:35 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-02-03 18:32:35 */ /** * Node Statistics Component * Displays memory node statistics by type with navigation to detail views */ import { type FC, useEffect, useState } from 'react' import clsx from 'clsx' import { useTranslation } from 'react-i18next' import { useParams, useNavigate } from 'react-router-dom' import { Skeleton } from 'antd'; import RbCard from '@/components/RbCard/Card' import { getNodeStatistics, } from '@/api/memory' import type { NodeStatisticsItem } from '../types' /** Background gradient list */ const BG_LIST = [ 'rb:bg-[linear-gradient(316deg,rgba(21,94,239,0.06)_0%,rgba(251,253,255,0)_100%)]', 'rb:bg-[linear-gradient(316deg,rgba(54,159,33,0.06)_0%,rgba(251,253,255,0)_100%)]', 'rb:bg-[linear-gradient(314deg,rgba(156,111,255,0.06)_0%,rgba(251,253,255,0)_100%)]', 'rb:bg-[linear-gradient(332deg,rgba(255,93,52,0.06)_0%,rgba(251,253,255,0)_100%)]', 'rb:bg-[linear-gradient(313deg,rgba(156,111,255,0.06)_0%,rgba(251,253,255,0)_100%)]', 'rb:bg-[linear-gradient(332deg,rgba(54,159,33,0.06)_0%,rgba(251,253,255,0)_100%)]', ] /** Memory type configuration */ const typeList = [ { key: 'PERCEPTUAL_MEMORY', bg: 0 }, { key: 'WORKING_MEMORY', bg: 1 }, { key: 'EMOTIONAL_MEMORY', bg: 2 }, { key: 'SHORT_TERM_MEMORY', bg: 3 }, { key: 'LONG_TERM_MEMORY', bg: 4, children: [ { key: 'IMPLICIT_MEMORY' }, { key: 'EPISODIC_MEMORY' }, { key: 'EXPLICIT_MEMORY' } ] }, { key: 'FORGET_MEMORY', bg: 5 }, ] const NodeStatistics: FC = () => { const navigate = useNavigate(); const { t } = useTranslation() const { id } = useParams() const [loading, setLoading] = useState(false) const [total, setTotal] = useState(0) const [data, setData] = useState([]) useEffect(() => { if (!id) return getData() }, [id]) /** Fetch node statistics */ const getData = () => { if (!id) return setLoading(true) getNodeStatistics(id).then((res) => { const response = res as NodeStatisticsItem[] setData(response) // Calculate total count const totalCount = response.reduce((sum, item) => sum + (item.count || 0), 0) setTotal(totalCount) setLoading(false) }) .finally(() => { setLoading(false) }) } /** Navigate to detail page */ const handleViewDetail = (type: string) => { navigate(`/user-memory/detail/${id}/${type}`) } /** Render statistics card */ const renderCard = (key: string, bgIndex: number | null, isChild: boolean = false) => { const item = data.find((item) => item.type === key) return (
handleViewDetail(key)} >
{t(`userMemory.${key}`)}
{item?.count ?? 0}
) } return ( {t('userMemory.nodeStatistics')} ({t('userMemory.total')}: {total})} headerType="borderless" headerClassName="rb:min-h-[46px]!" > {loading ? :
{typeList.map((vo) => { if (!vo.children) { return
{renderCard(vo.key, vo.bg)}
} return (
{t(`userMemory.${vo.key}`)}
{vo.children.map((child) =>
{renderCard(child.key, null, true)}
)}
) })}
}
) } export default NodeStatistics