feat(components): 新增 Drawer 组件并优化 Playground 页面

- 新增 Drawer 组件用于创建可滑动的抽屉式界面
-优化 Playground 页面布局和样式,增加 logo 和 frosted glass 效果
- 添加统计卡片组件和动画效果,提升用户体验
- 新增数据项目图标组件
This commit is contained in:
zhaoweijie 2025-08-22 21:28:40 +08:00
parent 37a11fbb8b
commit 6fb71b01f0
20 changed files with 672 additions and 126 deletions

BIN
bun.lockb Executable file

Binary file not shown.

View File

@ -35,6 +35,7 @@
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",
"d3-dsv": "2", "d3-dsv": "2",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"framer-motion": "^12.23.12",
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"i18next": "^23.10.1", "i18next": "^23.10.1",
"i18next-browser-languagedetector": "^7.2.0", "i18next-browser-languagedetector": "^7.2.0",
@ -47,6 +48,7 @@
"property-information": "^6.4.1", "property-information": "^6.4.1",
"pubsub-js": "^1.9.4", "pubsub-js": "^1.9.4",
"react": "18.2.0", "react": "18.2.0",
"react-countup": "^6.5.3",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-i18next": "^14.1.0", "react-i18next": "^14.1.0",
"react-icons": "^5.2.1", "react-icons": "^5.2.1",

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

View File

