-优化了 Data、Scene 和 Team组件的逻辑,使用 currentIodMessage 替代复杂的条件判断- 改进了 IodRelevant 组件的动画和数据处理方式 - 调整了 Message 组件以支持数联网搜索功能 - 重构了 PlaygroundIodProvider,简化了上下文类型和数据处理 - 更新了数据库相关操作,使用新的 HistoryMessage 类型 - 新增了 IodDb 类来管理数联网连接配置
140 lines
5.0 KiB
TypeScript
140 lines
5.0 KiB
TypeScript
import React, { useMemo } from "react"
|
||
import { DataNavigation } from "@/components/Common/DataNavigation.tsx"
|
||
import { Card, Skeleton } from "antd"
|
||
import { useMessageOption } from "@/hooks/useMessageOption.tsx"
|
||
import { IodRegistryEntry } from "@/types/iod.ts"
|
||
import { useIodPlaygroundContext } from "@/components/Option/Playground/PlaygroundIod.tsx"
|
||
|
||
// import { Drawer } from './Drawer.tsx'
|
||
|
||
const defaultData: IodRegistryEntry[] = [
|
||
{
|
||
name: "固态电池固体电解质材料数据集",
|
||
doId: "CSTR:16666.11.nbsdc.9bjqrscd",
|
||
description: "国家基础学科公共科学数据中心"
|
||
},
|
||
{
|
||
name: "固体颗粒物与流体耦合",
|
||
doId: "CSTR:16666.11.nbsdc.xyzbycl7",
|
||
description: "清华大学"
|
||
}
|
||
]
|
||
|
||
type HeaderProps = {
|
||
title: string
|
||
showButton?: boolean
|
||
onClick?: () => void
|
||
}
|
||
const Header: React.FC<HeaderProps> = ({
|
||
title,
|
||
showButton = true,
|
||
onClick
|
||
}) => (
|
||
<DataNavigation
|
||
Header={
|
||
<div className="flex items-center gap-0.5 text-[#3581e3]">
|
||
<svg
|
||
className="icon"
|
||
viewBox="0 0 1024 1024"
|
||
version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
p-id="3572"
|
||
width="18"
|
||
height="18">
|
||
<path
|
||
d="M877.714286 54.857143H754.285714V9.142857c0-5.028571-4.114286-9.142857-9.142857-9.142857h-64c-5.028571 0-9.142857 4.114286-9.142857 9.142857v45.714286H498.285714V9.142857c0-5.028571-4.114286-9.142857-9.142857-9.142857h-64c-5.028571 0-9.142857 4.114286-9.142857 9.142857v45.714286H292.571429c-20.228571 0-36.571429 16.342857-36.571429 36.571428v137.142858h-109.714286c-20.228571 0-36.571429 16.342857-36.571428 36.571428v722.285714c0 20.228571 16.342857 36.571429 36.571428 36.571429h585.142857c20.228571 0 36.571429-16.342857 36.571429-36.571429v-109.714285h109.714286c20.228571 0 36.571429-16.342857 36.571428-36.571429V91.428571c0-20.228571-16.342857-36.571429-36.571428-36.571428zM685.714286 941.714286H192V310.857143h249.142857v198.857143c0 25.257143 20.457143 45.714286 45.714286 45.714285h198.857143v386.285715z m0-459.428572H514.285714V310.857143h0.228572L685.714286 482.057143v0.228571z m146.285714 313.142857h-64V448L548.571429 228.571429H338.285714v-91.428572h77.714286v36.571429c0 5.028571 4.114286 9.142857 9.142857 9.142857h64c5.028571 0 9.142857-4.114286 9.142857-9.142857v-36.571429h173.714286v36.571429c0 5.028571 4.114286 9.142857 9.142857 9.142857h64c5.028571 0 9.142857-4.114286 9.142857-9.142857v-36.571429h77.714286v658.285714z"
|
||
p-id="3573"
|
||
fill="#3581e3"></path>
|
||
</svg>
|
||
{title}
|
||
</div>
|
||
}
|
||
showButton={showButton}
|
||
onClick={onClick}
|
||
/>
|
||
)
|
||
|
||
type MainProps = {
|
||
loading: boolean
|
||
data: IodRegistryEntry[]
|
||
truncate?: boolean
|
||
}
|
||
const Main: React.FC<MainProps> = ({ data, loading, truncate = true }) => (
|
||
<div className="space-y-1.5 flex-1 overflow-y-auto">
|
||
{data.map((item, index) => {
|
||
return (
|
||
<Card
|
||
className="[&_.ant-card-body]:!p-2 !bg-[gb(248, 248, 248)] border !border-[#e9e9e9]"
|
||
key={item.doId}>
|
||
{loading ? (
|
||
<Skeleton title={false} active />
|
||
) : (
|
||
<div className="flex flex-col gap-0.5">
|
||
<h3
|
||
className={`text-base font-medium mb-1 text-[#222222] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||
title={item.name}>
|
||
{item.name}
|
||
</h3>
|
||
<p
|
||
className={`text-sm text-[#383838] break-all ${truncate ? "line-clamp-2" : ""}`}
|
||
title={item.doId}>
|
||
数字对象标识:{item.doId}
|
||
</p>
|
||
<p
|
||
className={`text-[#828282] text-xs break-all ${truncate ? "truncate" : ""}`}
|
||
title={item.description}>
|
||
{item.description}
|
||
</p>
|
||
</div>
|
||
)}
|
||
</Card>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
|
||
type Props = {
|
||
className?: string
|
||
}
|
||
export const PlaygroundData: React.FC<Props> = ({ className }) => {
|
||
const { iodLoading } = useMessageOption()
|
||
|
||
const {
|
||
setShowPlayground,
|
||
setDetailHeader,
|
||
setDetailMain,
|
||
currentIodMessage
|
||
} = useIodPlaygroundContext()
|
||
|
||
const data = useMemo<IodRegistryEntry[]>(() => {
|
||
return currentIodMessage ? currentIodMessage.data?.data ?? [] : defaultData
|
||
}, [currentIodMessage])
|
||
|
||
const title = useMemo(() => {
|
||
return currentIodMessage ? "推荐数据" : "热点数据"
|
||
}, [currentIodMessage])
|
||
|
||
const showMore = () => {
|
||
setShowPlayground(false)
|
||
setDetailHeader(
|
||
<Header
|
||
title={title}
|
||
showButton={false}
|
||
onClick={() => setShowPlayground(false)}
|
||
/>
|
||
)
|
||
setDetailMain(<Main loading={iodLoading && Boolean(currentIodMessage)} data={data} truncate={false} />)
|
||
}
|
||
|
||
return (
|
||
<Card className={`${className}`} hoverable>
|
||
<div className="h-full flex flex-col gap-2 relative">
|
||
{/* 数据导航 */}
|
||
<Header title={title} onClick={showMore} />
|
||
{/* 数据列表 */}
|
||
<Main loading={iodLoading && Boolean(currentIodMessage)} data={data.slice(0, 3)} />
|
||
</div>
|
||
</Card>
|
||
)
|
||
}
|