feat: Update dependencies and restructure Playground component

- Upgraded @douyinfe/semi-ui from version 2.63.1 to 2.69.1 in package.json.
- Updated pnpm-lock.yaml to reflect new dependency versions and lockfile format.
- Moved Playground component to a new directory structure under pages.
- Enhanced Playground component with new features and improved user experience.
This commit is contained in:
CalciumIon
2024-12-11 18:27:30 +08:00
parent 713de36ecd
commit 7cab9d7c8a
4 changed files with 2922 additions and 2460 deletions

View File

@@ -5,7 +5,7 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@douyinfe/semi-icons": "^2.63.1", "@douyinfe/semi-icons": "^2.63.1",
"@douyinfe/semi-ui": "^2.63.1", "@douyinfe/semi-ui": "^2.69.1",
"@visactor/react-vchart": "~1.8.8", "@visactor/react-vchart": "~1.8.8",
"@visactor/vchart": "~1.8.8", "@visactor/vchart": "~1.8.8",
"@visactor/vchart-semi-theme": "~1.8.8", "@visactor/vchart-semi-theme": "~1.8.8",

5166
web/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ import { Layout } from '@douyinfe/semi-ui';
import Midjourney from './pages/Midjourney'; import Midjourney from './pages/Midjourney';
import Pricing from './pages/Pricing/index.js'; import Pricing from './pages/Pricing/index.js';
import Task from "./pages/Task/index.js"; import Task from "./pages/Task/index.js";
import Playground from './components/Playground.js'; import Playground from './pages/Playground/Playground.js';
import OAuth2Callback from "./components/OAuth2Callback.js"; import OAuth2Callback from "./components/OAuth2Callback.js";
const Home = lazy(() => import('./pages/Home')); const Home = lazy(() => import('./pages/Home'));

View File

