🎉 搭完基本框架
This commit is contained in:
28
frontend/src/page/connection/connection.css
Normal file
28
frontend/src/page/connection/connection.css
Normal file
@ -0,0 +1,28 @@
|
||||
div.connection-container {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.connection-form {
|
||||
max-width: 700px;
|
||||
min-width: 500px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.connection-form-field {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
div.connection-form-field-actions {
|
||||
display: flex;
|
||||
margin-top: 50px;
|
||||
}
|
111
frontend/src/page/connection/connection.tsx
Normal file
111
frontend/src/page/connection/connection.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import './connection.css'
|
||||
import {
|
||||
useId,
|
||||
Button,
|
||||
FieldProps,
|
||||
useToastController,
|
||||
Toast,
|
||||
ToastTitle,
|
||||
ToastIntent,
|
||||
Toaster
|
||||
} from "@fluentui/react-components";
|
||||
import {Field, Input} from "@fluentui/react-components";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {useState} from "react";
|
||||
import {Dial} from "../../api";
|
||||
|
||||
|
||||
const Connection = (props: Partial<FieldProps>) => {
|
||||
|
||||
const toasterId = useId("toaster");
|
||||
const {dispatchToast} = useToastController(toasterId);
|
||||
const navigate = useNavigate();
|
||||
const [value, setValue] = useState<{ name: string, endpoint: string, access: string, key: string }>({
|
||||
name: '',
|
||||
endpoint: '',
|
||||
access: '',
|
||||
key: ''
|
||||
})
|
||||
|
||||
function test() {
|
||||
const val = JSON.stringify(value);
|
||||
console.log('[DEBUG] connection.test: value =', val)
|
||||
Dial<string>("/api/connection/test", value).then(res => {
|
||||
if (res.status === 200) {
|
||||
dispatchToast(
|
||||
<Toast>
|
||||
<ToastTitle>连接成功!</ToastTitle>
|
||||
</Toast>,
|
||||
{position: "top-end", intent: "success"}
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div className='connection-container'>
|
||||
<div className='connection-form'>
|
||||
<div className='connection-form-field'>
|
||||
<Field
|
||||
label="name"
|
||||
validationState="success"
|
||||
validationMessage="This is a success message."
|
||||
{...props}
|
||||
>
|
||||
<Input placeholder='名称 (example: 测试S3-minio)' value={value.name} onChange={(e) => {
|
||||
setValue({...value, name: e.target.value});
|
||||
}}/>
|
||||
</Field>
|
||||
</div>
|
||||
<div className='connection-form-field'>
|
||||
<Field
|
||||
label="endpoint"
|
||||
validationState="success"
|
||||
validationMessage="This is a success message."
|
||||
{...props}
|
||||
>
|
||||
<Input placeholder='地址 (example: https://ip_or_server-name:port)' value={value.endpoint}
|
||||
onChange={(e) => {
|
||||
setValue({...value, endpoint: e.target.value});
|
||||
}}/>
|
||||
</Field>
|
||||
</div>
|
||||
<div className='connection-form-field'>
|
||||
<Field
|
||||
label="secret access"
|
||||
validationState="success"
|
||||
validationMessage="This is a success message."
|
||||
{...props}
|
||||
>
|
||||
<Input placeholder='' value={value.access} onChange={(e) => {
|
||||
setValue({...value, access: e.target.value});
|
||||
}}/>
|
||||
</Field>
|
||||
</div>
|
||||
<div className='connection-form-field'>
|
||||
<Field
|
||||
label="secret key"
|
||||
validationState="success"
|
||||
validationMessage="This is a success message."
|
||||
{...props}
|
||||
>
|
||||
<Input placeholder='' value={value.key} onChange={(e) => {
|
||||
setValue({...value, key: e.target.value});
|
||||
}}/>
|
||||
</Field>
|
||||
</div>
|
||||
<div className='connection-form-field connection-form-field-actions'>
|
||||
<Button appearance='transparent' onClick={() => test()}>测试连接</Button>
|
||||
<div style={{marginLeft: 'auto'}}>
|
||||
<Button style={{marginRight: '20px'}} className='connection-form-field-actions-cancel'
|
||||
onClick={() => {
|
||||
navigate("/")
|
||||
}}>取消</Button>
|
||||
<Button className='connection-form-field-actions-confirm' appearance='primary'>新建</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Toaster toasterId={toasterId}/>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Connection;
|
50
frontend/src/page/home/home.css
Normal file
50
frontend/src/page/home/home.css
Normal file
@ -0,0 +1,50 @@
|
||||
div.container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div.header {
|
||||
height: 50px;
|
||||
border-bottom: 1px solid lightgray;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
div.body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.body div.body-connections {
|
||||
width: 200px;
|
||||
border-right: 1px solid lightgray;
|
||||
}
|
||||
|
||||
div.body-connections-search {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
input.body-connections-search-input {
|
||||
border: none;
|
||||
border-bottom: 1px solid lightgray;
|
||||
width: calc(100% - 4px);
|
||||
height: 30px;
|
||||
outline: none;
|
||||
text-indent: 5px;
|
||||
}
|
||||
div.body-connections-search-dismiss{
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
border-bottom: 1px solid lightgray;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
39
frontend/src/page/home/home.tsx
Normal file
39
frontend/src/page/home/home.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import {useState} from 'react';
|
||||
import './home.css';
|
||||
import {
|
||||
Button,
|
||||
} from "@fluentui/react-components";
|
||||
import {
|
||||
CloudAddFilled, DismissRegular
|
||||
} from "@fluentui/react-icons";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
function Home() {
|
||||
const [connectionFilterKeywords, setConnectionFilterKeywords] = useState<string>('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="header">
|
||||
<Button appearance="primary" icon={<CloudAddFilled />} onClick={() => {navigate("/connection")}}>
|
||||
新建连接
|
||||
</Button>
|
||||
</div>
|
||||
<div className="body">
|
||||
<div className="body-connections">
|
||||
<div className="body-connections-search">
|
||||
<input className="body-connections-search-input" type={"text"} placeholder="搜索连接" value={connectionFilterKeywords} onChange={(e) => setConnectionFilterKeywords(e.target.value)} />
|
||||
<div className="body-connections-search-dismiss" onClick={() => {setConnectionFilterKeywords('')}}>
|
||||
<DismissRegular />
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-connections-list"></div>
|
||||
</div>
|
||||
<div className="body-content"></div>
|
||||
</div>
|
||||
<div className="footer"></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
Reference in New Issue
Block a user