@ -4,6 +4,8 @@ import { Card, Drawer, Skeleton } from "antd"
import { useMessageOption } from "@/hooks/useMessageOption.tsx" import { useMessageOption } from "@/hooks/useMessageOption.tsx"
import { IodRegistryEntry } from "@/types/iod.ts" import { IodRegistryEntry } from "@/types/iod.ts"
// import { Drawer } from './Drawer.tsx'
const defaultData: IodRegistryEntry[] = [ const defaultData: IodRegistryEntry[] = [
{ {
name: "2019-2024年黄海清浅海域中河湖代数生物物种数据集", name: "2019-2024年黄海清浅海域中河湖代数生物物种数据集",
@ -66,7 +68,8 @@ const ShowCard: React.FC<ShowCardProps> = ({
</Card> </Card>
) )
export const PlaygroundData = () => { export const PlaygroundData = () => {
const { messages, iodLoading, currentMessageId, iodSearch } = useMessageOption() const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption()
const data = useMemo<IodRegistryEntry[]>(() => { const data = useMemo<IodRegistryEntry[]>(() => {
// 确保loading状态时数据大于3 // 确保loading状态时数据大于3
@ -147,7 +150,12 @@ export const PlaygroundData = () => {
width="33.33%"> width="33.33%">
<div className="grid grid-cols-1 gap-3 overflow-y-auto"> <div className="grid grid-cols-1 gap-3 overflow-y-auto">
{data.map((item, index) => ( {data.map((item, index) => (
<ShowCard key={item.doId} loading={iodLoading} record={item} truncate={false} /> <ShowCard
key={item.doId}
loading={iodLoading}
record={item}
truncate={false}
/>
))} ))}
</div> </div>
</Drawer> </Drawer>

View File

@ -0,0 +1,91 @@
// Drawer.tsx
import React, { useEffect } from "react"
import styled from "styled-components"
import { shadow } from "pdfjs-dist"
interface DrawerProps {
open: boolean
onClose: () => void
children: React.ReactNode
width?: string | number
overlay?: boolean
keydown?: boolean
shadow?: boolean
}
const DrawerOverlay = styled.div<{ isOpen: boolean }>`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
opacity: ${({ isOpen }) => (isOpen ? 1 : 0)};
visibility: ${({ isOpen }) => (isOpen ? "visible" : "hidden")};
transition:
opacity 0.3s ease,
visibility 0.3s ease;
z-index: 1000;
`
const DrawerContainer = styled.div<{
isOpen: boolean
width: string | number
shadow: boolean
}>`
position: fixed;
top: 0;
right: 0;
height: 100%;
width: ${({ width }) => (typeof width === "number" ? `${width}px` : width)};
background: #ffffff;
box-shadow: ${shadow ? "-2px 0 8px rgba(0, 0, 0, 0.15)" : ""};
transform: translateX(${({ isOpen }) => (isOpen ? "0" : "100%")});
transition: transform 0.3s ease;
z-index: 9999;
overflow-y: auto;
`
export const Drawer: React.FC<DrawerProps> = ({
open,
onClose,
children,
overlay = true,
keydown = true,
shadow = true,
width = "300px"
}) => {
// 处理 Escape 键关闭抽屉
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape" && open) {
onClose()
}
}
if (keydown) {
document.addEventListener("keydown", handleEscape)
}
return () => {
if (keydown) {
document.removeEventListener("keydown", handleEscape)
}
}
}, [open, onClose, keydown])
// 处理点击遮罩层关闭抽屉
const handleOverlayClick = (e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
onClose()
}
}
return (
<>
{overlay && <DrawerOverlay isOpen={open} onClick={handleOverlayClick} />}
<DrawerContainer isOpen={open} width={width}>
{children}
</DrawerContainer>
</>
)
}

View File

@ -22,6 +22,8 @@ import { PlusOutlined, RightOutlined } from "@ant-design/icons"
import { qaPrompt } from "@/libs/playground.tsx" import { qaPrompt } from "@/libs/playground.tsx"
import { ProviderIcons } from "@/components/Common/ProviderIcon.tsx" import { ProviderIcons } from "@/components/Common/ProviderIcon.tsx"
import { fetchChatModels } from "@/services/ollama.ts" import { fetchChatModels } from "@/services/ollama.ts"
import logo from '@/assets/logo.png'
const ModelIcon = () => { const ModelIcon = () => {
return ( return (
@ -115,6 +117,7 @@ export const PlaygroundHistory = () => {
{/*Header*/} {/*Header*/}
<div className="flex flex-col overflow-y-hidden h-full"> <div className="flex flex-col overflow-y-hidden h-full">
<div className="flex items-center justify-between transition-all duration-300 ease-in-out w-[250px]"> <div className="flex items-center justify-between transition-all duration-300 ease-in-out w-[250px]">
<img src={logo} alt="logo" className="w-8" />
<h2 className="text-xl font-bold text-zinc-700 dark:text-zinc-300 mr-3"> <h2 className="text-xl font-bold text-zinc-700 dark:text-zinc-300 mr-3">
<span className="text-[#d30100]"></span> <span className="text-[#d30100]"></span>
</h2> </h2>

View File

@ -1,8 +1,15 @@
import React, { useMemo } from "react" import React, { useMemo } from "react"
import { Card } from "antd" import { Avatar, Card } from "antd"
import { AnimatePresence, motion } from "framer-motion" // 使用 CSS-in-JS 方式
// 使用 CSS-in-JS 方式
import styled, { keyframes } from "styled-components" import styled, { keyframes } from "styled-components"
import CountUp from "react-countup"
import { TalentPoolIcon } from "@/components/Icons/TalentPool .tsx"
import { ResearchPaperIcon } from "@/components/Icons/ResearchPaper.tsx"
import { DataProjectIcon } from "@/components/Icons/DataProject.tsx"
import { DatasetIcon } from "@/components/Icons/Dataset.tsx"
import { TechCompanyIcon } from "@/components/Icons/TechCompany.tsx"
import { ResearchInstitutesIcon } from "@/components/Icons/ResearchInstitutes.tsx"
import { NSDCIcon } from "@/components/Icons/NSDC.tsx"
const rotate = keyframes` const rotate = keyframes`
0% { 0% {
@ -25,6 +32,7 @@ const breathe = keyframes`
} }
` `
// 花瓣
const CircleElement = styled.div<{ delay: number; playing: boolean }>` const CircleElement = styled.div<{ delay: number; playing: boolean }>`
position: absolute; position: absolute;
width: 300px; width: 300px;
@ -39,15 +47,29 @@ const CircleElement = styled.div<{ delay: number; playing: boolean }>`
${breathe} 2s infinite alternate; ${breathe} 2s infinite alternate;
animation-delay: ${(props) => props.delay}s; animation-delay: ${(props) => props.delay}s;
animation-play-state: ${(props) => (props.playing ? "running" : "paused")}; animation-play-state: ${(props) => (props.playing ? "running" : "paused")};
animation-duration: 3s; /* 添加动画总持续时间 */
animation-fill-mode: forwards; /* 保持动画结束时的状态 */
` `
const SuccessIcon = () => { const FrostedGlassCard = styled(Card)`
background: rgba(255, 255, 255, 0.25) !important;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
`
const SuccessIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return ( return (
<svg <svg
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
className="w-full h-full text-green-500"> className="text-green-500"
ref={ref}
{...props}>
<path <path
d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
stroke="currentColor" stroke="currentColor"
@ -57,9 +79,12 @@ const SuccessIcon = () => {
/> />
</svg> </svg>
) )
} })
const LoadingIcon = () => { const LoadingIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return ( return (
<svg <svg
className="icon animate-spin" className="icon animate-spin"
@ -67,16 +92,15 @@ const LoadingIcon = () => {
version="1.1" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
p-id="29588" p-id="29588"
width="18" ref={ref}
height="18"> {...props}>
<path <path
d="M483.712 888.064a52.437333 52.437333 0 1 1 52.48 52.352 52.394667 52.394667 0 0 1-52.48-52.352z m-235.434667-53.76a65.578667 65.578667 0 1 1 46.421334 19.242667 65.962667 65.962667 0 0 1-46.378667-19.242667z m499.584-16.597333a41.984 41.984 0 0 1 59.264-59.434667 42.282667 42.282667 0 0 1 0 59.434667 41.941333 41.941333 0 0 1-59.264 0zM112.853333 546.602667a81.92 81.92 0 1 1 81.92 81.92 81.834667 81.834667 0 0 1-81.92-81.877334z m731.008 0a33.536 33.536 0 1 1 33.493334 33.578666 33.578667 33.578667 0 0 1-33.450667-33.536zM222.208 377.6a102.4 102.4 0 1 1 72.533333 29.866667 102.869333 102.869333 0 0 1-72.533333-29.824z m536.32-53.504a26.666667 26.666667 0 1 1 18.816 7.936 26.368 26.368 0 0 1-18.773333-7.893333zM414.378667 205.184a121.642667 121.642667 0 1 1 121.813333 121.6A121.728 121.728 0 0 1 414.378667 205.226667z" d="M483.712 888.064a52.437333 52.437333 0 1 1 52.48 52.352 52.394667 52.394667 0 0 1-52.48-52.352z m-235.434667-53.76a65.578667 65.578667 0 1 1 46.421334 19.242667 65.962667 65.962667 0 0 1-46.378667-19.242667z m499.584-16.597333a41.984 41.984 0 0 1 59.264-59.434667 42.282667 42.282667 0 0 1 0 59.434667 41.941333 41.941333 0 0 1-59.264 0zM112.853333 546.602667a81.92 81.92 0 1 1 81.92 81.92 81.834667 81.834667 0 0 1-81.92-81.877334z m731.008 0a33.536 33.536 0 1 1 33.493334 33.578666 33.578667 33.578667 0 0 1-33.450667-33.536zM222.208 377.6a102.4 102.4 0 1 1 72.533333 29.866667 102.869333 102.869333 0 0 1-72.533333-29.824z m536.32-53.504a26.666667 26.666667 0 1 1 18.816 7.936 26.368 26.368 0 0 1-18.773333-7.893333zM414.378667 205.184a121.642667 121.642667 0 1 1 121.813333 121.6A121.728 121.728 0 0 1 414.378667 205.226667z"
p-id="29589" p-id="29589"
fill="#4284f6"></path> fill="#4284f6"></path>
</svg> </svg>
) )
} })
const SearchIcon = () => { const SearchIcon = () => {
return ( return (
<svg <svg
@ -95,11 +119,110 @@ const SearchIcon = () => {
) )
} }
// 自定义统计卡片组件
const StatCard: React.FC<{
number: number
unit?: string
label: string
decimals?: number
icon: React.ReactNode
}> = ({ number, unit, label, decimals, icon }) => {
return (
<div
className="flex flex-col items-center justify-center p-3 rounded-xl shadow-sm bg-[rgba(240,245,255,0.3)] backdrop-blur-sm border border-[rgba(200,220,255,0.25)]
">
<Avatar size={40} className="!bg-[#3581e3b3]" icon={icon} />
<div className="text-lg font-bold text-[#f00000]">
<CountUp
end={number}
duration={2.5}
separator=","
decimals={decimals}
/>
{unit}
</div>
<div className="text-sm text-[#3581e3] mt-1 flex items-center gap-2">
{" "}
{label}
</div>
</div>
)
}
// 主组件
export const StatisticGrid: React.FC = () => {
return (
<div className="p-6 min-h-screen">
{/* 第一行3 个卡片 */}
<div className="grid grid-cols-3 gap-6 mb-6">
<StatCard
icon={<NSDCIcon className="w-6 h-6 text-white" color="#3581e3" />}
number={11}
unit="家"
label="国家科学数据中心"
/>
<StatCard
icon={
<ResearchInstitutesIcon
className="w-6 h-6 text-white"
color="#3581e3"
/>
}
number={763}
unit="家"
label="高等院校和科研机构"
/>
<StatCard
icon={
<TechCompanyIcon className="w-6 h-6 text-white" color="#3581e3" />
}
number={2.1}
decimals={1}
unit="万"
label="科技型企业"
/>
</div>
{/* 第二行4 个卡片 */}
<div className="grid grid-cols-4 gap-6">
<StatCard
icon={<DatasetIcon className="w-6 h-6 text-white" color="#3581e3" />}
number={537163}
label="数据集"
/>
<StatCard
icon={
<DataProjectIcon className="w-6 h-6 text-white" color="#3581e3" />
}
number={183729}
label="数据项目"
/>
<StatCard
icon={
<ResearchPaperIcon className="w-6 h-6 text-white" color="#3581e3" />
}
number={1380026}
label="科研论文"
/>
<StatCard
icon={
<TalentPoolIcon className="w-6 h-6 text-white" color="#3581e3" />
}
number={2}
unit="万"
label="科创人才"
/>
</div>
</div>
)
}
export const PlaygroundIodRelevant: React.FC = () => { export const PlaygroundIodRelevant: React.FC = () => {
const { messages, iodLoading, currentMessageId, iodSearch } = const { messages, iodLoading, currentMessageId, iodSearch } =
useMessageOption() useMessageOption()
const showDescription = useMemo(() => { const showSearchData = useMemo(() => {
return iodSearch && messages.length > 0 && !iodLoading return iodSearch && messages.length > 0 && !iodLoading
}, [iodSearch, messages, iodLoading]) }, [iodSearch, messages, iodLoading])
@ -111,17 +234,34 @@ export const PlaygroundIodRelevant: React.FC = () => {
{ {
title: ( title: (
<p className="font-extrabold"> <p className="font-extrabold">
<span className="text-[#f00000]"> 11 </span>
<span className="text-[#f00000]">
<span className="text-[#f00000]"> 500000+ </span> <CountUp end={29} duration={2.5} separator="," />
</span>
<span className="text-[#f00000]">
{" "}
<CountUp end={55} duration={2.5} separator="," />
</span>
<span className="text-[#f00000]">
<CountUp decimals={1} end={53.7} duration={2.5} separator="," />
</span>
</p> </p>
), ),
description: showDescription ? ( description: showSearchData ? (
<p> <p>
<span className="text-green-700"> <span className="text-green-700">
{" "} {" "}
{currentMessage?.iodSources.data.total}{" "} <CountUp
end={currentMessage?.iodSources.data.total ?? 0}
duration={2.5}
separator=","
/>
{" "}
</span> </span>
</p> </p>
@ -132,18 +272,32 @@ export const PlaygroundIodRelevant: React.FC = () => {
{ {
title: ( title: (
<p className="font-extrabold"> <p className="font-extrabold">
<span className="text-[#f00000]"> 1000000+ </span>
<span className="text-[#f00000]"> 50000+ </span> <span className="text-[#f00000]">
<CountUp end={138} duration={2.5} separator="," />
</span>
<span className="text-[#f00000]">
<CountUp end={18.3} decimals={1} duration={2.5} separator="," />
</span>
</p> </p>
), ),
description: showDescription ? ( description: showSearchData ? (
<p> <p>
<span className="text-green-700"> <span className="text-green-700">
{" "} {" "}
{currentMessage?.iodSources.scenario.total}{" "} <CountUp
end={currentMessage?.iodSources.scenario.total ?? 0}
duration={2.5}
separator=","
/>
{" "}
</span> </span>
</p> </p>
) : ( ) : (
"" ""
@ -152,19 +306,36 @@ export const PlaygroundIodRelevant: React.FC = () => {
{ {
title: ( title: (
<p className="font-extrabold"> <p className="font-extrabold">
<span className="text-[#f00000]"> 1000+ </span>
<span className="text-[#f00000]"> 763 </span> <span className="text-[#f00000]">
<span className="text-[#f00000]"> 21000+ </span> <CountUp end={763} duration={2.5} separator="," />
</span>
<span className="text-[#f00000]">
{" "}
<CountUp end={2.1} decimals={1} duration={2.5} separator="," />
</span>
<span className="text-[#f00000]">
{" "}
<CountUp end={2} duration={2.5} separator="," />
</span>
</p> </p>
), ),
description: showDescription ? ( description: showSearchData ? (
<p> <p>
<span className="text-green-700"> <span className="text-green-700">
{" "} {" "}
{currentMessage?.iodSources.organization.total}{" "} <CountUp
end={currentMessage?.iodSources.organization.total ?? 0}
duration={2.5}
separator=","
/>
{" "}
</span> </span>
</p> </p>
) : ( ) : (
"" ""
@ -180,7 +351,7 @@ export const PlaygroundIodRelevant: React.FC = () => {
className="flex flex-col h-full [&_.ant-card-body]:h-full [&_.ant-card-body]:!p-[20px] translate-y-[-2px] !bg-[#f0f9ff]"> className="flex flex-col h-full [&_.ant-card-body]:h-full [&_.ant-card-body]:!p-[20px] translate-y-[-2px] !bg-[#f0f9ff]">
<div className="h-full flex flex-col relative"> <div className="h-full flex flex-col relative">
{/* 花瓣效果 */} {/* 花瓣效果 */}
<div className="absolute inset-0 pointer-events-none z-0 overflow-hidden"> <div className={`absolute inset-0 pointer-events-none z-0 overflow-hidden ${showSearchData ? '' : ''}`}>
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-64 h-64"> <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-64 h-64">
<CircleElement delay={0} playing={true} /> <CircleElement delay={0} playing={true} />
<CircleElement delay={1} playing={true} /> <CircleElement delay={1} playing={true} />
@ -200,28 +371,43 @@ export const PlaygroundIodRelevant: React.FC = () => {
{/*</button>*/} {/*</button>*/}
</h2> </h2>
<p className="text-sm text-[#1a3c87] mt-1 text-center"> <p className="text-sm text-[#1a3c87] mt-1 text-center">
</p> </p>
</div> </div>
{/* Content */} {/* Content */}
<div className="space-y-2 flex-1 overflow-y-auto"> <div className="space-y-2 flex-1 overflow-y-auto">
{showSearchData ? (
<AnimatePresence mode="wait">
<motion.div
key="search-results"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.3 }}
className="space-y-2 flex-1 overflow-y-auto">
{data.map((item, index) => ( {data.map((item, index) => (
<Card <FrostedGlassCard
className="[&_.ant-card-body]:!p-3 [&_.ant-card-body]:h-full shadow-md h-[88px]" className="[&_.ant-card-body]:!p-3 [&_.ant-card-body]:h-full shadow-md min-h-[88px]"
key={index}> key={index}>
<div <div
className={`flex flex-col gap-2 h-full items-start ${showDescription ? "justify-start" : "justify-center"}`}> className={`flex flex-col gap-2 h-full items-start ${showSearchData ? "justify-start" : "justify-center"}`}>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className={`${showDescription ? "w-5 h-5" : "w-6 h-6"}`}> <div>
{iodSearch && iodLoading ? ( {iodSearch && iodLoading ? (
<LoadingIcon /> <LoadingIcon
width={showSearchData ? 16 : 22}
height={showSearchData ? 16 : 22}
/>
) : ( ) : (
<SuccessIcon /> <SuccessIcon
width={showSearchData ? 16 : 22}
height={showSearchData ? 16 : 22}
/>
)} )}
</div> </div>
<p <p
className={`text-gray-700 ${showDescription ? "text-sm" : "text-lg"}`}> className={`text-gray-700 ${showSearchData ? "text-sm" : "text-lg"}`}>
{item.title} {item.title}
</p> </p>
</div> </div>
@ -233,8 +419,23 @@ export const PlaygroundIodRelevant: React.FC = () => {
</div> </div>
)} )}
</div> </div>
</Card> </FrostedGlassCard>
))} ))}
</motion.div>
</AnimatePresence>
) : (
<AnimatePresence mode="wait">
<motion.div
key="statistic-grid"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.3 }}
className="flex-1 overflow-y-auto">
<StatisticGrid />
</motion.div>
</AnimatePresence>
)}
</div> </div>
</div> </div>
</Card> </Card>

View File

@ -0,0 +1,24 @@
import React from "react"
export const DataProjectIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M669.538462 315.076923a185.659077 185.659077 0 0 1 122.171076 325.474462 354.500923 354.500923 0 0 1 232.093539 321.378461l0.196923 11.421539c0 27.963077-22.685538 50.648615-50.688 50.648615H365.764923a50.688 50.688 0 0 1-50.412308-45.489231L315.076923 973.312a354.579692 354.579692 0 0 1 232.290462-332.8A185.659077 185.659077 0 0 1 669.538462 315.076923z m-263.404308 161.910154a267.815385 267.815385 0 0 0-1.024 23.748923l0.196923 11.027692c1.378462 32.846769 8.782769 64.630154 21.464615 93.971693l2.087385 4.489846v2.756923l-1.220923 0.866461A433.742769 433.742769 0 0 0 249.619692 866.461538H126.936615A87.512615 87.512615 0 0 1 39.384615 778.948923v-214.449231c0-48.324923 39.187692-87.512615 87.512616-87.512615h279.236923zM341.346462 0c48.324923 0 87.512615 39.187692 87.512615 87.512615V389.513846H126.897231A87.512615 87.512615 0 0 1 39.384615 301.961846V87.512615C39.384615 39.187692 78.572308 0 126.897231 0h214.449231z m476.947692 0C866.697846 0 905.846154 39.187692 905.846154 87.512615v294.4A264.428308 264.428308 0 0 0 516.332308 285.144615V87.512615C516.371692 39.187692 555.559385 0 603.884308 0h214.44923z"
p-id="11293"></path>
<path
d="M24.024615 24.615385L23.630769 22.646154l0.393846 1.969231zM24.024615 1001.353846l-0.393846-1.969231 0.393846 1.969231zM1000.763077 24.615385l-0.393846-1.969231 0.393846 1.969231zM1000.763077 1001.353846l-0.393846-1.969231 0.393846 1.969231z"
p-id="11294"></path>
</svg>
)
})

View File

@ -0,0 +1,27 @@
import React from "react"
export const DatasetIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1153 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M849.992624 307.054752c-56.549976 0-109.613995 0.871489-162.581182 0a39.701182 39.701182 0 0 0-40.282175 23.239716c-15.29948 27.403499-31.857778 54.226005-49.190733 80.370686A36.118392 36.118392 0 0 1 576.054468 426.061466C416.378251 441.167281 257.670355 439.908463 104.966052 380.35669a323.419385 323.419385 0 0 1-45.123782-22.852387C19.850591 334.167754-2.420804 300.857494 0.871489 252.344586a735.92435 735.92435 0 0 0 0-77.465721A98.478298 98.478298 0 0 1 46.285768 87.148936c51.030544-36.312057 109.80766-53.257683 169.940426-65.071206C384.810969-11.329362 552.427423-8.811726 716.55792 44.252293a419.767376 419.767376 0 0 1 93.927186 48.416076c28.274988 18.01078 39.894846 46.963593 39.313854 81.04851-0.387329 41.444161 0.193664 83.178818 0.193664 133.337873zM724.594988 957.766809c-52.967187 10.554704-105.740709 22.755556-159.095224 31.373617a981.587518 981.587518 0 0 1-293.595083 0 625.535697 625.535697 0 0 1-193.664303-55.581655c-52.289362-25.951017-82.791489-63.618723-77.465721-125.881797 3.195461-40.088511 0.580993-80.56435 0.580993-122.976832 58.099291 78.724539 144.279905 96.832151 229.879527 113.487281 111.16331 21.399905 223.391773 28.274988 335.717069 5.713097 14.137494-2.808132 21.496738 2.517636 28.178156 15.202648 16.267801 30.59896 35.634232 59.454941 51.417872 90.150733a58.099291 58.099291 0 0 0 50.159055 34.762742 189.50052 189.50052 0 0 1 27.113002 6.29409zM1.161986 397.689645c25.66052 44.54279 61.972577 65.071206 101.092766 81.242175A723.820331 723.820331 0 0 0 358.27896 531.027518c65.749031 1.936643 131.691726-5.616265 197.537588-7.456076a35.5374 35.5374 0 0 1 26.338346 13.556501 751.514326 751.514326 0 0 1 45.414279 79.692861c3.58279 7.262411 0 18.301277-1.258818 27.500331 0 2.808132-3.970118 5.035272-5.422601 7.843404-19.36643 38.732861-49.481229 56.646809-94.701844 60.32643-142.343262 11.426194-281.491064 1.936643-416.37825-47.350922a320.804917 320.804917 0 0 1-43.574469-20.818912C21.980898 619.725768-2.808132 584.575697 0.580993 530.737021c2.7113-41.734657 0.580993-83.856643 0.580993-133.047376zM1017.899574 477.57617c0-32.148274-0.774657-59.551773 0.580993-87.148936 0-6.100426 7.746572-12.104019 12.685012-17.429787 11.135697-11.910355 13.846998-26.822506 1.258818-35.731064-7.64974-5.4226-30.59896-4.454279-33.213428 0.580993-15.202648 29.049645-45.607943 34.375414-68.653995 50.546383a312.864681 312.864681 0 0 1-30.017967 17.139291c-9.683215-15.29948-19.36643-29.72747-27.306667-45.123783a21.399905 21.399905 0 0 1 1.646147-17.429787c18.591773-33.794421 37.474043-67.782506 58.099291-100.511773a32.729267 32.729267 0 0 1 22.561891-13.556501c37.086714-1.35565 74.27026-1.452482 111.260142 0a35.731064 35.731064 0 0 1 24.789031 14.137494c20.818913 31.567281 40.572671 64.006052 58.873948 96.832151a35.150071 35.150071 0 0 1 0 27.984492c-15.008983 29.049645-33.213428 57.227801-48.416076 86.567943-8.908558 17.429787-20.334752 25.176359-39.894846 23.046052a405.242553 405.242553 0 0 0-44.252294 0.096832zM900.539007 842.439716c28.37182 16.267801 55.000662 30.986288 80.951679 46.866762 4.551111 2.808132 5.906761 10.457872 9.683215 14.912151a76.594232 76.594232 0 0 0 24.014373 22.271395 25.370024 25.370024 0 0 0 20.915745-12.781844 72.430449 72.430449 0 0 0-8.811726-31.179953c-2.323972-6.197258-9.102222-11.523026-9.683215-17.429787-0.968322-29.049645 0-58.099291 0-90.44123 19.36643 0 38.055035-0.677825 56.162648 0a22.271395 22.271395 0 0 1 14.331158 10.264208c20.141087 33.891253 39.991678 67.782506 58.099291 102.738913a29.049645 29.049645 0 0 1-0.580993 23.917541c-17.720284 33.31026-36.312057 66.330024-56.25948 98.478298a32.148274 32.148274 0 0 1-22.658723 12.491348q-55.484823 2.033475-111.16331 0a32.148274 32.148274 0 0 1-22.368227-12.685012q-30.405296-47.931915-57.324633-97.994137a34.084917 34.084917 0 0 1 0-25.854185A401.272435 401.272435 0 0 1 900.539007 842.439716z"
p-id="6804"></path>
<path
d="M875.362648 419.96104c-26.628842 15.493144-51.32104 30.308463-76.691064 43.961797-4.551111 2.420804-12.200851-1.646147-17.817116 0-10.748369 2.517636-24.692199 4.06695-30.308463 11.329362-4.357447 5.713097 1.258818 19.36643 3.776454 29.630638 1.742979 7.165579 8.037069 13.750165 8.327565 20.72208 0.968322 29.049645 0 58.099291 0 90.92539-19.36643 0-37.667707 0.968322-55.678487-0.580993a25.176359 25.176359 0 0 1-15.008984-12.781844c-19.36643-34.278582-38.732861-68.653995-56.549976-103.900898a36.118392 36.118392 0 0 1 0.774657-28.37182c16.267801-31.373617 33.600757-62.359905 52.870355-91.990544a40.669504 40.669504 0 0 1 27.790827-16.267801c32.051442-2.033475 64.393381 0 96.832151-1.258818 20.334752-1.065154 33.794421 4.551111 41.928322 23.820709a381.22818 381.22818 0 0 0 19.753759 34.762742zM763.037352 639.092199c0 33.503924 0.774657 62.55357 0 91.40955 0 7.64974-8.424397 14.621655-10.36104 22.561892s-6.003593 22.658723-1.452482 27.984491 18.591773 7.262411 29.049645 9.00539a242.080378 242.080378 0 0 1 32.826099 3.292294 134.790355 134.790355 0 0 1 31.664114 17.332955c10.845201 7.359243 30.695792 18.785437 29.049645 23.530212a193.664303 193.664303 0 0 1-27.113002 50.352719c-2.130307 3.195461-10.264208 3.292293-15.589976 3.292293-38.732861 0-77.465721 1.065154-116.198582 0a34.375414 34.375414 0 0 1-23.723877-14.524822c-19.36643-30.695792-37.474043-62.069409-53.838676-94.314516a38.732861 38.732861 0 0 1 0-30.405295c14.427991-29.049645 32.632435-55.581655 46.866761-84.340804 9.683215-19.36643 21.303073-28.274988 43.090307-25.079527A246.050496 246.050496 0 0 0 763.037352 639.092199zM1017.899574 752.095319c0-31.373617-0.580993-58.680284 0-85.890118a30.017967 30.017967 0 0 1 9.683216-17.139291c15.589976-14.912151 15.686809-28.178156 1.452482-42.993475a40.088511 40.088511 0 0 1-11.038865-23.433381c-1.452482-25.466856-0.580993-51.127376-0.580993-79.983357 20.72208 0 38.732861-1.161986 57.130969 0.677825a29.630638 29.630638 0 0 1 17.236123 14.137495c19.36643 31.276785 39.410686 62.747234 56.937305 95.282836a38.055035 38.055035 0 0 1 0 30.211632c-15.202648 30.114799-33.891253 58.099291-49.384397 88.504586-8.037069 15.589976-17.623452 22.94922-35.5374 21.012577a450.075839 450.075839 0 0 0-45.89844-0.387329z"
p-id="6805"></path>
<path
d="M875.45948 551.943262c-32.535603 68.84766-35.924728 70.881135-103.51357 62.650402 0-31.276785-1.161986-63.328227 1.258818-95.089172 0-4.744775 20.334752-14.234326 26.435177-11.329362 25.951017 11.813522 50.159054 27.984492 75.819575 43.768132zM879.816927 697.966147c-27.693995 16.461466-54.03234 33.213428-81.532672 47.641418-14.427991 7.64974-25.66052 0.580993-26.338345-16.074137-1.161986-24.885863 0-49.771726 0-74.754421a19.947423 19.947423 0 0 1 4.066951-13.266005c10.554704-10.264208 71.074799 0 78.724539 12.58818s15.783641 27.693995 25.079527 43.864965zM907.510922 834.693144c39.410686-73.398771 16.945626-60.035934 102.15792-58.099291 0 31.470449 0.580993 63.134563-0.968322 94.701844 0 3.292293-15.493144 10.457872-20.044255 8.230733-27.209835-13.750165-53.354515-29.340142-81.145343-44.833286zM909.060236 416.378251c25.079527-14.912151 48.997069-29.533806 73.398771-43.283972 15.686809-8.908558 25.757352 0 26.725674 14.427991 1.936643 29.049645 0.580993 57.518298 0.580993 85.599621-56.356312 14.331158-71.55896 5.809929-100.705438-56.74364zM1009.765674 504.882837v87.148936c0 14.234326-9.683215 18.688605-21.399906 12.200851-25.854184-14.234326-51.127376-29.824303-76.206903-44.542789 14.331158-54.613333 29.921135-63.618723 97.606809-54.806998zM904.218629 568.114232c26.628842 15.880473 52.095697 31.083121 77.465721 46.479432 11.329362 6.778251 12.394515 14.718487 0.677825 21.884066-25.273191 15.589976-50.836879 30.695792-75.819575 45.704776-42.025154-43.090307-42.509314-58.680284-2.323971-114.068274zM1009.765674 749.965012c-64.780709 7.359243-66.233191 6.487754-99.252955-55.097494 26.628842-15.29948 53.160851-31.276785 80.56435-45.704776 10.845201-5.616265 18.688605-0.580993 18.688605 12.975509zM883.883877 709.973333c39.798014 60.616927 38.732861 46.479433-1.258818 110.098156L788.213712 764.973995zM791.31234 488.421371c7.359243-5.809929 10.264208-8.618061 13.556502-10.651536 24.789031-14.718487 49.674894-29.049645 74.27026-43.671301 36.796217 38.151868 37.086714 54.322837 0.580993 106.999527z"
p-id="6806"></path>
</svg>
)
})

View File

@ -0,0 +1,26 @@
import React from "react"
export const NSDCIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M482.233219 569.858314a74.216 74.216 0 1 0 56.802467-137.133287 74.216 74.216 0 1 0-56.802467 137.133287Z"
fill=""
p-id="7898"></path>
<path
d="M952.472 447.816c-25.08-25.224-59-45.952-99.736-63.784-81.616-35.808-191.784-59.872-317.32-66.536a1387.864 1387.864 0 0 0-49-1.16c28.56-38.272 56.824-72.624 83.496-101.04 52.328-55.376 100.896-84.224 123.216-85.088 9.712-0.288 15.224 1.448 19.856 4.352 9.568 6.376 22.176 21.456 21.456 47.256-0.584 19.856-8.984 58.128-19.568 81.76l67.696 30.152c15.656-34.648 25.08-75.528 26.096-109.88 1.304-50.88-23.776-91.032-55.232-111.472-18.992-12.176-41.312-17.104-63.056-16.384-62.912 2.464-116.984 47.544-174.384 108.432-40.592 42.912-81.904 96.112-122.64 154.24-28.264 2.176-55.952 5.072-82.336 9.28-13.48-45.52-22.472-86.544-23.048-115.096-0.432-25.656 2.176-46.824 6.52-60.304 4.496-13.624 8.984-17.688 12.464-19.424 2.752-1.448 5.656-2.32 10-2.608 20.008-1.592 60.88 6.96 100.312 43.776l50.592-54.216C421.32 76.584 370.88 57.88 328.984 56a233.76 233.76 0 0 0-17.544 0.288l-0.144 0.144a103.392 103.392 0 0 0-38.128 10.44v0.144c-25.512 12.904-41.024 37.256-49.288 62.624-8.264 25.512-10.584 53.632-10.144 84.368 0.728 38.128 9.568 82.624 22.616 129.016-22.32 5.656-43.488 12.032-63.056 19.136-39.576 14.496-73.208 31.744-99.008 53.632-25.952 21.888-46.096 50.88-46.096 85.528 0 39.864 21.6 72.912 47.544 95.672 26.096 22.904 57.256 38.416 87.408 50.304l26.96-69.288c-25.08-9.712-49.432-22.76-65.376-36.672-15.8-13.92-22.328-25.8-22.328-40.008 0-5.8 3.624-15.368 19.568-28.848 15.944-13.336 42.76-28.12 76.832-40.592 17.976-6.52 38.272-12.464 59.872-17.688 9.424 25.8 19.856 51.464 30.584 76.688-57.84 123.216-76.832 241.216-75.528 316.736 0.872 50.736 19.424 95.96 56.968 120.32 24.352 15.656 55.232 23.48 87.408 19.136 32.04-4.352 64.656-19.424 99.736-44.504l-42.912-60.304c-28.704 20.44-51.168 29.136-66.976 31.312-15.8 2.032-25.656-0.576-36.816-7.976-11.888-7.68-22.616-24.936-23.192-59.288-0.872-50.448 10.584-133.512 43.632-223.968 6.088 11.888 12.032 23.632 17.976 34.648h-0.144c39.576 73.352 99.008 161.2 161.2 228.168 31.024 33.488 62.48 61.752 95.096 80.6 31.6 18.12 69.144 27.832 103.792 12.176 30.584-10.584 49.576-37.832 58.856-67.264 9.568-30.728 12.032-66.68 9.424-107.416-5.512-81.32-33.048-181.344-86.104-279.488l-65.232 35.08c47.984 89.152 72.624 180.912 77.264 249.336 2.32 34.352-0.728 62.768-6.232 80.16-5.36 17.392-10.872 20.152-11.6 20.44l-3.48 0.872-3.04 1.592c-4.208 2.176-14.784 2.752-36.528-9.856-21.888-12.608-49.72-36.528-77.696-66.68C509.04 734.256 451.2 649.312 414.96 581.904c-14.352-26.672-29.136-57.552-43.488-90.312a694.256 694.256 0 0 1 33.632-57.84c9.28-14.496 18.848-28.416 28.416-42.472 10.872-0.288 21.6-1.304 32.616-1.304 21.312 0 43.056 0.584 65.376 1.736 118.288 6.088 221.496 29.568 291.512 60.304 34.936 15.224 61.32 32.472 76.832 48.128 15.656 15.656 19.568 27.104 18.992 36.384 0 2.464-4.352 13.048-22.032 24.936-17.832 11.888-46.384 23.336-80.888 29.568l12.904 73.064c42.76-7.68 80.016-21.456 109.152-41.024 29.28-19.568 53.2-46.68 55.088-82.776 1.728-35.224-15.52-67.408-40.6-92.48z m-615.936-43.784a34.84 34.84 0 0 1-1.592-4.2c1.448-0.144 2.896-0.288 4.208-0.432-0.88 1.592-1.752 3.04-2.616 4.632z"
fill=""
p-id="7899"></path>
</svg>
)
})

View File

@ -0,0 +1,24 @@
import React from "react"
export const ResearchInstitutesIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M977.997713 356.640616l-433.994529-149.255836c-27.084774-9.776045-21.395041-9.833246-48.245647-0.11619L59.169291 355.289237c-26.854181 9.717056-26.682578 25.531403 0.402196 35.336048l103.741547 35.223434c-45.948661 44.509693-48.937424 90.77296-49.513011 144.425909-17.825328 6.844482-30.363118 24.094223-30.363118 44.2505 0 18.515317 10.580437 34.531656 26.051577 42.325321-7.30388 54.571743-28.409339 116.85135-90.284962 190.658788 30.650912 23.692027 46.408058 31.600094 70.100085 39.479561 86.488232-37.150399 75.964996-135.85824 69.234916-234.076295 11.905002-8.626658 19.611078-22.601629 19.611078-38.387376 0-16.933346-8.912664-31.744885-22.195858-40.139163 1.494382-52.587576 12.938199-99.657023 52.27297-130.107731 0.344995-0.832993 1.206588-1.52477 2.93335-2.24336l298.340069-120.53189c11.098823-4.458119 23.634826 0.920582 28.062557 12.019405l0.402196 0.949183c4.431306 11.070222-0.918794 23.634826-12.017617 28.062557l-252.164391 100.808198 225.655204 76.540584c27.027572 9.802858 21.389678 9.861846 48.188446 0.141215L978.34092 392.007052c26.857756-9.747444 26.684365-25.561791-0.400408-35.337836L977.997713 356.640616zM977.997713 356.640616"
p-id="5109"></path>
<path
d="M498.801714 597.128809l-273.092884-92.610549 0 69.665713c14.260977 13.056177 22.140444 31.802086 22.140444 52.676953 0 18.74591-6.554901 35.797233-17.653724 48.563829 3.621552 10.925431 9.890447 21.622058 18.976502 24.959391 158.946079 87.866423 378.616606 86.88864 555.332599-8.885851 13.109803-10.898618 23.288043-24.412405 23.288043-37.493607l0-153.370748-280.570155 96.611059c-26.798768 9.690243-21.334264 9.659855-48.363624-0.11619L498.801714 597.128809zM498.801714 597.128809"
p-id="5110"></path>
</svg>
)
})

View File

@ -0,0 +1,21 @@
import React from "react"
export const ResearchPaperIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M715.648 196.928V0H308.352v118.144h220.544l11.904 11.52 203.648 196.992 11.904 11.52v528.32H960V236.288h-244.352v-39.36zM756.352 0v196.928H960L756.352 0zM471.296 157.568v236.288h244.352V1024H64V157.568h407.296zM512 354.496h203.648L512 157.568v196.928z m-136.064 47.424H163.328c-6.4 0-11.52 8-11.52 17.792 0 9.792 5.12 17.792 11.52 17.792h212.608c6.4 0 11.52-8 11.52-17.792 0-9.792-5.12-17.792-11.52-17.792z m100.352 189.888H168.512c-9.216 0-16.704 7.936-16.704 17.728 0 9.856 7.488 17.792 16.704 17.792h307.776c9.216 0 16.64-7.936 16.64-17.792 0-9.792-7.424-17.728-16.64-17.728z m-302.336 225.344H581.76c12.224 0 22.144-7.936 22.144-17.728 0-9.856-9.92-17.792-22.144-17.792H173.952c-12.224 0-22.144 7.936-22.144 17.792 0 9.792 9.92 17.728 22.144 17.728z"
p-id="10242"></path>
</svg>
)
})

View File

@ -0,0 +1,24 @@
import React from "react"
export const TalentPoolIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}>
<path
d="M194.7 296.1H571v50.6H194.7zM679.7 294.1c-15 1.9-26.2 13.1-26.2 28.1v1.9c1.8 15 13.1 26.2 28.1 26.2 15-1.9 26.2-13.2 26.2-28.1v-1.9c-1.9-14.9-13.2-26.2-28.1-26.2z"
p-id="19241"></path>
<path
d="M932.4 86.4c-18.7-15-43.1-22.5-67.4-22.5H279c-26.2 0-50.5 7.5-67.4 22.5-18.7 16.9-29.9 39.4-29.9 61.9v41H163c-26.2 0-50.5 7.5-67.4 22.4C75 230.5 63.8 253 63.8 277.4v598c0 24.3 11.2 46.8 29.9 61.8s43.1 22.5 67.4 22.5h584.2c26.2 0 50.6-7.5 67.4-22.5 18.7-16.8 31.8-39.3 31.8-61.8v-30h16.9c26.2 0 50.5-7.5 67.4-22.5 18.7-16.8 30-39.4 30-61.8v-611c3.6-24.4-7.6-46.8-26.4-63.7z m-345.5 711c-2.3 48.8-57.3 48.8-138.8 49-81.5-0.2-136.5-0.2-138.8-49-2.3-48.8 30-90.6 54.9-111 24.9-20.4 43-19.4 43-19.4l40.9-0.1 40.9 0.1s18.2-0.9 43 19.4c24.9 20.4 57.2 62.2 54.9 111zM368.5 578.5c0-43.9 35.6-79.6 79.6-79.6s79.6 35.6 79.6 79.6S492 658 448.1 658s-79.6-35.6-79.6-79.5z m412.3-197.9H128.2v-86.3c0-18.8 2.5-40.8 40.7-40.8h575.2c14.2 0 36.7 15 36.7 33.8v93.3z m117.1 363.6c0 3.8-6.4 22.5-18.6 31-12.2 8.4-30.1 6.5-32 6.5h-2.9V277.3c0-34.3-12.2-86.2-102.8-86.2H242.3v-30c0-3.8 0-7.5 1.9-11.3 1.9-3.8 3.8-5.6 7.5-9.4 9.4-9.4 22.5-15 39.3-15h548.2c26.2 0 58.7 15 58.7 33.7v585.1z"
p-id="19242"></path>
</svg>
)
})

View File

@ -0,0 +1,22 @@
import React from "react"
export const TechCompanyIcon = React.forwardRef<
SVGSVGElement,
React.SVGProps<SVGSVGElement>
>((props, ref) => {
return (
<svg
className="icon"
viewBox="0 0 1024 1024"
version="1.1"
fill="currentColor"
fillRule="evenodd"
ref={ref}
{...props}
>
<path
d="M968 905.6h-48.64V357.376c0-36.992-28.608-66.816-63.808-66.816h-128v615.168h-48V135.68c0-36.864-28.544-66.816-63.872-66.816H168.448c-35.328 0-63.872 29.952-63.872 66.816v769.92H56a24.32 24.32 0 0 0-24 24.64 24.32 24.32 0 0 0 24 24.64h576.128v0.128h287.168v-0.128h48.64a24.32 24.32 0 0 0 24.064-24.64 24.32 24.32 0 0 0-24-24.64zM440.192 265.92h95.808v73.856H440.192V265.856z m0 196.864h95.808v73.856H440.192V462.72z m0 196.928h95.808v73.856H440.192v-73.856z m-192-393.792h96v73.856h-96V265.856z m0 196.864h96v73.856h-96V462.72z m0 196.928h96v73.856h-96v-73.856z"
p-id="9056"></path>
</svg>
)
})

View File

@ -6,6 +6,7 @@ import { PlusOutlined } from "@ant-design/icons"
import { useMessageOption } from "@/hooks/useMessageOption.tsx" import { useMessageOption } from "@/hooks/useMessageOption.tsx"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { NavLink, useLocation } from "react-router-dom" import { NavLink, useLocation } from "react-router-dom"
import logo from "@/assets/logo.png"
interface SettingIconProps {} interface SettingIconProps {}
const SettingIcon: React.FC<SettingIconProps> = () => { const SettingIcon: React.FC<SettingIconProps> = () => {
@ -117,8 +118,9 @@ export const Header: React.FC<Props> = ({ setOpenModelSettings }) => {
fill="#ffffff" fill="#ffffff"
p-id="9635"></path> p-id="9635"></path>
</svg> </svg>
<h2 className="text-xl font-bold text-zinc-700 dark:text-zinc-300 mr-3 absolute left-1/2 transform -translate-x-1/2"> <h2 className="flex items-center gap-3 text-xl font-bold text-zinc-700 dark:text-zinc-300 mr-3 absolute left-1/2 transform -translate-x-1/2">
<span className="text-[#d30100]"></span> <img src={logo} alt="logo" className="w-8" />
<p><span className="text-[#d30100]"></span></p>
</h2> </h2>
</div> </div>
{/*设置框*/} {/*设置框*/}

View File

@ -1,13 +1,9 @@
import React, { useContext } from "react" import React from "react"
import { Card } from "antd"
import { PlaygroundForm } from "./PlaygroundForm" import { PlaygroundForm } from "./PlaygroundForm"
import { PlaygroundChat } from "./PlaygroundChat" import { PlaygroundChat } from "./PlaygroundChat"
import { useMessageOption } from "@/hooks/useMessageOption" import { useMessageOption } from "@/hooks/useMessageOption"
import { webUIResumeLastChat } from "@/services/app" import { webUIResumeLastChat } from "@/services/app"
import { PlaygroundData } from "@/components/Common/Playground/Data.tsx"
import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx"
import { import {
formatToChatHistory, formatToChatHistory,
@ -19,9 +15,8 @@ import { getLastUsedChatSystemPrompt } from "@/services/model-settings"
import { useStoreChatModelSettings } from "@/store/model" import { useStoreChatModelSettings } from "@/store/model"
import { useSmartScroll } from "@/hooks/useSmartScroll" import { useSmartScroll } from "@/hooks/useSmartScroll"
import { ChevronDown } from "lucide-react" import { ChevronDown } from "lucide-react"
import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx"
import { PlaygroundHistory } from "@/components/Common/Playground/History.tsx" import { PlaygroundHistory } from "@/components/Common/Playground/History.tsx"
import { PlaygroundIodRelevant } from "@/components/Common/Playground/IodRelevant.tsx" import { PlaygroundIod } from "@/components/Option/Playground/PlaygroundIod.tsx"
export const Playground = () => { export const Playground = () => {
const drop = React.useRef<HTMLDivElement>(null) const drop = React.useRef<HTMLDivElement>(null)
@ -165,21 +160,7 @@ export const Playground = () => {
<PlaygroundForm dropedFile={dropedFile} /> <PlaygroundForm dropedFile={dropedFile} />
</div> </div>
</div> </div>
{/*auto_530px_165px*/} <PlaygroundIod />
<div
className="w-4/12 h-full grid grid-rows-12 gap-3 pt-16 pr-5 pb-0"
style={{ paddingTop: "4rem" }}>
<div className="w-full row-span-5">
<PlaygroundIodRelevant />
</div>
<div className="w-full row-span-4 grid grid-cols-2 gap-3 custom-scrollbar">
<PlaygroundData />
<PlaygroundScene />
</div>
<div className="w-full row-span-3 pb-3">
<PlaygroundTeam />
</div>
</div>
</div> </div>
) )
} }

View File

@ -19,20 +19,20 @@ export const PlaygroundEmpty = () => {
}) })
function handleQuestion(message: string) { function handleQuestion(message: string) {
void sendMessage({ message, image: "", isRegenerate: true }) void sendMessage({ message, image: "" })
} }
return ( return (
<div className="w-full pb-4 pt-[20%]"> <div className="w-full pb-4 pt-[20%]">
{/* 标题区域 */} {/* 标题区域 */}
<div className="mb-4"> {/*<div className="mb-4">*/}
<h2 {/* <h2*/}
className="text-xl font-bold text-gray-800" {/* className="text-xl font-bold text-gray-800"*/}
style={{ lineHeight: "0" }}> {/* style={{ lineHeight: "0" }}>*/}
{/* 数联网科创智能体*/}
</h2> {/* </h2>*/}
<p className="text-sm text-gray-500"></p> {/* <p className="text-sm text-gray-500">您好!请问有什么可以帮您?</p>*/}
</div> {/*</div>*/}
{/* 卡片网格布局 */} {/* 卡片网格布局 */}
<Row gutter={[16, 16]} className="w-full"> <Row gutter={[16, 16]} className="w-full">

View File

@ -1,10 +1,18 @@
import { useForm } from "@mantine/form" import { useForm } from "@mantine/form"
import { useMutation, useQueryClient } from "@tanstack/react-query" import { useMutation, useQueryClient } from "@tanstack/react-query"
import React from "react" import React, { useMemo } from "react"
import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize" import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize"
import { toBase64 } from "~/libs/to-base64" import { toBase64 } from "~/libs/to-base64"
import { useMessageOption } from "~/hooks/useMessageOption" import { useMessageOption } from "~/hooks/useMessageOption"
import { Checkbox, Dropdown, Image, Switch, Tooltip } from "antd" import {
Button,
Checkbox,
Dropdown,
Image,
MenuProps,
Switch,
Tooltip
} from "antd"
import { useWebUI } from "~/store/webui" import { useWebUI } from "~/store/webui"
import { defaultEmbeddingModelForRag } from "~/services/ollama" import { defaultEmbeddingModelForRag } from "~/services/ollama"
import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react" import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react"
@ -205,6 +213,41 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
} }
} }
const iodSearchItems = useMemo<MenuProps["items"]>(() => {
return [
{
key: 0,
label: (
<p
onClick={() => {
setIodSearch(true)
}}>
<p
className={`${iodSearch ? "text-[#0057ff]" : "text-[#000000d9]"} flex items-center gap-1 mb-1`}>
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
)
},
{
key: 1,
label: (
<p
onClick={() => {
setIodSearch(false)
}}>
<p
className={`${!iodSearch ? "text-[#0057ff]" : "text-[#000000d9]"} flex items-center gap-1 mb-1`}>
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
)
}
]
}, [iodSearch])
return ( return (
<div className="flex w-full flex-col items-center p-2 px-5 pt-1 pb-4"> <div className="flex w-full flex-col items-center p-2 px-5 pt-1 pb-4">
<div className="relative z-10 flex w-full flex-col items-center justify-center gap-2 text-base"> <div className="relative z-10 flex w-full flex-col items-center justify-center gap-2 text-base">
@ -318,21 +361,40 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
/> />
</div> </div>
</Tooltip> </Tooltip>
<Tooltip {/*<Tooltip*/}
title={t("tooltip.searchIod")} {/* title={t("tooltip.searchIod")}*/}
className="ml-3"> {/* className="ml-3">*/}
<div className="inline-flex items-center gap-2"> {/* <div className="inline-flex items-center gap-2">*/}
<PiNetwork {/* <PiNetwork*/}
className={`h-5 w-5 dark:text-gray-300 `} {/* className={`h-5 w-5 dark:text-gray-300 `}*/}
/> {/* />*/}
<Switch {/* <Switch*/}
value={iodSearch} {/* value={iodSearch}*/}
onChange={(e) => setIodSearch(e)} {/* onChange={(e) => setIodSearch(e)}*/}
checkedChildren={t("form.webSearch.on")} {/* checkedChildren={t("form.webSearch.on")}*/}
unCheckedChildren={t("form.webSearch.off")} {/* unCheckedChildren={t("form.webSearch.off")}*/}
/> {/* />*/}
</div> {/* </div>*/}
</Tooltip> {/*</Tooltip>*/}
<Dropdown
menu={{ items: iodSearchItems }}
placement="bottom"
trigger={["click"]}
arrow>
<Button
color="purple"
variant="filled"
size="large"
className="w-full mt-4 hover:!bg-[#0057ff1a]"
style={{
color: "#0057ff",
background: "#0057ff0f",
border: "1px solid #0066ff26"
}}>
<PiNetwork className="h-5 w-5" />
{iodSearch ? "开" : "关"}
</Button>
</Dropdown>
</div> </div>
)} )}
</div> </div>

View File

@ -0,0 +1,25 @@
import React from "react"
import { PlaygroundIodRelevant } from "@/components/Common/Playground/IodRelevant.tsx"
import { PlaygroundData } from "@/components/Common/Playground/Data.tsx"
import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx"
import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx"
export const PlaygroundIod = () => {
return (
<div
className="w-[36%] h-full grid grid-rows-12 gap-3 pt-16 pr-5 pb-0"
style={{ paddingTop: "4rem" }}>
<div className="w-full row-span-5">
<PlaygroundIodRelevant />
</div>
<div className="w-full row-span-4 grid grid-cols-2 gap-3 custom-scrollbar">
<PlaygroundData />
<PlaygroundScene />
</div>
<div className="w-full row-span-3 pb-3">
<PlaygroundTeam />
</div>
</div>
)
}

View File

@ -108,8 +108,10 @@ export const getSystemPromptForWeb = async (
// .join("\n") // .join("\n")
} }
for (const key of Object.keys(iodSearchResults)) { for (const key of Object.keys(iodSearchResults)) {
const arr = iodSearchResults[key] const record = iodSearchResults[key]
_iodSearchResults[key] = arr.data.map((res) => ({ _iodSearchResults[key] = {
...record,
data: record.data.map((res) => ({
doId: res.doId, doId: res.doId,
name: res.name, name: res.name,
url: res.url, url: res.url,
@ -123,6 +125,7 @@ export const getSystemPromptForWeb = async (
traceId: res?.traceId traceId: res?.traceId
})) }))
} }
}
} finally { } finally {
resolve(0) resolve(0)
} }
@ -130,8 +133,8 @@ export const getSystemPromptForWeb = async (
]) ])
// let search_results_iod = "" // let search_results_iod = ""
debugger
let iod_search_results = Object.values(_iodSearchResults) let iod_search_results = Object.values(_iodSearchResults)
.map(item => item.data)
.flat() .flat()
.map((result, idx) => { .map((result, idx) => {
const nameAttr = result.name ? ` name="${result.name}"` : "" const nameAttr = result.name ? ` name="${result.name}"` : ""