@@ -1,9 +1,11 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom'; import { useNavigate, useSearchParams } from 'react-router-dom';
import { UserContext } from '../context/User'; import { UserContext } from '../../context/User/index.js';
import { API, getUserIdFromLocalStorage, showError } from '../helpers'; import { API, getUserIdFromLocalStorage, showError } from '../../helpers/index.js';
import { Card, Chat, Input, Layout, Select, Slider, TextArea, Typography } from '@douyinfe/semi-ui'; import { Card, Chat, Input, Layout, Select, Slider, TextArea, Typography, Button } from '@douyinfe/semi-ui';
import { SSE } from 'sse'; import { SSE } from 'sse';
import { IconSetting } from '@douyinfe/semi-icons';
import { StyleContext } from '../../context/Style/index.js';
const defaultMessage = [ const defaultMessage = [
{ {
@@ -54,6 +56,8 @@ const Playground = () => {
const [message, setMessage] = useState(defaultMessage); const [message, setMessage] = useState(defaultMessage);
const [models, setModels] = useState([]); const [models, setModels] = useState([]);
const [groups, setGroups] = useState([]); const [groups, setGroups] = useState([]);
const [showSettings, setShowSettings] = useState(true);
const [styleState, styleDispatch] = useContext(StyleContext);
const handleInputChange = (name, value) => { const handleInputChange = (name, value) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
@@ -257,95 +261,141 @@ const Playground = () => {
}) })
}, []); }, []);
const SettingsToggle = () => {
if (!styleState.isMobile) return null;
return (
<Button
icon={<IconSetting />}
style={{
position: 'absolute',
left: showSettings ? -10 : -20,
top: '50%',
transform: 'translateY(-50%)',
zIndex: 1000,
width: 40,
height: 40,
borderRadius: '0 20px 20px 0',
padding: 0,
boxShadow: '2px 0 8px rgba(0, 0, 0, 0.15)',
}}
onClick={() => setShowSettings(!showSettings)}
theme="solid"
type="primary"
/>
);
};
function CustomInputRender(props) {
const { detailProps } = props;
const { clearContextNode, uploadNode, inputNode, sendNode, onClick } = detailProps;
return <div style={{margin: '8px 16px', display: 'flex', flexDirection:'row',
alignItems: 'flex-end', borderRadius: 16,padding: 10, border: '1px solid var(--semi-color-border)'}}
onClick={onClick}
>
{/*{uploadNode}*/}
{inputNode}
{sendNode}
</div>
}
const renderInputArea = useCallback((props) => {
return (<CustomInputRender {...props} />)
}, []);
return ( return (
<Layout style={{height: '100%'}}> <Layout style={{height: '100%'}}>
<Layout.Sider> {(showSettings || !styleState.isMobile) && (
<Card style={commonOuterStyle}> <Layout.Sider style={{ display: styleState.isMobile ? 'block' : 'initial' }}>
<div style={{ marginTop: 10 }}> <Card style={commonOuterStyle}>
<Typography.Text strong>分组</Typography.Text> <div style={{ marginTop: 10 }}>
</div> <Typography.Text strong>分组</Typography.Text>
<Select </div>
placeholder={'请选择分组'} <Select
name='group' placeholder={'请选择分组'}
required name='group'
selection required
onChange={(value) => { selection
handleInputChange('group', value); onChange={(value) => {
}} handleInputChange('group', value);
value={inputs.group} }}
autoComplete='new-password' value={inputs.group}
optionList={groups} autoComplete='new-password'
/> optionList={groups}
<div style={{ marginTop: 10 }}> />
<Typography.Text strong>模型</Typography.Text> <div style={{ marginTop: 10 }}>
</div> <Typography.Text strong>模型</Typography.Text>
<Select </div>
placeholder={'请选择模型'} <Select
name='model' placeholder={'请选择模型'}
required name='model'
selection required
searchPosition='dropdown' selection
filter searchPosition='dropdown'
onChange={(value) => { filter
handleInputChange('model', value); onChange={(value) => {
}} handleInputChange('model', value);
value={inputs.model} }}
autoComplete='new-password' value={inputs.model}
optionList={models} autoComplete='new-password'
/> optionList={models}
<div style={{ marginTop: 10 }}> />
<Typography.Text strong>Temperature</Typography.Text> <div style={{ marginTop: 10 }}>
</div> <Typography.Text strong>Temperature</Typography.Text>
<Slider </div>
step={0.1} <Slider
min={0.1} step={0.1}
max={1} min={0.1}
value={inputs.temperature} max={1}
onChange={(value) => { value={inputs.temperature}
handleInputChange('temperature', value); onChange={(value) => {
}} handleInputChange('temperature', value);
/> }}
<div style={{ marginTop: 10 }}> />
<Typography.Text strong>MaxTokens</Typography.Text> <div style={{ marginTop: 10 }}>
</div> <Typography.Text strong>MaxTokens</Typography.Text>
<Input </div>
placeholder='MaxTokens' <Input
name='max_tokens' placeholder='MaxTokens'
required name='max_tokens'
autoComplete='new-password' required
defaultValue={0} autoComplete='new-password'
value={inputs.max_tokens} defaultValue={0}
onChange={(value) => { value={inputs.max_tokens}
handleInputChange('max_tokens', value); onChange={(value) => {
}} handleInputChange('max_tokens', value);
/> }}
/>
<div style={{ marginTop: 10 }}> <div style={{ marginTop: 10 }}>
<Typography.Text strong>System</Typography.Text> <Typography.Text strong>System</Typography.Text>
</div> </div>
<TextArea <TextArea
placeholder='System Prompt' placeholder='System Prompt'
name='system' name='system'
required required
autoComplete='new-password' autoComplete='new-password'
autosize autosize
defaultValue={systemPrompt} defaultValue={systemPrompt}
// value={systemPrompt} // value={systemPrompt}
onChange={(value) => { onChange={(value) => {
setSystemPrompt(value); setSystemPrompt(value);
}} }}
/> />
</Card> </Card>
</Layout.Sider> </Layout.Sider>
)}
<Layout.Content> <Layout.Content>
<div style={{height: '100%'}}> <div style={{height: '100%', position: 'relative'}}>
<SettingsToggle />
<Chat <Chat
chatBoxRenderConfig={{ chatBoxRenderConfig={{
renderChatBoxAction: () => { renderChatBoxAction: () => {
return <div></div> return <div></div>
} }
}} }}
renderInputArea={renderInputArea}
roleConfig={roleInfo} roleConfig={roleInfo}
style={commonOuterStyle} style={commonOuterStyle}
chats={message} chats={message}