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

View File

@@ -1,13 +1,9 @@
import React, { useContext } from "react"
import { Card } from "antd"
import React from "react"
import { PlaygroundForm } from "./PlaygroundForm"
import { PlaygroundChat } from "./PlaygroundChat"
import { useMessageOption } from "@/hooks/useMessageOption"
import { webUIResumeLastChat } from "@/services/app"
import { PlaygroundData } from "@/components/Common/Playground/Data.tsx"
import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx"
import {
formatToChatHistory,
@@ -19,9 +15,8 @@ import { getLastUsedChatSystemPrompt } from "@/services/model-settings"
import { useStoreChatModelSettings } from "@/store/model"
import { useSmartScroll } from "@/hooks/useSmartScroll"
import { ChevronDown } from "lucide-react"
import { PlaygroundTeam } from "@/components/Common/Playground/Team.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 = () => {
const drop = React.useRef<HTMLDivElement>(null)
@@ -165,21 +160,7 @@ export const Playground = () => {
<PlaygroundForm dropedFile={dropedFile} />
</div>
</div>
{/*auto_530px_165px*/}
<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>
<PlaygroundIod />
</div>
)
}

View File

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

View File

@@ -1,10 +1,18 @@
import { useForm } from "@mantine/form"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import React from "react"
import React, { useMemo } from "react"
import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize"
import { toBase64 } from "~/libs/to-base64"
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 { defaultEmbeddingModelForRag } from "~/services/ollama"
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 (
<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">
@@ -318,21 +361,40 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
/>
</div>
</Tooltip>
<Tooltip
title={t("tooltip.searchIod")}
className="ml-3">
<div className="inline-flex items-center gap-2">
<PiNetwork
className={`h-5 w-5 dark:text-gray-300 `}
/>
<Switch
value={iodSearch}
onChange={(e) => setIodSearch(e)}
checkedChildren={t("form.webSearch.on")}
unCheckedChildren={t("form.webSearch.off")}
/>
</div>
</Tooltip>
{/*<Tooltip*/}
{/* title={t("tooltip.searchIod")}*/}
{/* className="ml-3">*/}
{/* <div className="inline-flex items-center gap-2">*/}
{/* <PiNetwork*/}
{/* className={`h-5 w-5 dark:text-gray-300 `}*/}
{/* />*/}
{/* <Switch*/}
{/* value={iodSearch}*/}
{/* onChange={(e) => setIodSearch(e)}*/}
{/* checkedChildren={t("form.webSearch.on")}*/}
{/* unCheckedChildren={t("form.webSearch.off")}*/}
{/* />*/}
{/* </div>*/}
{/*</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>

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>
)
}